aboutsummaryrefslogtreecommitdiff
path: root/src/tilde_expr.cpp
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2023-08-07 14:40:42 +0100
committergingerBill <bill@gingerbill.org>2023-08-07 14:40:42 +0100
commit0c1b39d881a5f91534bf0f33fb945ab57ef293d8 (patch)
tree5b16e10ddad44dccdb8f827294e9f3c73b68dba1 /src/tilde_expr.cpp
parent67ffae7e32301a817d73ba68b5e0d6a626c2b4de (diff)
Mock out map get/set functionality
Diffstat (limited to 'src/tilde_expr.cpp')
-rw-r--r--src/tilde_expr.cpp103
1 files changed, 93 insertions, 10 deletions
diff --git a/src/tilde_expr.cpp b/src/tilde_expr.cpp
index 6ff912dd9..7097f76ed 100644
--- a/src/tilde_expr.cpp
+++ b/src/tilde_expr.cpp
@@ -3416,9 +3416,93 @@ gb_internal cgValue cg_build_expr_internal(cgProcedure *p, Ast *expr) {
token_pos_to_string(token_pos));
return {};
+}
+
+
+gb_internal cgValue cg_map_data_uintptr(cgProcedure *p, cgValue value) {
+ GB_ASSERT(is_type_map(value.type) || are_types_identical(value.type, t_raw_map));
+ cgValue data = cg_emit_struct_ev(p, value, 0);
+ u64 mask_value = 0;
+ if (build_context.ptr_size == 4) {
+ mask_value = 0xfffffffful & ~(MAP_CACHE_LINE_SIZE-1);
+ } else {
+ mask_value = 0xffffffffffffffffull & ~(MAP_CACHE_LINE_SIZE-1);
+ }
+ cgValue mask = cg_const_int(p, t_uintptr, mask_value);
+ return cg_emit_arith(p, Token_And, data, mask, t_uintptr);
+}
+
+gb_internal cgValue cg_gen_map_key_hash(cgProcedure *p, cgValue const &map_ptr, cgValue key, cgValue *key_ptr_) {
+ TEMPORARY_ALLOCATOR_GUARD();
+
+ cgValue key_ptr = cg_address_from_load_or_generate_local(p, key);
+ key_ptr = cg_emit_conv(p, key_ptr, t_rawptr);
+ if (key_ptr_) *key_ptr_ = key_ptr;
+
+ Type* key_type = base_type(type_deref(map_ptr.type))->Map.key;
+
+ cgValue hasher = cg_hasher_proc_value_for_type(p, key_type);
+
+ Slice<cgValue> args = {};
+ args = slice_make<cgValue>(temporary_allocator(), 1);
+ args[0] = cg_map_data_uintptr(p, cg_emit_load(p, map_ptr));
+ cgValue seed = cg_emit_runtime_call(p, "map_seed_from_map_data", args);
+
+ args = slice_make<cgValue>(temporary_allocator(), 2);
+ args[0] = key_ptr;
+ args[1] = seed;
+ return cg_emit_call(p, hasher, args);
}
+gb_internal cgValue cg_internal_dynamic_map_get_ptr(cgProcedure *p, cgValue const &map_ptr, cgValue const &key) {
+ TEMPORARY_ALLOCATOR_GUARD();
+
+ Type *map_type = base_type(type_deref(map_ptr.type));
+ GB_ASSERT(map_type->kind == Type_Map);
+
+ cgValue ptr = {};
+ cgValue key_ptr = {};
+ cgValue hash = cg_gen_map_key_hash(p, map_ptr, key, &key_ptr);
+
+ auto args = slice_make<cgValue>(temporary_allocator(), 4);
+ args[0] = cg_emit_transmute(p, map_ptr, t_raw_map_ptr);
+ args[1] = cg_builtin_map_info(p, map_type);
+ args[2] = hash;
+ args[3] = key_ptr;
+
+ ptr = cg_emit_runtime_call(p, "__dynamic_map_get", args);
+
+ return cg_emit_conv(p, ptr, alloc_type_pointer(map_type->Map.value));
+}
+
+
+gb_internal void cg_internal_dynamic_map_set(cgProcedure *p, cgValue const &map_ptr, Type *map_type,
+ cgValue const &map_key, cgValue const &map_value, Ast *node) {
+ TEMPORARY_ALLOCATOR_GUARD();
+
+ map_type = base_type(map_type);
+ GB_ASSERT(map_type->kind == Type_Map);
+
+ cgValue key_ptr = {};
+ cgValue hash = cg_gen_map_key_hash(p, map_ptr, map_key, &key_ptr);
+
+ cgValue v = cg_emit_conv(p, map_value, map_type->Map.value);
+ cgValue value_ptr = cg_address_from_load_or_generate_local(p, v);
+
+ auto args = slice_make<cgValue>(temporary_allocator(), 6);
+ args[0] = cg_emit_conv(p, map_ptr, t_raw_map_ptr);
+ args[1] = cg_builtin_map_info(p, map_type);
+ args[2] = hash;
+ args[3] = cg_emit_conv(p, key_ptr, t_rawptr);
+ args[4] = cg_emit_conv(p, value_ptr, t_rawptr);
+ args[5] = cg_emit_source_code_location_as_global(p, node);
+ cg_emit_runtime_call(p, "__dynamic_map_set", args);
+}
+
+
+
+
gb_internal cgValue cg_build_addr_ptr(cgProcedure *p, Ast *expr) {
cgAddr addr = cg_build_addr(p, expr);
return cg_addr_get_ptr(p, addr);
@@ -3501,17 +3585,16 @@ gb_internal cgAddr cg_build_addr_index_expr(cgProcedure *p, Ast *expr) {
GB_ASSERT_MSG(is_type_indexable(t), "%s %s", type_to_string(t), expr_to_string(expr));
if (is_type_map(t)) {
- GB_PANIC("TODO(bill): map indexing");
- // lbAddr map_addr = lb_build_addr(p, ie->expr);
- // lbValue key = lb_build_expr(p, ie->index);
- // key = lb_emit_conv(p, key, t->Map.key);
+ cgAddr map_addr = cg_build_addr(p, ie->expr);
+ cgValue key = cg_build_expr(p, ie->index);
+ key = cg_emit_conv(p, key, t->Map.key);
- // Type *result_type = type_of_expr(expr);
- // lbValue map_ptr = lb_addr_get_ptr(p, map_addr);
- // if (is_type_pointer(type_deref(map_ptr.type))) {
- // map_ptr = lb_emit_load(p, map_ptr);
- // }
- // return lb_addr_map(map_ptr, key, t, result_type);
+ Type *result_type = type_of_expr(expr);
+ cgValue map_ptr = cg_addr_get_ptr(p, map_addr);
+ if (is_type_pointer(type_deref(map_ptr.type))) {
+ map_ptr = cg_emit_load(p, map_ptr);
+ }
+ return cg_addr_map(map_ptr, key, t, result_type);
}
switch (t->kind) {