From b934e4b564e58c62b8c6848a71fe99b02c588a94 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 25 Jul 2023 00:33:43 +0100 Subject: [PATCH] Implement basic runtime type information This allows for `runtime.println_any` to work! --- src/tilde.cpp | 2 +- src/tilde/tb.lib | Bin 4164088 -> 4164640 bytes src/tilde_builtin.cpp | 3 +- src/tilde_const.cpp | 81 ++++++++------ src/tilde_expr.cpp | 229 ++++++++++++++++++++++++++++++++++++++-- src/tilde_proc.cpp | 5 +- src/tilde_stmt.cpp | 43 ++++---- src/tilde_type_info.cpp | 167 +++++++++++++++++++++++++++++ 8 files changed, 459 insertions(+), 71 deletions(-) diff --git a/src/tilde.cpp b/src/tilde.cpp index 82d30215e..729b8fa1e 100644 --- a/src/tilde.cpp +++ b/src/tilde.cpp @@ -260,7 +260,7 @@ gb_internal isize cg_type_info_index(CheckerInfo *info, Type *type, bool err_on_ } } if (err_on_not_found) { - GB_PANIC("NOT FOUND lb_type_info_index %s @ index %td", type_to_string(type), index); + GB_PANIC("NOT FOUND lb_type_info_index '%s' @ index %td", type_to_string(type), index); } return -1; } diff --git a/src/tilde/tb.lib b/src/tilde/tb.lib index 7ec145bda5b64062280a0aef0f964f044e60a9d4..78e661bf81e4969908183b620e584f08c86aae94 100644 GIT binary patch delta 65417 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 V*4JQ-VLgELwWrg&ue;~g{{tgft*-z8 delta 64668 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 dmt(HOdc#6=T)~J{(tuLCi4IQ diff --git a/src/tilde_builtin.cpp b/src/tilde_builtin.cpp index e30ff1cb0..edf436424 100644 --- a/src/tilde_builtin.cpp +++ b/src/tilde_builtin.cpp @@ -267,8 +267,7 @@ gb_internal cgValue cg_build_builtin(cgProcedure *p, BuiltinProcId id, Ast *expr pos = e->token.pos; } - GB_PANIC("TODO(bill): cg_emit_source_code_location_as_global"); - // return cg_emit_source_code_location_as_global(p, procedure, pos); + return cg_emit_source_code_location_as_global(p, procedure, pos); } break; case BuiltinProc_len: { diff --git a/src/tilde_const.cpp b/src/tilde_const.cpp index 60f8e636b..30038cfdf 100644 --- a/src/tilde_const.cpp +++ b/src/tilde_const.cpp @@ -31,7 +31,7 @@ gb_internal cgValue cg_const_nil(cgModule *m, cgProcedure *p, Type *type) { if (is_type_internally_pointer_like(type)) { return cg_value(tb_inst_uint(p->func, dt, 0), type); - } else if (is_type_integer(type) || is_type_boolean(type) || is_type_bit_set(type)) { + } else if (is_type_integer(type) || is_type_boolean(type) || is_type_bit_set(type) || is_type_typeid(type)) { return cg_value(tb_inst_uint(p->func, dt, 0), type); } else if (is_type_float(type)) { switch (size) { @@ -51,10 +51,49 @@ gb_internal cgValue cg_const_nil(cgProcedure *p, Type *type) { return cg_const_nil(p->module, p, type); } +gb_internal TB_Global *cg_global_const_string(cgModule *m, String const &str, Type *type, TB_Global *global, i64 offset); +gb_internal void cg_write_int_at_ptr(void *dst, i64 i, Type *original_type); + +gb_internal void cg_global_source_code_location_const(cgModule *m, String const &proc_name, TokenPos pos, TB_Global *global, i64 offset) { + // Source_Code_Location :: struct { + // file_path: string, + // line, column: i32, + // procedure: string, + // } + + i64 file_path_offset = type_offset_of(t_source_code_location, 0); + i64 line_offset = type_offset_of(t_source_code_location, 1); + i64 column_offset = type_offset_of(t_source_code_location, 2); + i64 procedure_offset = type_offset_of(t_source_code_location, 3); + + String file_path = get_file_path_string(pos.file_id); + if (file_path.len != 0) { + cg_global_const_string(m, file_path, t_string, global, offset+file_path_offset); + } + + void *line_ptr = tb_global_add_region(m->mod, global, offset+line_offset, 4); + void *column_ptr = tb_global_add_region(m->mod, global, offset+column_offset, 4); + cg_write_int_at_ptr(line_ptr, pos.line, t_i32); + cg_write_int_at_ptr(column_ptr, pos.column, t_i32); + + if (proc_name.len != 0) { + cg_global_const_string(m, proc_name, t_string, global, offset+procedure_offset); + } +} + gb_internal cgValue cg_emit_source_code_location_as_global(cgProcedure *p, String const &proc_name, TokenPos pos) { - // TODO(bill): cg_emit_source_code_location_as_global - return cg_const_nil(p, t_source_code_location); + cgModule *m = p->module; + char name[32] = {}; + gb_snprintf(name, 31, "scl$%u", 1+m->const_nil_guid.fetch_add(1)); + + TB_Global *global = tb_global_create(m->mod, -1, name, cg_debug_type(m, t_source_code_location), TB_LINKAGE_PRIVATE); + tb_global_set_storage(m->mod, tb_module_get_rdata(m->mod), global, type_size_of(t_source_code_location), type_align_of(t_source_code_location), 6); + + cg_global_source_code_location_const(m, proc_name, pos, global, 0); + + TB_Node *ptr = tb_inst_get_symbol_address(p->func, cast(TB_Symbol *)global); + return cg_lvalue_addr(ptr, t_source_code_location); } @@ -143,33 +182,6 @@ gb_internal TB_Global *cg_global_const_string(cgModule *m, String const &str, Ty return global; } -gb_internal void cg_global_source_code_location_const(cgModule *m, String const &proc_name, TokenPos pos, TB_Global *global, i64 offset) { - // Source_Code_Location :: struct { - // file_path: string, - // line, column: i32, - // procedure: string, - // } - - i64 file_path_offset = type_offset_of(t_source_code_location, 0); - i64 line_offset = type_offset_of(t_source_code_location, 1); - i64 column_offset = type_offset_of(t_source_code_location, 2); - i64 procedure_offset = type_offset_of(t_source_code_location, 3); - - String file_path = get_file_path_string(pos.file_id); - if (file_path.len != 0) { - cg_global_const_string(m, file_path, t_string, global, offset+file_path_offset); - } - - void *line_ptr = tb_global_add_region(m->mod, global, offset+line_offset, 4); - void *column_ptr = tb_global_add_region(m->mod, global, offset+column_offset, 4); - cg_write_int_at_ptr(line_ptr, pos.line, t_i32); - cg_write_int_at_ptr(column_ptr, pos.column, t_i32); - - if (proc_name.len != 0) { - cg_global_const_string(m, proc_name, t_string, global, offset+procedure_offset); - } -} - gb_internal bool cg_elem_type_can_be_constant(Type *t) { t = base_type(t); if (t == t_invalid) { @@ -1003,3 +1015,12 @@ gb_internal cgValue cg_const_int(cgProcedure *p, Type *type, i64 i) { gb_internal cgValue cg_const_bool(cgProcedure *p, Type *type, bool v) { return cg_value(tb_inst_bool(p->func, v), type); } + +gb_internal cgValue cg_const_string(cgProcedure *p, Type *type, String const &str) { + return cg_const_value(p, type, exact_value_string(str)); +} + +gb_internal cgValue cg_const_union_tag(cgProcedure *p, Type *u, Type *v) { + return cg_const_value(p, union_tag_type(u), exact_value_i64(union_variant_index(u, v))); +} + diff --git a/src/tilde_expr.cpp b/src/tilde_expr.cpp index 8737e75cd..551ffbfbb 100644 --- a/src/tilde_expr.cpp +++ b/src/tilde_expr.cpp @@ -267,7 +267,8 @@ gb_internal cgValue cg_emit_byte_swap(cgProcedure *p, cgValue value, Type *end_t GB_ASSERT(value.kind == cgValue_Value); - value.node = tb_inst_bswap(p->func, value.node); + // TODO(bill): bswap + // value.node = tb_inst_bswap(p->func, value.node); return cg_emit_transmute(p, value, end_type); } @@ -913,13 +914,12 @@ gb_internal cgValue cg_emit_conv(cgProcedure *p, cgValue value, Type *t) { if (are_types_identical(src, t_cstring) && are_types_identical(dst, t_string)) { - GB_PANIC("TODO(bill): cstring_to_string call"); - // TEMPORARY_ALLOCATOR_GUARD(); - // lbValue c = lb_emit_conv(p, value, t_cstring); - // auto args = array_make(temporary_allocator(), 1); - // args[0] = c; - // lbValue s = lb_emit_runtime_call(p, "cstring_to_string", args); - // return lb_emit_conv(p, s, dst); + TEMPORARY_ALLOCATOR_GUARD(); + cgValue c = cg_emit_conv(p, value, t_cstring); + auto args = slice_make(temporary_allocator(), 1); + args[0] = c; + cgValue s = cg_emit_runtime_call(p, "cstring_to_string", args); + return cg_emit_conv(p, s, dst); } // float -> float @@ -1115,7 +1115,29 @@ gb_internal cgValue cg_emit_conv(cgProcedure *p, cgValue value, Type *t) { } if (is_type_any(dst)) { - GB_PANIC("TODO(bill): ? -> any"); + if (is_type_untyped_nil(src) || + is_type_untyped_uninit(src)) { + return cg_const_nil(p, t); + } + + cgAddr result = cg_add_local(p, t, nullptr, false); + + Type *st = default_type(src_type); + + cgValue data = cg_address_from_load_or_generate_local(p, value); + GB_ASSERT(is_type_pointer(data.type)); + GB_ASSERT(is_type_typed(st)); + + data = cg_emit_conv(p, data, t_rawptr); + + cgValue id = cg_typeid(p, st); + cgValue data_ptr = cg_emit_struct_ep(p, result.addr, 0); + cgValue id_ptr = cg_emit_struct_ep(p, result.addr, 1); + + cg_emit_store(p, data_ptr, data); + cg_emit_store(p, id_ptr, id); + + return cg_addr_load(p, result); } i64 src_sz = type_size_of(src); @@ -2868,6 +2890,190 @@ gb_internal cgValue cg_build_unary_and(cgProcedure *p, Ast *expr) { return cg_build_addr_ptr(p, ue->expr); } +gb_internal cgValue cg_emit_cast_union(cgProcedure *p, cgValue value, Type *type, TokenPos pos) { + Type *src_type = value.type; + bool is_ptr = is_type_pointer(src_type); + + bool is_tuple = true; + Type *tuple = type; + if (type->kind != Type_Tuple) { + is_tuple = false; + tuple = make_optional_ok_type(type); + } + + + if (is_ptr) { + value = cg_emit_load(p, value); + } + Type *src = base_type(type_deref(src_type)); + GB_ASSERT_MSG(is_type_union(src), "%s", type_to_string(src_type)); + Type *dst = tuple->Tuple.variables[0]->type; + + cgValue value_ = cg_address_from_load_or_generate_local(p, value); + + if ((p->state_flags & StateFlag_no_type_assert) != 0 && !is_tuple) { + // just do a bit cast of the data at the front + cgValue ptr = cg_emit_conv(p, value_, alloc_type_pointer(type)); + return cg_emit_load(p, ptr); + } + + + cgValue tag = {}; + cgValue dst_tag = {}; + cgValue cond = {}; + cgValue data = {}; + + cgValue gep0 = cg_add_local(p, tuple->Tuple.variables[0]->type, nullptr, true).addr; + cgValue gep1 = cg_add_local(p, tuple->Tuple.variables[1]->type, nullptr, true).addr; + + if (is_type_union_maybe_pointer(src)) { + data = cg_emit_load(p, cg_emit_conv(p, value_, gep0.type)); + } else { + tag = cg_emit_load(p, cg_emit_union_tag_ptr(p, value_)); + dst_tag = cg_const_union_tag(p, src, dst); + } + + TB_Node *ok_block = cg_control_region(p, "union_cast_ok"); + TB_Node *end_block = cg_control_region(p, "union_cast_end"); + + if (data.node != nullptr) { + GB_ASSERT(is_type_union_maybe_pointer(src)); + cond = cg_emit_comp_against_nil(p, Token_NotEq, data); + } else { + cond = cg_emit_comp(p, Token_CmpEq, tag, dst_tag); + } + + cg_emit_if(p, cond, ok_block, end_block); + tb_inst_set_control(p->func, ok_block); + + if (data.node == nullptr) { + data = cg_emit_load(p, cg_emit_conv(p, value_, gep0.type)); + } + cg_emit_store(p, gep0, data); + cg_emit_store(p, gep1, cg_const_bool(p, t_bool, true)); + + cg_emit_goto(p, end_block); + tb_inst_set_control(p->func, end_block); + + if (!is_tuple) { + GB_ASSERT((p->state_flags & StateFlag_no_type_assert) == 0); + // NOTE(bill): Panic on invalid conversion + Type *dst_type = tuple->Tuple.variables[0]->type; + + isize arg_count = 7; + if (build_context.no_rtti) { + arg_count = 4; + } + + cgValue ok = cg_emit_load(p, gep1); + auto args = slice_make(permanent_allocator(), arg_count); + args[0] = ok; + + args[1] = cg_const_string(p, t_string, get_file_path_string(pos.file_id)); + args[2] = cg_const_int(p, t_i32, pos.line); + args[3] = cg_const_int(p, t_i32, pos.column); + + if (!build_context.no_rtti) { + args[4] = cg_typeid(p, src_type); + args[5] = cg_typeid(p, dst_type); + args[6] = cg_emit_conv(p, value_, t_rawptr); + } + cg_emit_runtime_call(p, "type_assertion_check2", args); + + return cg_emit_load(p, gep0); + } + + return cg_value_multi2(cg_emit_load(p, gep0), cg_emit_load(p, gep1), tuple); +} + +gb_internal cgValue cg_emit_cast_any(cgProcedure *p, cgValue value, Type *type, TokenPos pos) { + Type *src_type = value.type; + + if (is_type_pointer(src_type)) { + value = cg_emit_load(p, value); + } + + bool is_tuple = true; + Type *tuple = type; + if (type->kind != Type_Tuple) { + is_tuple = false; + tuple = make_optional_ok_type(type); + } + Type *dst_type = tuple->Tuple.variables[0]->type; + + if ((p->state_flags & StateFlag_no_type_assert) != 0 && !is_tuple) { + // just do a bit cast of the data at the front + cgValue ptr = cg_emit_struct_ev(p, value, 0); + ptr = cg_emit_conv(p, ptr, alloc_type_pointer(type)); + return cg_emit_load(p, ptr); + } + + cgValue dst_typeid = cg_typeid(p, dst_type); + cgValue any_typeid = cg_emit_struct_ev(p, value, 1); + + + TB_Node *ok_block = cg_control_region(p, "any_cast_ok"); + TB_Node *end_block = cg_control_region(p, "any_cast_end"); + cgValue cond = cg_emit_comp(p, Token_CmpEq, any_typeid, dst_typeid); + cg_emit_if(p, cond, ok_block, end_block); + tb_inst_set_control(p->func, ok_block); + + cgValue gep0 = cg_add_local(p, tuple->Tuple.variables[0]->type, nullptr, true).addr; + cgValue gep1 = cg_add_local(p, tuple->Tuple.variables[1]->type, nullptr, true).addr; + + cgValue any_data = cg_emit_struct_ev(p, value, 0); + cgValue ptr = cg_emit_conv(p, any_data, alloc_type_pointer(dst_type)); + cg_emit_store(p, gep0, cg_emit_load(p, ptr)); + cg_emit_store(p, gep1, cg_const_bool(p, t_bool, true)); + + cg_emit_goto(p, end_block); + tb_inst_set_control(p->func, end_block); + + if (!is_tuple) { + // NOTE(bill): Panic on invalid conversion + cgValue ok = cg_emit_load(p, gep1); + + isize arg_count = 7; + if (build_context.no_rtti) { + arg_count = 4; + } + auto args = slice_make(permanent_allocator(), arg_count); + args[0] = ok; + + args[1] = cg_const_string(p, t_string, get_file_path_string(pos.file_id)); + args[2] = cg_const_int(p, t_i32, pos.line); + args[3] = cg_const_int(p, t_i32, pos.column); + + if (!build_context.no_rtti) { + args[4] = any_typeid; + args[5] = dst_typeid; + args[6] = cg_emit_struct_ev(p, value, 0); + } + cg_emit_runtime_call(p, "type_assertion_check2", args); + + return cg_emit_load(p, gep0); + } + + return cg_value_multi2(cg_emit_load(p, gep0), cg_emit_load(p, gep1), tuple); +} + + +gb_internal cgValue cg_build_type_assertion(cgProcedure *p, Ast *expr, Type *type) { + ast_node(ta, TypeAssertion, expr); + + TokenPos pos = ast_token(expr).pos; + cgValue e = cg_build_expr(p, ta->expr); + Type *t = type_deref(e.type); + + if (is_type_union(t)) { + return cg_emit_cast_union(p, e, type, pos); + } else if (is_type_any(t)) { + return cg_emit_cast_any(p, e, type, pos); + } + GB_PANIC("TODO(bill): type assertion %s", type_to_string(e.type)); + return {}; +} + gb_internal cgValue cg_build_expr_internal(cgProcedure *p, Ast *expr) { expr = unparen_expr(expr); @@ -3079,8 +3285,11 @@ gb_internal cgValue cg_build_expr_internal(cgProcedure *p, Ast *expr) { case_ast_node(oe, OrElseExpr, expr); return cg_build_or_else(p, oe->x, oe->y, tv.type); case_end; + + case_ast_node(ta, TypeAssertion, expr); + return cg_build_type_assertion(p, expr, tv.type); + case_end; } - GB_PANIC("TODO(bill): cg_build_expr_internal %.*s", LIT(ast_strings[expr->kind])); return {}; } diff --git a/src/tilde_proc.cpp b/src/tilde_proc.cpp index a805b2985..398148965 100644 --- a/src/tilde_proc.cpp +++ b/src/tilde_proc.cpp @@ -352,7 +352,7 @@ gb_internal WORKER_TASK_PROC(cg_procedure_compile_worker_proc) { bool emit_asm = false; if ( - // string_starts_with(p->name, str_lit("runtime@_os_write")) || + // string_starts_with(p->name, str_lit("bug@main")) || false ) { emit_asm = true; @@ -866,8 +866,7 @@ gb_internal cgValue cg_build_call_expr_internal(cgProcedure *p, Ast *expr) { cgValue base_elem = cg_emit_array_epi(p, base_array.addr, 0); cgValue len = cg_const_int(p, t_int, slice_len); - GB_PANIC("TODO(bill): cg_fill_slice"); - // cg_fill_slice(p, slice, base_elem, len); + cg_fill_slice(p, slice, base_elem, len); variadic_args = cg_addr_load(p, slice); } diff --git a/src/tilde_stmt.cpp b/src/tilde_stmt.cpp index 8b577dfeb..a663a401d 100644 --- a/src/tilde_stmt.cpp +++ b/src/tilde_stmt.cpp @@ -409,11 +409,9 @@ gb_internal cgValue cg_emit_struct_ep(cgProcedure *p, cgValue s, i64 index) { switch (t->kind) { case Type_Struct: - { - type_set_offsets(t); - result_type = t->Struct.fields[index]->type; - offset = t->Struct.offsets[index]; - } + type_set_offsets(t); + result_type = t->Struct.fields[index]->type; + offset = t->Struct.offsets[index]; break; case Type_Union: GB_ASSERT(index == -1); @@ -421,7 +419,10 @@ gb_internal cgValue cg_emit_struct_ep(cgProcedure *p, cgValue s, i64 index) { break; // return cg_emit_union_tag_ptr(p, s); case Type_Tuple: - GB_PANIC("TODO(bill): cg_emit_tuple_ep"); + type_set_offsets(t); + result_type = t->Tuple.variables[index]->type; + offset = t->Tuple.offsets[index]; + GB_PANIC("TODO(bill): cg_emit_tuple_ep %d", s.kind); break; // return cg_emit_tuple_ep(p, s, index); case Type_Slice: @@ -1799,8 +1800,11 @@ gb_internal void cg_build_switch_stmt(cgProcedure *p, Ast *node) { expr = unparen_expr(expr); GB_ASSERT(!is_ast_range(expr)); if (expr->tav.mode == Addressing_Type) { - GB_PANIC("TODO(bill): cg_typeid as i64"); - // key = cg_typeid(p, expr->tav.value.value_typeid); + Type *type = expr->tav.value.value_typeid; + if (type == nullptr || type == t_invalid) { + type = expr->tav.type; + } + key = cg_typeid_as_u64(p->module, type); } else { auto tv = type_and_value_of_expr(expr); GB_ASSERT(tv.mode == Addressing_Constant); @@ -1912,21 +1916,16 @@ gb_internal void cg_build_switch_stmt(cgProcedure *p, Ast *node) { cg_scope_close(p, cgDeferExit_Default, done); } -gb_internal void cg_type_case_body(cgProcedure *p, Ast *label, Ast *clause, TB_Node *body_region, TB_Node *done_region) { - // ast_node(cc, CaseClause, clause); - - // cg_push_target_list(p, label, done, nullptr, nullptr); - // cg_build_stmt_list(p, cc->stmts); - // cg_scope_close(p, cgDeferExit_Default, body_region); - // cg_pop_target_list(p); - - // cg_emit_goto(p, done_region); -} - gb_internal void cg_build_type_switch_stmt(cgProcedure *p, Ast *node) { ast_node(ss, TypeSwitchStmt, node); + TB_Node *done_region = cg_control_region(p, "typeswitch_done"); + TB_Node *else_region = done_region; + TB_Node *default_region = nullptr; + isize num_cases = 0; + cg_scope_open(p, ss->scope); + defer (cg_scope_close(p, cgDeferExit_Default, done_region)); ast_node(as, AssignStmt, ss->tag); GB_ASSERT(as->lhs.count == 1); @@ -1969,11 +1968,6 @@ gb_internal void cg_build_type_switch_stmt(cgProcedure *p, Ast *node) { ast_node(body, BlockStmt, ss->body); - TB_Node *done_region = cg_control_region(p, "typeswitch_done"); - TB_Node *else_region = done_region; - TB_Node *default_region = nullptr; - isize num_cases = 0; - for (Ast *clause : body->stmts) { ast_node(cc, CaseClause, clause); num_cases += cc->list.count; @@ -2158,7 +2152,6 @@ gb_internal void cg_build_type_switch_stmt(cgProcedure *p, Ast *node) { cg_emit_goto(p, done_region); tb_inst_set_control(p->func, done_region); - cg_scope_close(p, cgDeferExit_Default, done_region); } diff --git a/src/tilde_type_info.cpp b/src/tilde_type_info.cpp index 1e86f6644..adad2cace 100644 --- a/src/tilde_type_info.cpp +++ b/src/tilde_type_info.cpp @@ -340,6 +340,173 @@ gb_internal void cg_setup_type_info_data(cgModule *m) { break; } break; + + case Type_Pointer: + tag_type = t_type_info_pointer; + cg_global_const_type_info_ptr(m, type_table_array, t->Pointer.elem, global, offset+0); + break; + case Type_MultiPointer: + tag_type = t_type_info_multi_pointer; + cg_global_const_type_info_ptr(m, type_table_array, t->MultiPointer.elem, global, offset+0); + break; + case Type_SoaPointer: + tag_type = t_type_info_soa_pointer; + cg_global_const_type_info_ptr(m, type_table_array, t->SoaPointer.elem, global, offset+0); + break; + + case Type_Array: + { + tag_type = t_type_info_array; + + cg_global_const_type_info_ptr(m, type_table_array, t->Array.elem, global, offset+0); + void *elem_size_ptr = tb_global_add_region(m->mod, global, offset+1*build_context.int_size, build_context.int_size); + void *count_ptr = tb_global_add_region(m->mod, global, offset+2*build_context.int_size, build_context.int_size); + + cg_write_int_at_ptr(elem_size_ptr, type_size_of(t->Array.elem), t_int); + cg_write_int_at_ptr(count_ptr, t->Array.count, t_int); + } + break; + + case Type_EnumeratedArray: + { + tag_type = t_type_info_enumerated_array; + + i64 elem_offset = type_offset_of(tag_type, 0); + i64 index_offset = type_offset_of(tag_type, 1); + i64 elem_size_offset = type_offset_of(tag_type, 2); + i64 count_offset = type_offset_of(tag_type, 3); + i64 min_value_offset = type_offset_of(tag_type, 4); + i64 max_value_offset = type_offset_of(tag_type, 5); + i64 is_sparse_offset = type_offset_of(tag_type, 6); + + cg_global_const_type_info_ptr(m, type_table_array, t->EnumeratedArray.elem, global, offset+elem_offset); + cg_global_const_type_info_ptr(m, type_table_array, t->EnumeratedArray.index, global, offset+index_offset); + + void *elem_size_ptr = tb_global_add_region(m->mod, global, offset+elem_size_offset, build_context.int_size); + void *count_ptr = tb_global_add_region(m->mod, global, offset+count_offset, build_context.int_size); + + void *min_value_ptr = tb_global_add_region(m->mod, global, offset+min_value_offset, type_size_of(t_type_info_enum_value)); + void *max_value_ptr = tb_global_add_region(m->mod, global, offset+max_value_offset, type_size_of(t_type_info_enum_value)); + void *is_sparse_ptr = tb_global_add_region(m->mod, global, offset+is_sparse_offset, 1); + + cg_write_int_at_ptr(elem_size_ptr, type_size_of(t->EnumeratedArray.elem), t_int); + cg_write_int_at_ptr(count_ptr, t->EnumeratedArray.count, t_int); + + cg_write_int_at_ptr(min_value_ptr, exact_value_to_i64(*t->EnumeratedArray.min_value), t_type_info_enum_value); + cg_write_int_at_ptr(max_value_ptr, exact_value_to_i64(*t->EnumeratedArray.max_value), t_type_info_enum_value); + *(bool *)is_sparse_ptr = t->EnumeratedArray.is_sparse; + } + break; + + case Type_DynamicArray: + { + tag_type = t_type_info_dynamic_array; + + cg_global_const_type_info_ptr(m, type_table_array, t->DynamicArray.elem, global, offset+0); + void *elem_size_ptr = tb_global_add_region(m->mod, global, offset+1*build_context.int_size, build_context.int_size); + cg_write_int_at_ptr(elem_size_ptr, type_size_of(t->DynamicArray.elem), t_int); + } + break; + case Type_Slice: + { + tag_type = t_type_info_slice; + + cg_global_const_type_info_ptr(m, type_table_array, t->Slice.elem, global, offset+0); + void *elem_size_ptr = tb_global_add_region(m->mod, global, offset+1*build_context.int_size, build_context.int_size); + cg_write_int_at_ptr(elem_size_ptr, type_size_of(t->Slice.elem), t_int); + } + break; + + case Type_Proc: + { + tag_type = t_type_info_procedure; + + i64 params_offset = type_offset_of(tag_type, 0); + i64 results_offset = type_offset_of(tag_type, 1); + i64 variadic_offset = type_offset_of(tag_type, 2); + i64 convention_offset = type_offset_of(tag_type, 3); + + if (t->Proc.params) { + cg_global_const_type_info_ptr(m, type_table_array, t->Proc.params, global, offset+params_offset); + } + if (t->Proc.results) { + cg_global_const_type_info_ptr(m, type_table_array, t->Proc.results, global, offset+results_offset); + } + + bool *variadic_ptr = cast(bool *)tb_global_add_region(m->mod, global, offset+variadic_offset, 1); + u8 * convention_ptr = cast(u8 *) tb_global_add_region(m->mod, global, offset+convention_offset, 1); + + *variadic_ptr = t->Proc.variadic; + *convention_ptr = cast(u8)t->Proc.calling_convention; + } + break; + + case Type_Tuple: + { + tag_type = t_type_info_parameters; + + // TODO(bill): Type_Info_Parameters + } + break; + + case Type_Enum: + { + tag_type = t_type_info_enum; + + // TODO(bill): Type_Info_Enum + } + break; + case Type_Struct: + { + tag_type = t_type_info_struct; + + // TODO(bill): Type_Info_Struct + } + break; + case Type_Union: + { + tag_type = t_type_info_union; + + // TODO(bill): Type_Info_Union + } + break; + case Type_Map: + { + tag_type = t_type_info_map; + + // TODO(bill): Type_Info_Map + } + break; + case Type_BitSet: + { + tag_type = t_type_info_bit_set; + + // TODO(bill): Type_Info_Bit_Set + } + break; + case Type_SimdVector: + { + tag_type = t_type_info_simd_vector; + + // TODO(bill): Type_Info_Simd_Vector + } + break; + + case Type_RelativePointer: + { + tag_type = t_type_info_relative_pointer; + } + break; + case Type_RelativeSlice: + { + tag_type = t_type_info_relative_slice; + } + break; + case Type_Matrix: + { + tag_type = t_type_info_matrix; + } + break; } if (tag_type != nullptr) {