diff --git a/core/_preload.odin b/core/_preload.odin index 8807aa9da..646a6313c 100644 --- a/core/_preload.odin +++ b/core/_preload.odin @@ -244,9 +244,18 @@ __typeid_of :: proc "contextless" (ti: ^Type_Info) -> typeid { start := uintptr(&__type_table[0]); end := uintptr(ti); id := (end-start)/size_of(Type_Info); + if uintptr(len(__type_table)) < id { + return nil; + } 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 { ti := type_info_of(id); diff --git a/core/fmt.odin b/core/fmt.odin index b29fa40a7..743c43222 100644 --- a/core/fmt.odin +++ b/core/fmt.odin @@ -755,8 +755,7 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) { write_string(fi.buf, "any{}"); } else { 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"); @@ -884,8 +883,7 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) { write_string(fi.buf, "any{}"); } else { 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"); } diff --git a/src/check_expr.cpp b/src/check_expr.cpp index e592597d2..760e72cfe 100644 --- a/src/check_expr.cpp +++ b/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); if (is_operand_value(o) && is_type_typeid(t)) { - // Okay + add_preload_dependency(c, "__type_info_of"); } else if (o.mode != Addressing_Type) { error(ce->args[0], "Expected a type or typeid for 'type_info_of'"); return false; diff --git a/src/ir.cpp b/src/ir.cpp index 20f1cb947..7197534ae 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -4216,8 +4216,10 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv return ir_type_info(proc, t); } 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(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: {