Browse Source

Source_Code_Location.hash; %#v printing for Source_Code_Location; allow typeid for map keys

gingerBill 6 years ago
parent
commit
5acea1bceb
6 changed files with 58 additions and 6 deletions
  1. 15 0
      core/fmt/fmt.odin
  2. 18 2
      core/runtime/core.odin
  3. 4 4
      core/runtime/internal.odin
  4. 15 0
      src/ir.cpp
  5. 3 0
      src/ir_print.cpp
  6. 3 0
      src/types.cpp

+ 15 - 0
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 {

+ 18 - 2
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_);
 

+ 4 - 4
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 ");

+ 15 - 0
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;
 }
 

+ 3 - 0
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;
 	}

+ 3 - 0
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;
 }