Browse Source

Basic fmt printing for `map`

gingerBill 2 years ago
parent
commit
bce62b98d4

+ 14 - 30
core/fmt/fmt.odin

@@ -2069,45 +2069,29 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) {
 
 
 		m := (^mem.Raw_Map)(v.data)
 		m := (^mem.Raw_Map)(v.data)
 		if m != nil {
 		if m != nil {
-			if info.generated_struct == nil {
+			if info.map_info == nil {
 				return
 				return
 			}
 			}
-			/*
-			entries    := &m.entries
-			gs         := runtime.type_info_base(info.generated_struct).variant.(runtime.Type_Info_Struct)
-			ed         := runtime.type_info_base(gs.types[1]).variant.(runtime.Type_Info_Dynamic_Array)
-			entry_type := ed.elem.variant.(runtime.Type_Info_Struct)
-			entry_size := ed.elem_size
-			/*
-				NOTE: The layout of a `map` is as follows:
-
-					map[Key]Value
-
-				## Internal Layout
-				struct {
-					hashes: []int,
-					entries: [dynamic]struct{
-						hash:  uintptr,
-						next:  int,
-						key:   Key,
-						value: Value,
-					},
+			map_cap := uintptr(runtime.map_cap(m^))
+			ks, vs, hs, _, _ := runtime.map_kvh_data_dynamic(m^, info.map_info)
+			j := 0
+			for bucket_index in 0..<map_cap {
+				if hs[bucket_index] == 0 {
+					continue
 				}
 				}
-			*/
-			for i in 0..<entries.len {
-				if i > 0 { io.write_string(fi.writer, ", ", &fi.n) }
 
 
-				data := uintptr(entries.data) + uintptr(i*entry_size)
+				if j > 0 {
+					io.write_string(fi.writer, ", ", &fi.n)
+				}
+				j += 1
 
 
-				key := data + entry_type.offsets[2] // key: Key
-				fmt_arg(&Info{writer = fi.writer}, any{rawptr(key), info.key.id}, 'v')
+				key   := ks + bucket_index*uintptr(info.key.size)
+				value := vs + bucket_index*uintptr(info.value.size)
 
 
+				fmt_arg(&Info{writer = fi.writer}, any{rawptr(key), info.key.id}, 'v')
 				io.write_string(fi.writer, "=", &fi.n)
 				io.write_string(fi.writer, "=", &fi.n)
-
-				value := data + entry_type.offsets[3] // value: Value
 				fmt_arg(fi, any{rawptr(value), info.value.id}, 'v')
 				fmt_arg(fi, any{rawptr(value), info.value.id}, 'v')
 			}
 			}
-			*/
 		}
 		}
 
 
 	case runtime.Type_Info_Struct:
 	case runtime.Type_Info_Struct:

+ 3 - 5
core/runtime/core.odin

@@ -143,11 +143,9 @@ Type_Info_Enum :: struct {
 	values:    []Type_Info_Enum_Value,
 	values:    []Type_Info_Enum_Value,
 }
 }
 Type_Info_Map :: struct {
 Type_Info_Map :: struct {
-	key:              ^Type_Info,
-	value:            ^Type_Info,
-	generated_struct: ^Type_Info,
-	key_equal:        Equal_Proc,
-	key_hasher:       Hasher_Proc,
+	key:      ^Type_Info,
+	value:    ^Type_Info,
+	map_info: ^Map_Info,
 }
 }
 Type_Info_Bit_Set :: struct {
 Type_Info_Bit_Set :: struct {
 	elem:       ^Type_Info,
 	elem:       ^Type_Info,

+ 6 - 7
core/runtime/dynamic_map_internal.odin

@@ -242,8 +242,8 @@ map_probe_distance :: #force_inline proc "contextless" (m: Raw_Map, hash: Map_Ha
 Map_Info :: struct {
 Map_Info :: struct {
 	ks:   Map_Cell_Info,                                                 // 32-bytes on 64-bit, 16-bytes on 32-bit
 	ks:   Map_Cell_Info,                                                 // 32-bytes on 64-bit, 16-bytes on 32-bit
 	vs:   Map_Cell_Info,                                                 // 32-bytes on 64-bit, 16-bytes on 32-bit
 	vs:   Map_Cell_Info,                                                 // 32-bytes on 64-bit, 16-bytes on 32-bit
-	hash: proc "contextless" (key: rawptr, seed: Map_Hash) -> Map_Hash,  // 8-bytes on 64-bit, 4-bytes on 32-bit
-	cmp:  proc "contextless" (lhs, rhs: rawptr) -> bool,                 // 8-bytes on 64-bit, 4-bytes on 32-bit
+	key_hasher: proc "contextless" (key: rawptr, seed: Map_Hash) -> Map_Hash,  // 8-bytes on 64-bit, 4-bytes on 32-bit
+	key_equal:  proc "contextless" (lhs, rhs: rawptr) -> bool,                 // 8-bytes on 64-bit, 4-bytes on 32-bit
 }
 }
 
 
 
 
@@ -669,7 +669,7 @@ map_lookup_dynamic :: proc "contextless" (m: Raw_Map, #no_alias info: ^Map_Info,
 	if map_len(m) == 0 {
 	if map_len(m) == 0 {
 		return 0, false
 		return 0, false
 	}
 	}
-	h := info.hash(rawptr(k), 0)
+	h := info.key_hasher(rawptr(k), 0)
 	p := map_desired_position(m, h)
 	p := map_desired_position(m, h)
 	d := uintptr(0)
 	d := uintptr(0)
 	c := (uintptr(1) << map_log2_cap(m)) - 1
 	c := (uintptr(1) << map_log2_cap(m)) - 1
@@ -681,7 +681,7 @@ map_lookup_dynamic :: proc "contextless" (m: Raw_Map, #no_alias info: ^Map_Info,
 			return 0, false
 			return 0, false
 		} else if d > map_probe_distance(m, element_hash, p) {
 		} else if d > map_probe_distance(m, element_hash, p) {
 			return 0, false
 			return 0, false
-		} else if element_hash == h && info.cmp(rawptr(k), rawptr(map_cell_index_dynamic(ks, info_ks, p))) {
+		} else if element_hash == h && info.key_equal(rawptr(k), rawptr(map_cell_index_dynamic(ks, info_ks, p))) {
 			return p, true
 			return p, true
 		}
 		}
 		p = (p + 1) & c
 		p = (p + 1) & c
@@ -698,7 +698,7 @@ map_insert_dynamic :: proc(#no_alias m: ^Raw_Map, #no_alias info: ^Map_Info, k,
 	if map_len(m^) + 1 >= map_resize_threshold(m^) {
 	if map_len(m^) + 1 >= map_resize_threshold(m^) {
 		map_grow_dynamic(m, info) or_return
 		map_grow_dynamic(m, info) or_return
 	}
 	}
-	hashed := info.hash(rawptr(k), 0)
+	hashed := info.key_hasher(rawptr(k), 0)
 	value = map_insert_hash_dynamic(m^, info, hashed, k, v)
 	value = map_insert_hash_dynamic(m^, info, hashed, k, v)
 	m.len += 1
 	m.len += 1
 	return
 	return
@@ -710,7 +710,7 @@ map_add_dynamic :: proc(#no_alias m: ^Raw_Map, #no_alias info: ^Map_Info, k, v:
 	if map_len(m^) + 1 >= map_resize_threshold(m^) {
 	if map_len(m^) + 1 >= map_resize_threshold(m^) {
 		map_grow_dynamic(m, info) or_return
 		map_grow_dynamic(m, info) or_return
 	}
 	}
-	map_add_hash_dynamic(m^, info, info.hash(rawptr(k), 0), k, v)
+	map_add_hash_dynamic(m^, info, info.key_hasher(rawptr(k), 0), k, v)
 	m.len += 1
 	m.len += 1
 	return nil
 	return nil
 }
 }
@@ -735,7 +735,6 @@ map_clear_dynamic :: #force_inline proc "contextless" (#no_alias m: ^Raw_Map, #n
 }
 }
 
 
 
 
-// TODO(bill): Change signature to not be a `rawptr`
 __dynamic_map_get :: proc "contextless" (m: rawptr, #no_alias info: ^Map_Info, key: rawptr) -> rawptr {
 __dynamic_map_get :: proc "contextless" (m: rawptr, #no_alias info: ^Map_Info, key: rawptr) -> rawptr {
 	rm := (^Raw_Map)(m)^
 	rm := (^Raw_Map)(m)^
 	index, ok := map_lookup_dynamic(rm, info, uintptr(key))
 	index, ok := map_lookup_dynamic(rm, info, uintptr(key))

+ 6 - 8
src/llvm_backend.cpp

@@ -530,15 +530,13 @@ LLVMValueRef lb_gen_map_cell_info(lbModule *m, Type *type) {
 	return llvm_const_named_struct(m, t_map_cell_info, const_values, gb_count_of(const_values));
 	return llvm_const_named_struct(m, t_map_cell_info, const_values, gb_count_of(const_values));
 
 
 }
 }
-lbValue lb_gen_map_info_ptr(lbProcedure *p, Type *map_type) {
-	lbModule *m = p->module;
-
+lbValue lb_gen_map_info_ptr(lbModule *m, Type *map_type) {
 	map_type = base_type(map_type);
 	map_type = base_type(map_type);
 	GB_ASSERT(map_type->kind == Type_Map);
 	GB_ASSERT(map_type->kind == Type_Map);
 
 
 	lbAddr *found = map_get(&m->map_info_map, map_type);
 	lbAddr *found = map_get(&m->map_info_map, map_type);
 	if (found) {
 	if (found) {
-		return lb_addr_get_ptr(p, *found);
+		return found->addr;
 	}
 	}
 
 
 	GB_ASSERT(t_map_info != nullptr);
 	GB_ASSERT(t_map_info != nullptr);
@@ -560,7 +558,7 @@ lbValue lb_gen_map_info_ptr(lbProcedure *p, Type *map_type) {
 	lb_make_global_private_const(addr);
 	lb_make_global_private_const(addr);
 
 
 	map_set(&m->map_info_map, map_type, addr);
 	map_set(&m->map_info_map, map_type, addr);
-	return lb_addr_get_ptr(p, addr);
+	return addr.addr;
 }
 }
 
 
 lbValue lb_const_hash(lbModule *m, lbValue key, Type *key_type) {
 lbValue lb_const_hash(lbModule *m, lbValue key, Type *key_type) {
@@ -637,7 +635,7 @@ lbValue lb_internal_dynamic_map_get_ptr(lbProcedure *p, lbValue const &map_ptr,
 
 
 	auto args = array_make<lbValue>(permanent_allocator(), 3);
 	auto args = array_make<lbValue>(permanent_allocator(), 3);
 	args[0] = lb_emit_conv(p, map_ptr, t_rawptr);
 	args[0] = lb_emit_conv(p, map_ptr, t_rawptr);
-	args[1] = lb_gen_map_info_ptr(p, map_type);
+	args[1] = lb_gen_map_info_ptr(p->module, map_type);
 	args[2] = key_ptr;
 	args[2] = key_ptr;
 
 
 	lbValue ptr = lb_emit_runtime_call(p, "__dynamic_map_get", args);
 	lbValue ptr = lb_emit_runtime_call(p, "__dynamic_map_get", args);
@@ -659,7 +657,7 @@ void lb_insert_dynamic_map_key_and_value(lbProcedure *p, lbValue const &map_ptr,
 
 
 	auto args = array_make<lbValue>(permanent_allocator(), 5);
 	auto args = array_make<lbValue>(permanent_allocator(), 5);
 	args[0] = lb_emit_conv(p, map_ptr, t_rawptr);
 	args[0] = lb_emit_conv(p, map_ptr, t_rawptr);
-	args[1] = lb_gen_map_info_ptr(p, map_type);
+	args[1] = lb_gen_map_info_ptr(p->module, map_type);
 	args[2] = key_ptr;
 	args[2] = key_ptr;
 	args[3] = lb_emit_conv(p, value_addr.addr, t_rawptr);
 	args[3] = lb_emit_conv(p, value_addr.addr, t_rawptr);
 	args[4] = lb_emit_source_code_location_as_global(p, node);
 	args[4] = lb_emit_source_code_location_as_global(p, node);
@@ -676,7 +674,7 @@ void lb_dynamic_map_reserve(lbProcedure *p, lbValue const &map_ptr, isize const
 
 
 	auto args = array_make<lbValue>(permanent_allocator(), 4);
 	auto args = array_make<lbValue>(permanent_allocator(), 4);
 	args[0] = lb_emit_conv(p, map_ptr, t_rawptr);
 	args[0] = lb_emit_conv(p, map_ptr, t_rawptr);
-	args[1] = lb_gen_map_info_ptr(p, type_deref(map_ptr.type));
+	args[1] = lb_gen_map_info_ptr(p->module, type_deref(map_ptr.type));
 	args[2] = lb_const_int(p->module, t_uint, capacity);
 	args[2] = lb_const_int(p->module, t_uint, capacity);
 	args[3] = lb_emit_source_code_location_as_global(p, proc_name, pos);
 	args[3] = lb_emit_source_code_location_as_global(p, proc_name, pos);
 	lb_emit_runtime_call(p, "__dynamic_map_reserve", args);
 	lb_emit_runtime_call(p, "__dynamic_map_reserve", args);

+ 1 - 0
src/llvm_backend.hpp

@@ -447,6 +447,7 @@ String lb_get_const_string(lbModule *m, lbValue value);
 lbValue lb_generate_local_array(lbProcedure *p, Type *elem_type, i64 count, bool zero_init=true);
 lbValue lb_generate_local_array(lbProcedure *p, Type *elem_type, i64 count, bool zero_init=true);
 lbValue lb_generate_global_array(lbModule *m, Type *elem_type, i64 count, String prefix, i64 id);
 lbValue lb_generate_global_array(lbModule *m, Type *elem_type, i64 count, String prefix, i64 id);
 lbValue lb_gen_map_key_hash(lbProcedure *p, lbValue key, Type *key_type, lbValue *key_ptr_);
 lbValue lb_gen_map_key_hash(lbProcedure *p, lbValue key, Type *key_type, lbValue *key_ptr_);
+lbValue lb_gen_map_info_ptr(lbModule *m, Type *map_type);
 
 
 lbValue lb_internal_dynamic_map_get_ptr(lbProcedure *p, lbValue const &map_ptr, lbValue const &key);
 lbValue lb_internal_dynamic_map_get_ptr(lbProcedure *p, lbValue const &map_ptr, lbValue const &key);
 void    lb_insert_dynamic_map_key_and_value(lbProcedure *p, lbValue const &map_ptr, Type *map_type, lbValue const &map_key, lbValue const &map_value, Ast *node);
 void    lb_insert_dynamic_map_key_and_value(lbProcedure *p, lbValue const &map_ptr, Type *map_type, lbValue const &map_key, lbValue const &map_value, Ast *node);

+ 2 - 6
src/llvm_backend_type.cpp

@@ -788,15 +788,11 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
 		case Type_Map: {
 		case Type_Map: {
 			tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_map_ptr);
 			tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_map_ptr);
 			init_map_internal_types(t);
 			init_map_internal_types(t);
-			
-			lbValue gst = lb_type_info(m, t->Map.internal_type);
 
 
-			LLVMValueRef vals[5] = {
+			LLVMValueRef vals[3] = {
 				lb_type_info(m, t->Map.key).value,
 				lb_type_info(m, t->Map.key).value,
 				lb_type_info(m, t->Map.value).value,
 				lb_type_info(m, t->Map.value).value,
-				gst.value,
-				lb_get_equal_proc_for_type(m, t->Map.key).value,
-				lb_get_hasher_proc_for_type(m, t->Map.key).value
+				lb_gen_map_info_ptr(p->module, t).value
 			};
 			};
 
 
 			lbValue res = {};
 			lbValue res = {};