mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-07 16:18:52 +00:00
Add defer statements; add implicit context pointer to context stack
This commit is contained in:
+23
-4
@@ -181,11 +181,8 @@ gb_internal void cg_procedure_begin(cgProcedure *p) {
|
|||||||
|
|
||||||
GB_ASSERT(p->type->kind == Type_Proc);
|
GB_ASSERT(p->type->kind == Type_Proc);
|
||||||
TypeProc *pt = &p->type->Proc;
|
TypeProc *pt = &p->type->Proc;
|
||||||
if (pt->params == nullptr) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
int param_index = 0;
|
int param_index = 0;
|
||||||
for (Entity *e : pt->params->Tuple.variables) {
|
if (pt->params != nullptr) for (Entity *e : pt->params->Tuple.variables) {
|
||||||
if (e->kind != Entity_Variable) {
|
if (e->kind != Entity_Variable) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -247,6 +244,28 @@ gb_internal void cg_procedure_begin(cgProcedure *p) {
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (p->type->Proc.calling_convention == ProcCC_Odin) {
|
||||||
|
// NOTE(bill): Push context on to stack from implicit parameter
|
||||||
|
|
||||||
|
String name = str_lit("__.context_ptr");
|
||||||
|
|
||||||
|
Entity *e = alloc_entity_param(nullptr, make_token_ident(name), t_context_ptr, false, false);
|
||||||
|
e->flags |= EntityFlag_NoAlias;
|
||||||
|
|
||||||
|
TB_Node *param = p->param_nodes[p->param_nodes.count-1];
|
||||||
|
param = tb_inst_load(p->func, TB_TYPE_PTR, param, cast(TB_CharUnits)build_context.ptr_size, false);
|
||||||
|
|
||||||
|
cgValue local = cg_value(param, t_context_ptr);
|
||||||
|
cgAddr addr = cg_addr(local);
|
||||||
|
map_set(&p->variable_map, e, addr);
|
||||||
|
|
||||||
|
|
||||||
|
cgContextData *cd = array_add_and_get(&p->context_stack);
|
||||||
|
cd->ctx = addr;
|
||||||
|
cd->scope_index = -1;
|
||||||
|
cd->uses = +1; // make sure it has been used already
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gb_internal void cg_procedure_end(cgProcedure *p) {
|
gb_internal void cg_procedure_end(cgProcedure *p) {
|
||||||
|
|||||||
+26
-10
@@ -725,14 +725,14 @@ gb_internal void cg_build_defer_stmt(cgProcedure *p, cgDefer const &d) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NOTE(bill): The prev block may defer injection before it's terminator
|
// NOTE(bill): The prev block may defer injection before it's terminator
|
||||||
TB_Node *last_instr = nullptr;
|
TB_Node *last_inst = nullptr;
|
||||||
if (curr_region->input_count) {
|
// if (curr_region->input_count) {
|
||||||
last_instr = *(curr_region->inputs + curr_region->input_count);
|
// last_inst = *(curr_region->inputs + curr_region->input_count);
|
||||||
}
|
// }
|
||||||
if (last_instr && TB_IS_NODE_TERMINATOR(last_instr->type)) {
|
// if (last_inst && TB_IS_NODE_TERMINATOR(last_inst->type)) {
|
||||||
// NOTE(bill): ReturnStmt defer stuff will be handled previously
|
// // NOTE(bill): ReturnStmt defer stuff will be handled previously
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
|
||||||
isize prev_context_stack_count = p->context_stack.count;
|
isize prev_context_stack_count = p->context_stack.count;
|
||||||
GB_ASSERT(prev_context_stack_count <= p->context_stack.capacity);
|
GB_ASSERT(prev_context_stack_count <= p->context_stack.capacity);
|
||||||
@@ -740,7 +740,7 @@ gb_internal void cg_build_defer_stmt(cgProcedure *p, cgDefer const &d) {
|
|||||||
p->context_stack.count = d.context_stack_count;
|
p->context_stack.count = d.context_stack_count;
|
||||||
|
|
||||||
TB_Node *b = cg_control_region(p, "defer");
|
TB_Node *b = cg_control_region(p, "defer");
|
||||||
if (last_instr == nullptr) {
|
if (last_inst == nullptr) {
|
||||||
cg_emit_goto(p, b);
|
cg_emit_goto(p, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -771,7 +771,6 @@ gb_internal void cg_emit_defer_stmts(cgProcedure *p, cgDeferExitKind kind, TB_No
|
|||||||
} else if (kind == cgDeferExit_Return) {
|
} else if (kind == cgDeferExit_Return) {
|
||||||
cg_build_defer_stmt(p, d);
|
cg_build_defer_stmt(p, d);
|
||||||
} else if (kind == cgDeferExit_Branch) {
|
} else if (kind == cgDeferExit_Branch) {
|
||||||
GB_PANIC("TODO(bill): cgDeferExit_Branch");
|
|
||||||
GB_ASSERT(control_region != nullptr);
|
GB_ASSERT(control_region != nullptr);
|
||||||
isize lower_limit = -1;
|
isize lower_limit = -1;
|
||||||
for (auto const &cr : p->control_regions) {
|
for (auto const &cr : p->control_regions) {
|
||||||
@@ -1465,6 +1464,23 @@ gb_internal void cg_build_stmt(cgProcedure *p, Ast *node) {
|
|||||||
cg_build_switch_stmt(p, node);
|
cg_build_switch_stmt(p, node);
|
||||||
case_end;
|
case_end;
|
||||||
|
|
||||||
|
case_ast_node(ds, DeferStmt, node);
|
||||||
|
Type *pt = base_type(p->type);
|
||||||
|
GB_ASSERT(pt->kind == Type_Proc);
|
||||||
|
if (pt->Proc.calling_convention == ProcCC_Odin) {
|
||||||
|
GB_ASSERT(p->context_stack.count != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
cgDefer *d = array_add_and_get(&p->defer_stack);
|
||||||
|
d->kind = cgDefer_Node;
|
||||||
|
d->scope_index = p->scope_index;
|
||||||
|
d->context_stack_count = p->context_stack.count;
|
||||||
|
d->control_region = tb_inst_get_control(p->func);
|
||||||
|
GB_ASSERT(d->control_region != nullptr);
|
||||||
|
d->stmt = ds->stmt;
|
||||||
|
case_end;
|
||||||
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
GB_PANIC("TODO cg_build_stmt %.*s", LIT(ast_strings[node->kind]));
|
GB_PANIC("TODO cg_build_stmt %.*s", LIT(ast_strings[node->kind]));
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user