mirror of
https://github.com/odin-lang/Odin.git
synced 2026-02-15 15:44:04 +00:00
Update TB; Fix calling nullptr TB_Node* problems
This commit is contained in:
@@ -1,5 +1,127 @@
|
||||
gb_internal cgValue cg_build_call_expr(cgProcedure *p, Ast *expr) {
|
||||
ast_node(ce, CallExpr, expr);
|
||||
// TODO(bill): cg_build_call_expr
|
||||
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);
|
||||
|
||||
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 {};
|
||||
}
|
||||
|
||||
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, {});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user