mirror of
https://github.com/Ed94/Odin.git
synced 2026-07-11 22:01:25 -07:00
Mock out map get/set functionality
This commit is contained in:
+17
-1
@@ -189,6 +189,19 @@ gb_internal cgAddr cg_addr(cgValue const &value) {
|
||||
return addr;
|
||||
}
|
||||
|
||||
gb_internal cgAddr cg_addr_map(cgValue addr, cgValue map_key, Type *map_type, Type *map_result) {
|
||||
GB_ASSERT(is_type_pointer(addr.type));
|
||||
Type *mt = type_deref(addr.type);
|
||||
GB_ASSERT(is_type_map(mt));
|
||||
|
||||
cgAddr v = {cgAddr_Map, addr};
|
||||
v.map.key = map_key;
|
||||
v.map.type = map_type;
|
||||
v.map.result = map_result;
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
gb_internal void cg_set_debug_pos_from_node(cgProcedure *p, Ast *node) {
|
||||
if (node) {
|
||||
TokenPos pos = ast_token(node).pos;
|
||||
@@ -435,6 +448,8 @@ gb_internal cgModule *cg_module_create(Checker *c) {
|
||||
map_init(&m->hasher_procs);
|
||||
map_init(&m->map_get_procs);
|
||||
map_init(&m->map_set_procs);
|
||||
map_init(&m->map_info_map);
|
||||
map_init(&m->map_cell_info_map);
|
||||
|
||||
array_init(&m->single_threaded_procedure_queue, heap_allocator());
|
||||
|
||||
@@ -461,6 +476,8 @@ gb_internal void cg_module_destroy(cgModule *m) {
|
||||
map_destroy(&m->hasher_procs);
|
||||
map_destroy(&m->map_get_procs);
|
||||
map_destroy(&m->map_set_procs);
|
||||
map_destroy(&m->map_info_map);
|
||||
map_destroy(&m->map_cell_info_map);
|
||||
|
||||
array_free(&m->single_threaded_procedure_queue);
|
||||
|
||||
@@ -784,7 +801,6 @@ gb_internal bool cg_generate_code(Checker *c, LinkerData *linker_data) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
TB_DebugFormat debug_format = TB_DEBUGFMT_NONE;
|
||||
if (build_context.ODIN_DEBUG) {
|
||||
switch (build_context.metrics.os) {
|
||||
|
||||
+8
-1
@@ -237,6 +237,9 @@ struct cgModule {
|
||||
PtrMap<Type *, cgProcedure *> map_get_procs;
|
||||
PtrMap<Type *, cgProcedure *> map_set_procs;
|
||||
|
||||
RecursiveMutex map_info_mutex;
|
||||
PtrMap<Type *, TB_Symbol *> map_info_map;
|
||||
PtrMap<Type *, TB_Symbol *> map_cell_info_map;
|
||||
|
||||
// NOTE(bill): no need to protect this with a mutex
|
||||
PtrMap<uintptr, TB_FileID> file_id_map; // Key: AstFile.id (i32 cast to uintptr)
|
||||
@@ -289,6 +292,7 @@ gb_internal cgValue cg_value(TB_Symbol * s, Type *type);
|
||||
gb_internal cgValue cg_value(TB_Node * node, Type *type);
|
||||
|
||||
gb_internal cgAddr cg_addr(cgValue const &value);
|
||||
gb_internal cgAddr cg_addr_map(cgValue addr, cgValue map_key, Type *map_type, Type *map_result);
|
||||
|
||||
gb_internal u64 cg_typeid_as_u64(cgModule *m, Type *type);
|
||||
gb_internal cgValue cg_type_info(cgProcedure *p, Type *type);
|
||||
@@ -370,4 +374,7 @@ gb_internal cgValue cg_handle_param_value(cgProcedure *p, Type *parameter_type,
|
||||
|
||||
gb_internal cgValue cg_builtin_len(cgProcedure *p, cgValue value);
|
||||
gb_internal cgValue cg_builtin_raw_data(cgProcedure *p, cgValue const &x);
|
||||
|
||||
gb_internal cgValue cg_builtin_map_info(cgProcedure *p, Type *map_type);
|
||||
gb_internal cgValue cg_builtin_map_cell_info(cgProcedure *p, Type *type);
|
||||
gb_internal cgValue cg_emit_source_code_location_as_global(cgProcedure *p, String const &proc_name, TokenPos pos);
|
||||
gb_internal cgValue cg_emit_source_code_location_as_global(cgProcedure *p, Ast *node);
|
||||
|
||||
@@ -231,6 +231,76 @@ gb_internal cgValue cg_builtin_mem_copy_non_overlapping(cgProcedure *p, cgValue
|
||||
return dst;
|
||||
}
|
||||
|
||||
gb_internal TB_Symbol *cg_builtin_map_cell_info_symbol(cgModule *m, Type *type) {
|
||||
MUTEX_GUARD(&m->map_info_mutex);
|
||||
TB_Symbol **found = map_get(&m->map_cell_info_map, type);
|
||||
if (found) {
|
||||
return *found;
|
||||
}
|
||||
i64 size = 0, len = 0;
|
||||
map_cell_size_and_len(type, &size, &len);
|
||||
|
||||
TB_Global *global = tb_global_create(m->mod, 0, "", cg_debug_type(m, t_map_cell_info), TB_LINKAGE_PRIVATE);
|
||||
tb_global_set_storage(m->mod, tb_module_get_rdata(m->mod), global, type_size_of(t_map_cell_info), type_align_of(t_map_cell_info), 4);
|
||||
|
||||
i64 ptr_size = build_context.ptr_size;
|
||||
void *size_of_type = tb_global_add_region(m->mod, global, 0*ptr_size, ptr_size);
|
||||
void *align_of_type = tb_global_add_region(m->mod, global, 1*ptr_size, ptr_size);
|
||||
void *size_of_cell = tb_global_add_region(m->mod, global, 2*ptr_size, ptr_size);
|
||||
void *elements_per_cell = tb_global_add_region(m->mod, global, 3*ptr_size, ptr_size);
|
||||
|
||||
cg_write_uint_at_ptr(size_of_type, type_size_of(type), t_uintptr);
|
||||
cg_write_uint_at_ptr(align_of_type, type_align_of(type), t_uintptr);
|
||||
cg_write_uint_at_ptr(size_of_cell, size, t_uintptr);
|
||||
cg_write_uint_at_ptr(elements_per_cell, len, t_uintptr);
|
||||
|
||||
map_set(&m->map_cell_info_map, type, cast(TB_Symbol *)global);
|
||||
|
||||
return cast(TB_Symbol *)global;
|
||||
}
|
||||
|
||||
|
||||
gb_internal cgValue cg_builtin_map_cell_info(cgProcedure *p, Type *type) {
|
||||
type = core_type(type);
|
||||
TB_Symbol *symbol = cg_builtin_map_cell_info_symbol(p->module, type);
|
||||
TB_Node *node = tb_inst_get_symbol_address(p->func, symbol);
|
||||
return cg_value(node, t_map_cell_info_ptr);
|
||||
}
|
||||
|
||||
gb_internal cgValue cg_builtin_map_info(cgProcedure *p, Type *map_type) {
|
||||
map_type = base_type(map_type);
|
||||
GB_ASSERT(map_type->kind == Type_Map);
|
||||
|
||||
cgModule *m = p->module;
|
||||
MUTEX_GUARD(&m->map_info_mutex);
|
||||
TB_Global *global = nullptr;
|
||||
TB_Symbol **found = map_get(&m->map_info_map, map_type);
|
||||
if (found) {
|
||||
global = cast(TB_Global *)*found;
|
||||
} else {
|
||||
global = tb_global_create(m->mod, 0, "", cg_debug_type(m, t_map_info), TB_LINKAGE_PRIVATE);
|
||||
tb_global_set_storage(m->mod, tb_module_get_rdata(m->mod), global, type_size_of(t_map_info), type_align_of(t_map_info), 4);
|
||||
|
||||
TB_Symbol *key_cell_info = cg_builtin_map_cell_info_symbol(m, map_type->Map.key);
|
||||
TB_Symbol *value_cell_info = cg_builtin_map_cell_info_symbol(m, map_type->Map.value);
|
||||
cgProcedure *key_hasher = cg_hasher_proc_for_type(p->module, map_type->Map.key);
|
||||
cgProcedure *key_equal = cg_equal_proc_for_type (p->module, map_type->Map.key);
|
||||
|
||||
tb_global_add_symbol_reloc(p->module->mod, global, 0*build_context.ptr_size, key_cell_info);
|
||||
tb_global_add_symbol_reloc(p->module->mod, global, 1*build_context.ptr_size, value_cell_info);
|
||||
tb_global_add_symbol_reloc(p->module->mod, global, 2*build_context.ptr_size, key_hasher->symbol);
|
||||
tb_global_add_symbol_reloc(p->module->mod, global, 3*build_context.ptr_size, key_equal->symbol);
|
||||
|
||||
map_set(&m->map_info_map, map_type, cast(TB_Symbol *)global);
|
||||
}
|
||||
|
||||
GB_ASSERT(global != nullptr);
|
||||
TB_Node *node = tb_inst_get_symbol_address(p->func, cast(TB_Symbol *)global);
|
||||
return cg_value(node, t_map_info_ptr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
gb_internal cgValue cg_build_builtin(cgProcedure *p, BuiltinProcId id, Ast *expr) {
|
||||
ast_node(ce, CallExpr, expr);
|
||||
@@ -434,6 +504,65 @@ gb_internal cgValue cg_build_builtin(cgProcedure *p, BuiltinProcId id, Ast *expr
|
||||
|
||||
case BuiltinProc_type_hasher_proc:
|
||||
return cg_hasher_proc_value_for_type(p, ce->args[0]->tav.type);
|
||||
|
||||
case BuiltinProc_type_map_cell_info:
|
||||
return cg_builtin_map_cell_info(p, ce->args[0]->tav.type);
|
||||
case BuiltinProc_type_map_info:
|
||||
return cg_builtin_map_info(p, ce->args[0]->tav.type);
|
||||
|
||||
case BuiltinProc_expect:
|
||||
{
|
||||
Type *t = default_type(expr->tav.type);
|
||||
cgValue x = cg_emit_conv(p, cg_build_expr(p, ce->args[0]), t);
|
||||
cgValue y = cg_emit_conv(p, cg_build_expr(p, ce->args[1]), t);
|
||||
gb_unused(y);
|
||||
return x;
|
||||
}
|
||||
|
||||
case BuiltinProc_count_leading_zeros:
|
||||
{
|
||||
cgValue n = cg_build_expr(p, ce->args[0]);
|
||||
n = cg_emit_conv(p, n, default_type(expr->tav.type));
|
||||
GB_ASSERT(n.kind == cgValue_Value);
|
||||
TB_Node *val = tb_inst_clz(p->func, n.node);
|
||||
val = tb_inst_zxt(p->func, val, cg_data_type(n.type));
|
||||
return cg_value(val, n.type);
|
||||
}
|
||||
|
||||
|
||||
case BuiltinProc_count_trailing_zeros:
|
||||
{
|
||||
cgValue n = cg_build_expr(p, ce->args[0]);
|
||||
n = cg_emit_conv(p, n, default_type(expr->tav.type));
|
||||
GB_ASSERT(n.kind == cgValue_Value);
|
||||
TB_Node *val = tb_inst_ctz(p->func, n.node);
|
||||
val = tb_inst_zxt(p->func, val, cg_data_type(n.type));
|
||||
return cg_value(val, n.type);
|
||||
}
|
||||
|
||||
case BuiltinProc_count_ones:
|
||||
{
|
||||
cgValue n = cg_build_expr(p, ce->args[0]);
|
||||
n = cg_emit_conv(p, n, default_type(expr->tav.type));
|
||||
GB_ASSERT(n.kind == cgValue_Value);
|
||||
TB_Node *val = tb_inst_popcount(p->func, n.node);
|
||||
val = tb_inst_zxt(p->func, val, cg_data_type(n.type));
|
||||
return cg_value(val, n.type);
|
||||
}
|
||||
|
||||
case BuiltinProc_count_zeros:
|
||||
{
|
||||
cgValue n = cg_build_expr(p, ce->args[0]);
|
||||
n = cg_emit_conv(p, n, default_type(expr->tav.type));
|
||||
GB_ASSERT(n.kind == cgValue_Value);
|
||||
TB_DataType dt = cg_data_type(n.type);
|
||||
TB_Node *ones = tb_inst_popcount(p->func, n.node);
|
||||
ones = tb_inst_zxt(p->func, ones, dt);
|
||||
|
||||
cgValue size = cg_const_int(p, n.type, 8*type_size_of(n.type));
|
||||
return cg_emit_arith(p, Token_Sub, size, cg_value(ones, n.type), n.type);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
+11
-2
@@ -96,7 +96,11 @@ gb_internal cgValue cg_emit_source_code_location_as_global(cgProcedure *p, Strin
|
||||
return cg_lvalue_addr(ptr, t_source_code_location);
|
||||
}
|
||||
|
||||
|
||||
gb_internal cgValue cg_emit_source_code_location_as_global(cgProcedure *p, Ast *node) {
|
||||
String proc_name = p->name;
|
||||
TokenPos pos = ast_token(node).pos;
|
||||
return cg_emit_source_code_location_as_global(p, proc_name, pos);
|
||||
}
|
||||
|
||||
gb_internal void cg_write_big_int_at_ptr(void *dst, BigInt const *a, Type *original_type) {
|
||||
GB_ASSERT(build_context.endian_kind == TargetEndian_Little);
|
||||
@@ -949,7 +953,12 @@ gb_internal cgValue cg_const_value(cgProcedure *p, Type *type, ExactValue const
|
||||
GB_ASSERT(!TB_IS_VOID_TYPE(dt));
|
||||
// GB_ASSERT(dt.raw != TB_TYPE_I128.raw);
|
||||
if (is_type_unsigned(type)) {
|
||||
u64 i = exact_value_to_u64(value);
|
||||
u64 i = 0;
|
||||
if (value.kind == ExactValue_Integer && value.value_integer.sign) {
|
||||
i = exact_value_to_i64(value);
|
||||
} else {
|
||||
i = exact_value_to_u64(value);
|
||||
}
|
||||
return cg_value(tb_inst_uint(p->func, dt, i), type);
|
||||
} else {
|
||||
i64 i = exact_value_to_i64(value);
|
||||
|
||||
+94
-11
@@ -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) {
|
||||
|
||||
+5
-1
@@ -388,7 +388,7 @@ gb_internal WORKER_TASK_PROC(cg_procedure_compile_worker_proc) {
|
||||
|
||||
// emit ir
|
||||
if (
|
||||
// string_starts_with(p->name, str_lit("bug@main")) ||
|
||||
string_starts_with(p->name, str_lit("main@")) ||
|
||||
// p->name == str_lit("runtime@_windows_default_alloc_or_resize") ||
|
||||
false
|
||||
) { // IR Printing
|
||||
@@ -398,6 +398,7 @@ gb_internal WORKER_TASK_PROC(cg_procedure_compile_worker_proc) {
|
||||
|
||||
tb_pass_print(passes);
|
||||
fprintf(stdout, "\n");
|
||||
fflush(stdout);
|
||||
}
|
||||
if (false) { // GraphViz printing
|
||||
tb_function_print(p->func, tb_default_print_callback, stdout);
|
||||
@@ -408,6 +409,7 @@ gb_internal WORKER_TASK_PROC(cg_procedure_compile_worker_proc) {
|
||||
if (emit_asm) {
|
||||
tb_output_print_asm(output, stdout);
|
||||
fprintf(stdout, "\n");
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -1018,6 +1020,7 @@ gb_internal cgProcedure *cg_equal_proc_for_type(cgModule *m, Type *type) {
|
||||
|
||||
cgProcedure *p = cg_procedure_create_dummy(m, proc_name, t_equal_proc);
|
||||
map_set(&m->equal_procs, type, p);
|
||||
p->split_returns_index = 2;
|
||||
|
||||
cg_procedure_begin(p);
|
||||
|
||||
@@ -1168,6 +1171,7 @@ gb_internal cgProcedure *cg_hasher_proc_for_type(cgModule *m, Type *type) {
|
||||
|
||||
cgProcedure *p = cg_procedure_create_dummy(m, proc_name, t_hasher_proc);
|
||||
map_set(&m->hasher_procs, type, p);
|
||||
p->split_returns_index = 2;
|
||||
|
||||
cg_procedure_begin(p);
|
||||
defer (cg_procedure_end(p));
|
||||
|
||||
+33
-3
@@ -77,7 +77,7 @@ gb_internal void cg_emit_store(cgProcedure *p, cgValue dst, cgValue src, bool is
|
||||
GB_ASSERT(is_type_pointer(dst.type));
|
||||
Type *dst_type = type_deref(dst.type);
|
||||
|
||||
GB_ASSERT_MSG(are_types_identical(dst_type, src.type), "%s vs %s", type_to_string(dst_type), type_to_string(src.type));
|
||||
GB_ASSERT_MSG(are_types_identical(core_type(dst_type), core_type(src.type)), "%s vs %s", type_to_string(dst_type), type_to_string(src.type));
|
||||
|
||||
TB_DataType dt = cg_data_type(dst_type);
|
||||
TB_DataType st = cg_data_type(src.type);
|
||||
@@ -225,6 +225,35 @@ gb_internal cgValue cg_addr_load(cgProcedure *p, cgAddr addr) {
|
||||
switch (addr.kind) {
|
||||
case cgAddr_Default:
|
||||
return cg_emit_load(p, addr.addr);
|
||||
|
||||
case cgAddr_Map:
|
||||
{
|
||||
Type *map_type = base_type(type_deref(addr.addr.type));
|
||||
GB_ASSERT(map_type->kind == Type_Map);
|
||||
cgAddr v_addr = cg_add_local(p, map_type->Map.value, nullptr, true);
|
||||
|
||||
cgValue ptr = cg_internal_dynamic_map_get_ptr(p, addr.addr, addr.map.key);
|
||||
cgValue ok = cg_emit_conv(p, cg_emit_comp_against_nil(p, Token_NotEq, ptr), t_bool);
|
||||
|
||||
TB_Node *then = cg_control_region(p, "map.get.then");
|
||||
TB_Node *done = cg_control_region(p, "map.get.done");
|
||||
cg_emit_if(p, ok, then, done);
|
||||
tb_inst_set_control(p->func, then);
|
||||
{
|
||||
cgValue value = cg_emit_conv(p, ptr, alloc_type_pointer(map_type->Map.value));
|
||||
value = cg_emit_load(p, value);
|
||||
cg_addr_store(p, v_addr, value);
|
||||
}
|
||||
cg_emit_goto(p, done);
|
||||
tb_inst_set_control(p->func, done);
|
||||
|
||||
cgValue v = cg_addr_load(p, v_addr);
|
||||
if (is_type_tuple(addr.map.result)) {
|
||||
return cg_value_multi2(v, ok, addr.map.result);
|
||||
} else {
|
||||
return v;
|
||||
}
|
||||
}
|
||||
}
|
||||
GB_PANIC("TODO(bill): cg_addr_load %p", addr.addr.node);
|
||||
return {};
|
||||
@@ -254,7 +283,8 @@ gb_internal void cg_addr_store(cgProcedure *p, cgAddr addr, cgValue value) {
|
||||
} else if (addr.kind == cgAddr_RelativeSlice) {
|
||||
GB_PANIC("TODO(bill): cgAddr_RelativeSlice");
|
||||
} else if (addr.kind == cgAddr_Map) {
|
||||
GB_PANIC("TODO(bill): cgAddr_Map");
|
||||
cg_internal_dynamic_map_set(p, addr.addr, addr.map.type, addr.map.key, value, p->curr_stmt);
|
||||
return;
|
||||
} else if (addr.kind == cgAddr_Context) {
|
||||
cgAddr old_addr = cg_find_or_generate_context_ptr(p);
|
||||
|
||||
@@ -1096,7 +1126,7 @@ gb_internal void cg_build_return_stmt_internal(cgProcedure *p, Slice<cgValue> co
|
||||
}
|
||||
|
||||
} else {
|
||||
GB_ASSERT(!is_calling_convention_odin(p->type->Proc.calling_convention));
|
||||
GB_ASSERT_MSG(!is_calling_convention_odin(p->type->Proc.calling_convention), "missing %s", proc_calling_convention_strings[p->type->Proc.calling_convention]);
|
||||
|
||||
if (p->return_by_ptr) {
|
||||
Entity *e = tuple->variables[return_count-1];
|
||||
|
||||
@@ -332,14 +332,14 @@ gb_internal void cg_setup_type_info_data(cgModule *m) {
|
||||
char const *name = CG_TYPE_INFO_TYPES_NAME;
|
||||
Type *t = alloc_type_array(t_type_info_ptr, count);
|
||||
TB_Global *g = tb_global_create(m->mod, -1, name, nullptr, TB_LINKAGE_PRIVATE);
|
||||
tb_global_set_storage(m->mod, tb_module_get_rdata(m->mod), g, type_size_of(t), 16, count*2);
|
||||
tb_global_set_storage(m->mod, tb_module_get_rdata(m->mod), g, type_size_of(t), 16, count*3);
|
||||
cg_global_type_info_member_types = GlobalTypeInfoData{g, t, t_type_info_ptr, 0};
|
||||
}
|
||||
{
|
||||
char const *name = CG_TYPE_INFO_NAMES_NAME;
|
||||
Type *t = alloc_type_array(t_string, count);
|
||||
TB_Global *g = tb_global_create(m->mod, -1, name, nullptr, TB_LINKAGE_PRIVATE);
|
||||
tb_global_set_storage(m->mod, tb_module_get_rdata(m->mod), g, type_size_of(t), 16, count*2);
|
||||
tb_global_set_storage(m->mod, tb_module_get_rdata(m->mod), g, type_size_of(t), 16, count*3);
|
||||
cg_global_type_info_member_names = GlobalTypeInfoData{g, t, t_string, 0};
|
||||
}
|
||||
{
|
||||
@@ -362,7 +362,7 @@ gb_internal void cg_setup_type_info_data(cgModule *m) {
|
||||
char const *name = CG_TYPE_INFO_TAGS_NAME;
|
||||
Type *t = alloc_type_array(t_string, count);
|
||||
TB_Global *g = tb_global_create(m->mod, -1, name, nullptr, TB_LINKAGE_PRIVATE);
|
||||
tb_global_set_storage(m->mod, tb_module_get_rdata(m->mod), g, type_size_of(t), 16, count*2);
|
||||
tb_global_set_storage(m->mod, tb_module_get_rdata(m->mod), g, type_size_of(t), 16, count*3);
|
||||
cg_global_type_info_member_tags = GlobalTypeInfoData{g, t, t_string, 0};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user