diff options
| author | gingerBill <bill@gingerbill.org> | 2023-07-15 13:15:50 +0100 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2023-07-15 13:15:50 +0100 |
| commit | e2e5641a450f4d7ea67eae468f1bd479361ec198 (patch) | |
| tree | 98574548de1b1c43ae3d5d409733f5fc3262f669 /src/tilde_proc.cpp | |
| parent | ca442defbbaae4269ff947dfc14059f69a5cdaec (diff) | |
Update TB; Fix calling nullptr TB_Node* problems
Diffstat (limited to 'src/tilde_proc.cpp')
| -rw-r--r-- | src/tilde_proc.cpp | 126 |
1 files changed, 124 insertions, 2 deletions
diff --git a/src/tilde_proc.cpp b/src/tilde_proc.cpp index 306852db3..dbebae853 100644 --- a/src/tilde_proc.cpp +++ b/src/tilde_proc.cpp @@ -1,5 +1,127 @@ +gb_internal cgValue cg_find_procedure_value_from_entity(cgModule *m, Entity *e) { + GB_ASSERT(is_type_proc(e->type)); + e = strip_entity_wrapping(e); + GB_ASSERT(e != nullptr); + GB_ASSERT(e->kind == Entity_Procedure); + + cgValue *found = nullptr; + rw_mutex_shared_lock(&m->values_mutex); + found = map_get(&m->values, e); + rw_mutex_shared_unlock(&m->values_mutex); + if (found) { + return *found; + } + + GB_PANIC("Error in: %s, missing procedure %.*s\n", token_pos_to_string(e->token.pos), LIT(e->token.string)); + return {}; +} + + + +gb_internal cgValue cg_build_call_expr_internal(cgProcedure *p, Ast *expr); gb_internal cgValue cg_build_call_expr(cgProcedure *p, Ast *expr) { + expr = unparen_expr(expr); ast_node(ce, CallExpr, expr); - // TODO(bill): cg_build_call_expr + + cgValue res = cg_build_call_expr_internal(p, expr); + + if (ce->optional_ok_one) { // TODO(bill): Minor hack for #optional_ok procedures + GB_PANIC("Handle optional_ok_one"); + // GB_ASSERT(is_type_tuple(res.type)); + // GB_ASSERT(res.type->Tuple.variables.count == 2); + // return cg_emit_struct_ev(p, res, 0); + } + return res; +} + +gb_internal cgValue cg_emit_call(cgProcedure * p, cgValue value, Slice<cgValue> args) { + if (value.kind == cgValue_Symbol) { + value = cg_value(tb_inst_get_symbol_address(p->func, value.symbol), value.type); + } + GB_ASSERT(value.kind == cgValue_Value); + + TB_FunctionPrototype *proto = cg_procedure_type_as_prototype(p->module, value.type); + TB_Node *target = value.node; + auto params = slice_make<TB_Node *>(temporary_allocator(), 0); + + GB_ASSERT(target != nullptr); + TB_MultiOutput multi_output = tb_inst_call(p->func, proto, target, 0, nullptr); + gb_unused(multi_output); return {}; -}
\ No newline at end of file +} + +gb_internal cgValue cg_build_call_expr_internal(cgProcedure *p, Ast *expr) { + ast_node(ce, CallExpr, expr); + + TypeAndValue tv = type_and_value_of_expr(expr); + + TypeAndValue proc_tv = type_and_value_of_expr(ce->proc); + AddressingMode proc_mode = proc_tv.mode; + if (proc_mode == Addressing_Type) { + GB_ASSERT(ce->args.count == 1); + cgValue x = cg_build_expr(p, ce->args[0]); + return cg_emit_conv(p, x, tv.type); + } + + Ast *proc_expr = unparen_expr(ce->proc); + if (proc_mode == Addressing_Builtin) { + Entity *e = entity_of_node(proc_expr); + BuiltinProcId id = BuiltinProc_Invalid; + if (e != nullptr) { + id = cast(BuiltinProcId)e->Builtin.id; + } else { + id = BuiltinProc_DIRECTIVE; + } + if (id == BuiltinProc___entry_point) { + if (p->module->info->entry_point) { + cgValue entry_point = cg_find_procedure_value_from_entity(p->module, p->module->info->entry_point); + GB_ASSERT(entry_point.node != nullptr); + cg_emit_call(p, entry_point, {}); + } + return {}; + } + GB_PANIC("TODO(bill): builtin procs %d %.*s", id, LIT(builtin_procs[id].name)); + } + + // NOTE(bill): Regular call + cgValue value = {}; + + Entity *proc_entity = entity_of_node(proc_expr); + if (proc_entity != nullptr) { + if (proc_entity->flags & EntityFlag_Disabled) { + GB_ASSERT(tv.type == nullptr); + return {}; + } + } + + if (proc_expr->tav.mode == Addressing_Constant) { + ExactValue v = proc_expr->tav.value; + switch (v.kind) { + case ExactValue_Integer: + { + u64 u = big_int_to_u64(&v.value_integer); + cgValue x = cg_value(tb_inst_uint(p->func, TB_TYPE_PTR, u), t_rawptr); + value = cg_emit_conv(p, x, proc_expr->tav.type); + break; + } + case ExactValue_Pointer: + { + u64 u = cast(u64)v.value_pointer; + cgValue x = cg_value(tb_inst_uint(p->func, TB_TYPE_PTR, u), t_rawptr); + value = cg_emit_conv(p, x, proc_expr->tav.type); + break; + } + } + } + + if (value.node == nullptr) { + value = cg_build_expr(p, proc_expr); + } + if (value.kind == cgValue_Addr) { + value = cg_emit_load(p, value); + } + GB_ASSERT(value.kind == cgValue_Value); + GB_ASSERT(is_type_proc(value.type)); + + return cg_emit_call(p, value, {}); +} |