diff --git a/core/fmt/fmt.odin b/core/fmt/fmt.odin index c166b426a..bcca57049 100644 --- a/core/fmt/fmt.odin +++ b/core/fmt/fmt.odin @@ -34,6 +34,7 @@ Fmt_Info :: struct { arg: any, // Temporary } + string_buffer_from_slice :: proc(backing: []byte) -> String_Buffer { s := transmute(mem.Raw_Slice)backing; d := mem.Raw_Dynamic_Array{ @@ -1281,6 +1282,20 @@ fmt_arg :: proc(fi: ^Fmt_Info, arg: any, verb: rune) { return; } + + custom_types: switch a in arg { + case runtime.Source_Code_Location: + if fi.hash && verb == 'v' { + write_string(fi.buf, a.file_path); + write_byte(fi.buf, '('); + write_i64(fi.buf, i64(a.line), 10); + write_byte(fi.buf, ':'); + write_i64(fi.buf, i64(a.column), 10); + write_byte(fi.buf, ')'); + return; + } + } + base_arg := arg; base_arg.id = runtime.typeid_base(base_arg.id); switch a in base_arg { diff --git a/core/runtime/core.odin b/core/runtime/core.odin index 382c73864..6730621c8 100644 --- a/core/runtime/core.odin +++ b/core/runtime/core.odin @@ -196,6 +196,7 @@ Source_Code_Location :: struct { file_path: string, line, column: int, procedure: string, + hash: u64, } Assertion_Failure_Proc :: #type proc(prefix, message: string, loc: Source_Code_Location); @@ -253,8 +254,6 @@ Map_Header :: struct { - - type_info_base :: proc "contextless" (info: ^Type_Info) -> ^Type_Info { if info == nil do return nil; @@ -842,6 +841,23 @@ default_hash :: proc(data: []byte) -> u64 { default_hash_string :: proc(s: string) -> u64 do return default_hash(([]byte)(s)); +source_code_location_hash :: proc(s: Source_Code_Location) -> u64 { + fnv64a :: proc(data: []byte, seed: u64 = 0xcbf29ce484222325) -> u64 { + h: u64 = seed; + for b in data { + h = (h ~ u64(b)) * 0x100000001b3; + } + return h; + } + hash := fnv64a(cast([]byte)s.file_path); + hash = hash ~ (u64(s.line) * 0x100000001b3); + hash = hash ~ (u64(s.column) * 0x100000001b3); + return hash; +} + + + + __slice_resize :: proc(array_: ^$T/[]$E, new_count: int, allocator: mem.Allocator, loc := #caller_location) -> bool { array := (^mem.Raw_Slice)(array_); diff --git a/core/runtime/internal.odin b/core/runtime/internal.odin index d6fa36167..4fdb01cdf 100644 --- a/core/runtime/internal.odin +++ b/core/runtime/internal.odin @@ -274,7 +274,7 @@ bounds_check_error :: proc "contextless" (file: string, line, column: int, index if 0 <= index && index < count do return; handle_error :: proc "contextless" (file: string, line, column: int, index, count: int) { fd := os.stderr; - print_caller_location(fd, Source_Code_Location{file, line, column, ""}); + print_caller_location(fd, Source_Code_Location{file, line, column, "", 0}); os.write_string(fd, " Index "); print_i64(fd, i64(index)); os.write_string(fd, " is out of bounds range 0:"); @@ -289,7 +289,7 @@ slice_expr_error :: proc "contextless" (file: string, line, column: int, lo, hi: if 0 <= lo && lo <= hi && hi <= len do return; handle_error :: proc "contextless" (file: string, line, column: int, lo, hi: int, len: int) { fd := os.stderr; - print_caller_location(fd, Source_Code_Location{file, line, column, ""}); + print_caller_location(fd, Source_Code_Location{file, line, column, "", 0}); os.write_string(fd, " Invalid slice indices: "); print_i64(fd, i64(lo)); os.write_string(fd, ":"); @@ -306,7 +306,7 @@ dynamic_array_expr_error :: proc "contextless" (file: string, line, column: int, if 0 <= low && low <= high && high <= max do return; handle_error :: proc "contextless" (file: string, line, column: int, low, high, max: int) { fd := os.stderr; - print_caller_location(fd, Source_Code_Location{file, line, column, ""}); + print_caller_location(fd, Source_Code_Location{file, line, column, "", 0}); os.write_string(fd, " Invalid dynamic array values: "); print_i64(fd, i64(low)); os.write_string(fd, ":"); @@ -324,7 +324,7 @@ type_assertion_check :: proc "contextless" (ok: bool, file: string, line, column if ok do return; handle_error :: proc "contextless" (file: string, line, column: int, from, to: typeid) { fd := os.stderr; - print_caller_location(fd, Source_Code_Location{file, line, column, ""}); + print_caller_location(fd, Source_Code_Location{file, line, column, "", 0}); os.write_string(fd, " Invalid type assertion from "); print_typeid(fd, from); os.write_string(fd, " to "); diff --git a/src/ir.cpp b/src/ir.cpp index 757b5adf3..12dc3d278 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -433,6 +433,7 @@ struct irValueSourceCodeLocation { irValue *line; irValue *column; irValue *procedure; + u64 hash; }; @@ -3084,6 +3085,9 @@ irValue *ir_gen_map_key(irProcedure *proc, irValue *key, Type *key_type) { key = ir_emit_conv(proc, key, key_type); if (is_type_integer(t)) { ir_emit_store(proc, ir_emit_struct_ep(proc, v, 0), ir_emit_conv(proc, key, hash_type)); + } else if (is_type_typeid(t)) { + irValue *i = ir_emit_bitcast(proc, key, t_uint); + ir_emit_store(proc, ir_emit_struct_ep(proc, v, 0), ir_emit_conv(proc, i, hash_type)); } else if (is_type_pointer(t)) { irValue *p = ir_emit_conv(proc, key, t_uintptr); ir_emit_store(proc, ir_emit_struct_ep(proc, v, 0), ir_emit_conv(proc, p, hash_type)); @@ -5554,6 +5558,16 @@ bool is_double_pointer(Type *t) { } +u64 ir_generate_source_code_location_hash(TokenPos pos) { + u64 h = 0xcbf29ce484222325; + for (isize i = 0; i < pos.file.len; i++) { + h = (h ^ u64(pos.file[i])) * 0x100000001b3; + } + h = h ^ (u64(pos.line) * 0x100000001b3); + h = h ^ (u64(pos.column) * 0x100000001b3); + return h; +} + irValue *ir_emit_source_code_location(irProcedure *proc, String procedure, TokenPos pos) { gbAllocator a = ir_allocator(); irValue *v = ir_alloc_value(irValue_SourceCodeLocation); @@ -5561,6 +5575,7 @@ irValue *ir_emit_source_code_location(irProcedure *proc, String procedure, Token v->SourceCodeLocation.line = ir_const_int(pos.line); v->SourceCodeLocation.column = ir_const_int(pos.column); v->SourceCodeLocation.procedure = ir_find_or_add_entity_string(proc->module, procedure); + v->SourceCodeLocation.hash = ir_generate_source_code_location_hash(pos); return v; } diff --git a/src/ir_print.cpp b/src/ir_print.cpp index 40325ae9f..17d34b659 100644 --- a/src/ir_print.cpp +++ b/src/ir_print.cpp @@ -1018,6 +1018,7 @@ void ir_print_value(irFileBuffer *f, irModule *m, irValue *value, Type *type_hin irValue *line = value->SourceCodeLocation.line; irValue *column = value->SourceCodeLocation.column; irValue *procedure = value->SourceCodeLocation.procedure; + u64 hash = value->SourceCodeLocation.hash; ir_write_byte(f, '{'); ir_print_type(f, m, t_string); ir_write_byte(f, ' '); ir_print_value(f, m, file, t_string); @@ -1027,6 +1028,8 @@ void ir_print_value(irFileBuffer *f, irModule *m, irValue *value, Type *type_hin ir_print_type(f, m, t_int); ir_write_byte(f, ' '); ir_print_value(f, m, column, t_int); ir_write_string(f, str_lit(", ")); ir_print_type(f, m, t_string); ir_write_byte(f, ' '); ir_print_value(f, m, procedure, t_string); + ir_write_string(f, str_lit(", ")); + ir_print_type(f, m, t_u64); ir_write_byte(f, ' '); ir_write_u64(f, hash); ir_write_byte(f, '}'); break; } diff --git a/src/types.cpp b/src/types.cpp index cd610d3cb..eb850fa66 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -1151,6 +1151,9 @@ bool is_type_valid_for_keys(Type *t) { if (is_type_pointer(t)) { return true; } + if (is_type_typeid(t)) { + return true; + } return false; }