Browse Source

Use `__type_info_of` internally

gingerBill 7 years ago
parent
commit
324b7d65e7
4 changed files with 17 additions and 8 deletions
  1. 10 1
      core/_preload.odin
  2. 2 4
      core/fmt.odin
  3. 1 1
      src/check_expr.cpp
  4. 4 2
      src/ir.cpp

+ 10 - 1
core/_preload.odin

@@ -244,9 +244,18 @@ __typeid_of :: proc "contextless" (ti: ^Type_Info) -> typeid {
 	start := uintptr(&__type_table[0]);
 	start := uintptr(&__type_table[0]);
 	end := uintptr(ti);
 	end := uintptr(ti);
 	id := (end-start)/size_of(Type_Info);
 	id := (end-start)/size_of(Type_Info);
+	if uintptr(len(__type_table)) < id {
+		return nil;
+	}
 	return transmute(typeid)id;
 	return transmute(typeid)id;
 }
 }
-
+__type_info_of :: proc "contextless" (id: typeid) -> ^Type_Info {
+	n := int(transmute(uintptr)id);
+	if n < 0 || n >= len(__type_table) {
+		n = 0;
+	}
+	return &__type_table[n];
+}
 
 
 typeid_base :: proc "contextless" (id: typeid) -> typeid {
 typeid_base :: proc "contextless" (id: typeid) -> typeid {
 	ti := type_info_of(id);
 	ti := type_info_of(id);

+ 2 - 4
core/fmt.odin

@@ -755,8 +755,7 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
 					write_string(fi.buf, "any{}");
 					write_string(fi.buf, "any{}");
 				} else {
 				} else {
 					data := rawptr(uintptr(v.data) + b.offsets[i]);
 					data := rawptr(uintptr(v.data) + b.offsets[i]);
-					id := typeid_of(t);
-					fmt_arg(fi, any{data, id}, 'v');
+					fmt_arg(fi, any{data, typeid_of(t)}, 'v');
 				}
 				}
 
 
 				if hash do write_string(fi.buf, ",\n");
 				if hash do write_string(fi.buf, ",\n");
@@ -884,8 +883,7 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
 				write_string(fi.buf, "any{}");
 				write_string(fi.buf, "any{}");
 			} else {
 			} else {
 				data := uintptr(v.data) + info.offsets[i];
 				data := uintptr(v.data) + info.offsets[i];
-				id := typeid_of(t);
-				fmt_arg(fi, any{rawptr(data), id}, 'v');
+				fmt_arg(fi, any{rawptr(data), typeid_of(t)}, 'v');
 			}
 			}
 			if hash do write_string(fi.buf, ",\n");
 			if hash do write_string(fi.buf, ",\n");
 		}
 		}

+ 1 - 1
src/check_expr.cpp

@@ -3422,7 +3422,7 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
 		add_type_info_type(c, t);
 		add_type_info_type(c, t);
 
 
 		if (is_operand_value(o) && is_type_typeid(t)) {
 		if (is_operand_value(o) && is_type_typeid(t)) {
-			// Okay
+			add_preload_dependency(c, "__type_info_of");
 		} else if (o.mode != Addressing_Type) {
 		} else if (o.mode != Addressing_Type) {
 			error(ce->args[0], "Expected a type or typeid for 'type_info_of'");
 			error(ce->args[0], "Expected a type or typeid for 'type_info_of'");
 			return false;
 			return false;

+ 4 - 2
src/ir.cpp

@@ -4216,8 +4216,10 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
 			return ir_type_info(proc, t);
 			return ir_type_info(proc, t);
 		}
 		}
 		GB_ASSERT(is_type_typeid(tav.type));
 		GB_ASSERT(is_type_typeid(tav.type));
-		irValue *id = ir_emit_bitcast(proc, ir_build_expr(proc, arg), t_uintptr);
-		return ir_emit_array_ep(proc, ir_global_type_info_data, id);
+
+		auto args = array_make<irValue *>(proc->module->allocator, 1);
+		args[0] = ir_build_expr(proc, arg);
+		return ir_emit_global_call(proc, "__type_info_of", args);
 	}
 	}
 
 
 	case BuiltinProc_typeid_of: {
 	case BuiltinProc_typeid_of: {