diff --git a/core/_preload.odin b/core/_preload.odin index a46883fea..b0c269bf8 100644 --- a/core/_preload.odin +++ b/core/_preload.odin @@ -1,7 +1,7 @@ #shared_global_scope import "core:os.odin" -import "core:fmt.odin" // TODO(bill): Remove the need for `fmt` here +// import "core:fmt.odin" // TODO(bill): Remove the need for `fmt` here import "core:utf8.odin" import "core:raw.odin" @@ -599,22 +599,55 @@ nil_allocator :: proc() -> Allocator { } -assert :: proc "contextless" (condition: bool, message := "", args: ...any, using loc := #caller_location) -> bool { +__print_u64 :: proc(fd: os.Handle, u: u64) { + digits := "0123456789"; + + a: [129]byte; + i := len(a); + b := u64(10); + for u >= b { + i -= 1; a[i] = digits[u % b]; + u /= b; + } + i -= 1; a[i] = digits[u % b]; + + os.write(fd, a[i..]); +} + +__print_caller_location :: proc(fd: os.Handle, using loc: Source_Code_Location) { + os.write_string(fd, file_path); + os.write_byte(fd, '('); + __print_u64(fd, u64(line)); + os.write_byte(fd, ':'); + __print_u64(fd, u64(column)); + os.write_byte(fd, ')'); +} + + +assert :: proc "contextless" (condition: bool, message := "", using loc := #caller_location) -> bool { if !condition { - fmt.fprintf(os.stderr, "%s(%d:%d) Runtime assertion", file_path, line, column); - if len(message) > 0 do fmt.fprint(os.stderr, ": "); - fmt.fprintf(os.stderr, message, ...args); - fmt.fprintf(os.stderr, "\n"); + fd := os.stderr; + __print_caller_location(fd, loc); + os.write_string(fd, " Runtime assertion"); + if len(message) > 0 { + os.write_string(fd, ": "); + os.write_string(fd, message); + os.write_byte(fd, '\n'); + } __debug_trap(); } return condition; } -panic :: proc "contextless" (message := "", args: ...any, using loc := #caller_location) { - fmt.fprintf(os.stderr, "%s(%d:%d) Panic", file_path, line, column); - if len(message) > 0 do fmt.fprint(os.stderr, ": "); - fmt.fprintf(os.stderr, message, ...args); - fmt.fprintf(os.stderr, "\n"); +panic :: proc "contextless" (message := "", using loc := #caller_location) { + fd := os.stderr; + __print_caller_location(fd, loc); + os.write_string(fd, " Panic"); + if len(message) > 0 { + os.write_string(fd, ": "); + os.write_string(fd, message); + os.write_byte(fd, '\n'); + } __debug_trap(); } @@ -672,29 +705,59 @@ __complex128_ne :: inline proc "contextless" (a, b: complex128) -> bool { return __bounds_check_error :: proc "contextless" (file: string, line, column: int, index, count: int) { if 0 <= index && index < count do return; - fmt.fprintf(os.stderr, "%s(%d:%d) Index %d is out of bounds range 0..%d\n", - file, line, column, index, count); + + fd := os.stderr; + __print_caller_location(fd, Source_Code_Location{file, line, column, ""}); + os.write_string(fd, " Index "); + __print_u64(fd, u64(index)); + os.write_string(fd, " is out of bounds range 0.."); + __print_u64(fd, u64(count)); + os.write_byte(fd, '\n'); __debug_trap(); } __slice_expr_error :: proc "contextless" (file: string, line, column: int, low, high: int) { if 0 <= low && low <= high do return; - fmt.fprintf(os.stderr, "%s(%d:%d) Invalid slice indices: %d..%d\n", - file, line, column, low, high); + + + fd := os.stderr; + __print_caller_location(fd, Source_Code_Location{file, line, column, ""}); + os.write_string(fd, " Invalid slice indices: "); + __print_u64(fd, u64(low)); + os.write_string(fd, ".."); + __print_u64(fd, u64(high)); + os.write_byte(fd, '\n'); + __debug_trap(); + + // fmt.fprintf(os.stderr, "%s(%d:%d) Invalid slice indices: %d..%d\n", + // file, line, column, low, high); __debug_trap(); } __dynamic_array_expr_error :: proc "contextless" (file: string, line, column: int, low, high, max: int) { if 0 <= low && low <= high && high <= max do return; - fmt.fprintf(os.stderr, "%s(%d:%d) Invalid slice indices: %d..%d..%d\n", - file, line, column, low, high, max); + + fd := os.stderr; + __print_caller_location(fd, Source_Code_Location{file, line, column, ""}); + os.write_string(fd, " Invalid slice indices: "); + __print_u64(fd, u64(low)); + os.write_string(fd, ".."); + __print_u64(fd, u64(high)); + os.write_string(fd, ".."); + __print_u64(fd, u64(max)); + os.write_byte(fd, '\n'); + __debug_trap(); __debug_trap(); } __type_assertion_check :: proc "contextless" (ok: bool, file: string, line, column: int, from, to: ^Type_Info) { if ok do return; - fmt.fprintf(os.stderr, "%s(%d:%d) Invalid type_assertion from %T to %T\n", - file, line, column, from, to); + + fd := os.stderr; + __print_caller_location(fd, Source_Code_Location{file, line, column, ""}); + os.write_string(fd, " Invalid type assertion"); + // fmt.fprintf(os.stderr, "%s(%d:%d) Invalid type_assertion from %T to %T\n", + // file, line, column, from, to); __debug_trap(); } diff --git a/core/os.odin b/core/os.odin index ef7ad7ac2..4de19e031 100644 --- a/core/os.odin +++ b/core/os.odin @@ -9,6 +9,11 @@ write_string :: proc(fd: Handle, str: string) -> (int, Errno) { return write(fd, cast([]byte)str); } +write_byte :: proc(fd: Handle, b: byte) -> (int, Errno) { + return write(fd, []byte{b}); +} + + read_entire_file :: proc(name: string) -> (data: []byte, success: bool) { fd, err := open(name, O_RDONLY, 0); if err != 0 { diff --git a/src/checker.cpp b/src/checker.cpp index 10da68af6..2dec1a7c7 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -576,18 +576,17 @@ void init_universal_scope(void) { void init_checker_info(CheckerInfo *i) { gbAllocator a = heap_allocator(); - map_init(&i->types, a); - array_init(&i->definitions, a); - array_init(&i->entities, a); - map_init(&i->untyped, a); - map_init(&i->foreigns, a); - map_init(&i->gen_procs, a); - map_init(&i->gen_types, a); - map_init(&i->type_info_map, a); - map_init(&i->files, a); + map_init(&i->types, a); + array_init(&i->definitions, a); + array_init(&i->entities, a); + map_init(&i->untyped, a); + map_init(&i->foreigns, a); + map_init(&i->gen_procs, a); + map_init(&i->gen_types, a); + array_init(&i->type_info_types, a); + map_init(&i->type_info_map, a); + map_init(&i->files, a); array_init(&i->variable_init_order, a); - - i->type_info_count = 0; } void destroy_checker_info(CheckerInfo *i) { @@ -598,6 +597,7 @@ void destroy_checker_info(CheckerInfo *i) { map_destroy(&i->foreigns); map_destroy(&i->gen_procs); map_destroy(&i->gen_types); + array_free(&i->type_info_types); map_destroy(&i->type_info_map); map_destroy(&i->files); array_free(&i->variable_init_order); @@ -922,6 +922,7 @@ void add_type_info_type(Checker *c, Type *t) { return; } + bool prev = false; isize ti_index = -1; for_array(i, c->info.type_info_map.entries) { auto *e = &c->info.type_info_map.entries[i]; @@ -929,19 +930,22 @@ void add_type_info_type(Checker *c, Type *t) { if (are_types_identical(t, prev_type)) { // Duplicate entry ti_index = e->value; + prev = true; break; } } if (ti_index < 0) { // Unique entry // NOTE(bill): map entries grow linearly and in order - ti_index = c->info.type_info_count; - c->info.type_info_count++; + ti_index = c->info.type_info_types.count; + array_add(&c->info.type_info_types, t); } map_set(&c->info.type_info_map, hash_type(t), ti_index); - - + if (prev) { + // NOTE(bill): If a previous one exists already, no need to continue + return; + } // Add nested types @@ -3053,7 +3057,8 @@ void check_parsed_files(Checker *c) { // Add "Basic" type information for (isize i = 0; i < gb_count_of(basic_types)-1; i++) { Type *t = &basic_types[i]; - if (t->Basic.size > 0 && t->Basic.kind != Basic_llvm_bool) { + if (t->Basic.size > 0 && + t->Basic.kind != Basic_llvm_bool) { add_type_info_type(c, t); } } @@ -3064,7 +3069,7 @@ void check_parsed_files(Checker *c) { if (e->kind == Entity_TypeName && e->type != nullptr) { // i64 size = type_size_of(c->allocator, e->type); i64 align = type_align_of(c->allocator, e->type); - if (align > 0) { + if (align > 0 && ptr_set_exists(&c->info.minimum_dependency_set, e)) { add_type_info_type(c, e->type); } } diff --git a/src/checker.hpp b/src/checker.hpp index 29b8eae1a..8b610f4fe 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -298,8 +298,8 @@ struct CheckerInfo { Map > gen_procs; // Key: AstNode * | Identifier -> Entity Map > gen_types; // Key: Type * + Array type_info_types; Map type_info_map; // Key: Type * - isize type_info_count; Scope * init_scope; Entity * entry_point; diff --git a/src/ir.cpp b/src/ir.cpp index 68608513f..068ed50f4 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -7838,9 +7838,8 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info i32 type_info_member_names_index = 0; i32 type_info_member_offsets_index = 0; - for_array(type_info_map_index, info->type_info_map.entries) { - auto *entry = &info->type_info_map.entries[type_info_map_index]; - Type *t = cast(Type *)entry->key.ptr; + for_array(type_info_type_index, info->type_info_types) { + Type *t = info->type_info_types[type_info_type_index]; t = default_type(t); if (t == t_invalid) { continue;