mirror of
https://github.com/odin-lang/Odin.git
synced 2026-04-21 05:45:19 +00:00
Support map keys for simple compare types
This commit is contained in:
@@ -76,6 +76,7 @@ default_hash_ptr :: inline proc "contextless" (data: rawptr, size: int) -> uintp
|
||||
return default_hash(transmute([]byte)(s));
|
||||
}
|
||||
|
||||
@(private)
|
||||
_default_hasher_const :: inline proc "contextless" (data: rawptr, seed: uintptr, $N: uint) -> uintptr {
|
||||
h := u64(seed) + 0xcbf29ce484222325;
|
||||
p := uintptr(data);
|
||||
@@ -86,7 +87,8 @@ _default_hasher_const :: inline proc "contextless" (data: rawptr, seed: uintptr,
|
||||
}
|
||||
return uintptr(h);
|
||||
}
|
||||
_default_hasher_n :: inline proc "contextless" (data: rawptr, seed: uintptr, N: int) -> uintptr {
|
||||
|
||||
default_hasher_n :: inline proc "contextless" (data: rawptr, seed: uintptr, N: int) -> uintptr {
|
||||
h := u64(seed) + 0xcbf29ce484222325;
|
||||
p := uintptr(data);
|
||||
for _ in 0..<N {
|
||||
|
||||
@@ -2856,6 +2856,10 @@ void add_map_key_type_dependencies(CheckerContext *ctx, Type *key) {
|
||||
} else if (!is_type_polymorphic(key)) {
|
||||
GB_ASSERT_MSG(is_type_simple_compare(key), "%s", type_to_string(key));
|
||||
|
||||
if (is_type_struct(key)) {
|
||||
add_package_dependency(ctx, "runtime", "default_hasher_n");
|
||||
}
|
||||
|
||||
i64 sz = type_size_of(key);
|
||||
switch (sz) {
|
||||
case 1: add_package_dependency(ctx, "runtime", "default_hasher1"); break;
|
||||
@@ -2863,7 +2867,6 @@ void add_map_key_type_dependencies(CheckerContext *ctx, Type *key) {
|
||||
case 4: add_package_dependency(ctx, "runtime", "default_hasher4"); break;
|
||||
case 8: add_package_dependency(ctx, "runtime", "default_hasher8"); break;
|
||||
case 16: add_package_dependency(ctx, "runtime", "default_hasher16"); break;
|
||||
default: GB_PANIC("unhandled hasher for key type: %s", type_to_string(key));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
10
src/ir.cpp
10
src/ir.cpp
@@ -5006,8 +5006,14 @@ irValue *ir_get_hasher_proc_for_type(irModule *m, Type *type) {
|
||||
|
||||
if (type->kind == Type_Struct) {
|
||||
type_set_offsets(type);
|
||||
|
||||
GB_PANIC("Type_Struct");
|
||||
GB_ASSERT(is_type_simple_compare(type));
|
||||
i64 sz = type_size_of(type);
|
||||
auto args = array_make<irValue *>(permanent_allocator(), 3);
|
||||
args[0] = data;
|
||||
args[1] = seed;
|
||||
args[2] = ir_const_int(sz);
|
||||
irValue *res = ir_emit_runtime_call(proc, "default_hasher_n", args);
|
||||
ir_emit(proc, ir_instr_return(proc, res));
|
||||
} else if (is_type_cstring(type)) {
|
||||
auto args = array_make<irValue *>(permanent_allocator(), 2);
|
||||
args[0] = data;
|
||||
|
||||
@@ -9284,8 +9284,14 @@ lbValue lb_get_hasher_proc_for_type(lbModule *m, Type *type) {
|
||||
|
||||
if (type->kind == Type_Struct) {
|
||||
type_set_offsets(type);
|
||||
|
||||
GB_PANIC("Type_Struct");
|
||||
GB_ASSERT(is_type_simple_compare(type));
|
||||
i64 sz = type_size_of(type);
|
||||
auto args = array_make<lbValue>(permanent_allocator(), 3);
|
||||
args[0] = data;
|
||||
args[1] = seed;
|
||||
args[2] = lb_const_int(m, t_int, sz);
|
||||
lbValue res = lb_emit_runtime_call(p, "default_hasher_n", args);
|
||||
LLVMBuildRet(p->builder, res.value);
|
||||
} else if (is_type_cstring(type)) {
|
||||
auto args = array_make<lbValue>(permanent_allocator(), 2);
|
||||
args[0] = data;
|
||||
|
||||
@@ -964,7 +964,6 @@ bool is_type_valid_for_keys(Type *t);
|
||||
|
||||
Type *alloc_type_map(i64 count, Type *key, Type *value) {
|
||||
if (key != nullptr) {
|
||||
GB_ASSERT(is_type_valid_for_keys(key));
|
||||
GB_ASSERT(value != nullptr);
|
||||
}
|
||||
Type *t = alloc_type(Type_Map);
|
||||
@@ -1558,6 +1557,9 @@ bool is_type_valid_for_keys(Type *t) {
|
||||
if (is_type_typeid(t)) {
|
||||
return true;
|
||||
}
|
||||
if (is_type_simple_compare(t)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user