mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 23:58:50 +00:00
Fix context bug with deferred_* attributes which caused a new context to be created every time
This commit is contained in:
+5
-6
@@ -1594,34 +1594,33 @@ irValue *ir_emit_struct_ep(irProcedure *proc, irValue *s, i32 index);
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
irDefer ir_add_defer_node(irProcedure *proc, isize scope_index, Ast *stmt) {
|
void ir_add_defer_node(irProcedure *proc, isize scope_index, Ast *stmt) {
|
||||||
irDefer d = {irDefer_Node};
|
irDefer d = {irDefer_Node};
|
||||||
d.scope_index = scope_index;
|
d.scope_index = scope_index;
|
||||||
d.context_stack_count = proc->context_stack.count;
|
d.context_stack_count = proc->context_stack.count;
|
||||||
d.block = proc->curr_block;
|
d.block = proc->curr_block;
|
||||||
d.stmt = stmt;
|
d.stmt = stmt;
|
||||||
array_add(&proc->defer_stmts, d);
|
array_add(&proc->defer_stmts, d);
|
||||||
return d;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
irDefer ir_add_defer_instr(irProcedure *proc, isize scope_index, irValue *instr) {
|
void ir_add_defer_instr(irProcedure *proc, isize scope_index, irValue *instr) {
|
||||||
irDefer d = {irDefer_Instr};
|
irDefer d = {irDefer_Instr};
|
||||||
d.scope_index = proc->scope_index;
|
d.scope_index = proc->scope_index;
|
||||||
|
d.context_stack_count = proc->context_stack.count;
|
||||||
d.block = proc->curr_block;
|
d.block = proc->curr_block;
|
||||||
d.instr = instr; // NOTE(bill): It will make a copy everytime it is called
|
d.instr = instr; // NOTE(bill): It will make a copy everytime it is called
|
||||||
array_add(&proc->defer_stmts, d);
|
array_add(&proc->defer_stmts, d);
|
||||||
return d;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
irDefer ir_add_defer_proc(irProcedure *proc, isize scope_index, irValue *deferred, Array<irValue *> const &result_as_args) {
|
void ir_add_defer_proc(irProcedure *proc, isize scope_index, irValue *deferred, Array<irValue *> const &result_as_args) {
|
||||||
irDefer d = {irDefer_Proc};
|
irDefer d = {irDefer_Proc};
|
||||||
d.scope_index = proc->scope_index;
|
d.scope_index = proc->scope_index;
|
||||||
|
d.context_stack_count = proc->context_stack.count;
|
||||||
d.block = proc->curr_block;
|
d.block = proc->curr_block;
|
||||||
d.proc.deferred = deferred;
|
d.proc.deferred = deferred;
|
||||||
d.proc.result_as_args = result_as_args;
|
d.proc.result_as_args = result_as_args;
|
||||||
array_add(&proc->defer_stmts, d);
|
array_add(&proc->defer_stmts, d);
|
||||||
return d;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
irValue *ir_add_module_constant(irModule *m, Type *type, ExactValue value);
|
irValue *ir_add_module_constant(irModule *m, Type *type, ExactValue value);
|
||||||
|
|||||||
+69
-44
@@ -2545,17 +2545,7 @@ void lb_begin_procedure_body(lbProcedure *p) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (p->type->Proc.calling_convention == ProcCC_Odin) {
|
if (p->type->Proc.calling_convention == ProcCC_Odin) {
|
||||||
Entity *e = alloc_entity_param(nullptr, make_token_ident(str_lit("__.context_ptr")), t_context_ptr, false, false);
|
lb_push_context_onto_stack_from_implicit_parameter(p);
|
||||||
e->flags |= EntityFlag_NoAlias;
|
|
||||||
lbValue param = {};
|
|
||||||
param.value = LLVMGetParam(p->value, LLVMCountParams(p->value)-1);
|
|
||||||
param.type = e->type;
|
|
||||||
lb_add_entity(p->module, e, param);
|
|
||||||
lbAddr ctx_addr = {};
|
|
||||||
ctx_addr.kind = lbAddr_Context;
|
|
||||||
ctx_addr.addr = param;
|
|
||||||
lbContextData ctx = {ctx_addr, p->scope_index};
|
|
||||||
array_add(&p->context_stack, ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lb_start_block(p, p->entry_block);
|
lb_start_block(p, p->entry_block);
|
||||||
@@ -6641,10 +6631,38 @@ void lb_emit_init_context(lbProcedure *p, lbAddr addr) {
|
|||||||
lb_emit_runtime_call(p, "__init_context", args);
|
lb_emit_runtime_call(p, "__init_context", args);
|
||||||
}
|
}
|
||||||
|
|
||||||
void lb_push_context_onto_stack(lbProcedure *p, lbAddr ctx) {
|
lbContextData *lb_push_context_onto_stack_from_implicit_parameter(lbProcedure *p) {
|
||||||
|
Type *pt = base_type(p->type);
|
||||||
|
GB_ASSERT(pt->kind == Type_Proc);
|
||||||
|
GB_ASSERT(pt->Proc.calling_convention == ProcCC_Odin);
|
||||||
|
|
||||||
|
Entity *e = alloc_entity_param(nullptr, make_token_ident(str_lit("__.context_ptr")), t_context_ptr, false, false);
|
||||||
|
e->flags |= EntityFlag_NoAlias;
|
||||||
|
|
||||||
|
LLVMValueRef context_ptr = LLVMGetParam(p->value, LLVMCountParams(p->value)-1);
|
||||||
|
context_ptr = LLVMBuildPointerCast(p->builder, context_ptr, lb_type(p->module, e->type), "");
|
||||||
|
|
||||||
|
lbValue param = {context_ptr, e->type};
|
||||||
|
lb_add_entity(p->module, e, param);
|
||||||
|
lbAddr ctx_addr = {};
|
||||||
|
ctx_addr.kind = lbAddr_Context;
|
||||||
|
ctx_addr.addr = param;
|
||||||
|
|
||||||
|
lbContextData *cd = array_add_and_get(&p->context_stack);
|
||||||
|
cd->ctx = ctx_addr;
|
||||||
|
cd->scope_index = -1;
|
||||||
|
return cd;
|
||||||
|
}
|
||||||
|
|
||||||
|
lbContextData *lb_push_context_onto_stack(lbProcedure *p, lbAddr ctx) {
|
||||||
|
if (p->name == "test.foo") {
|
||||||
|
gb_printf_err("lb_push_context_onto_stack %.*s\n", LIT(p->name));
|
||||||
|
}
|
||||||
ctx.kind = lbAddr_Context;
|
ctx.kind = lbAddr_Context;
|
||||||
lbContextData cd = {ctx, p->scope_index};
|
lbContextData *cd = array_add_and_get(&p->context_stack);
|
||||||
array_add(&p->context_stack, cd);
|
cd->ctx = ctx;
|
||||||
|
cd->scope_index = p->scope_index;
|
||||||
|
return cd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -6655,13 +6673,13 @@ lbAddr lb_find_or_generate_context_ptr(lbProcedure *p) {
|
|||||||
|
|
||||||
Type *pt = base_type(p->type);
|
Type *pt = base_type(p->type);
|
||||||
GB_ASSERT(pt->kind == Type_Proc);
|
GB_ASSERT(pt->kind == Type_Proc);
|
||||||
{
|
GB_ASSERT(pt->Proc.calling_convention != ProcCC_Odin);
|
||||||
lbAddr c = lb_add_local_generated(p, t_context, false);
|
|
||||||
c.kind = lbAddr_Context;
|
lbAddr c = lb_add_local_generated(p, t_context, true);
|
||||||
lb_emit_init_context(p, c);
|
c.kind = lbAddr_Context;
|
||||||
lb_push_context_onto_stack(p, c);
|
lb_emit_init_context(p, c);
|
||||||
return c;
|
lb_push_context_onto_stack(p, c);
|
||||||
}
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
lbValue lb_address_from_load_or_generate_local(lbProcedure *p, lbValue value) {
|
lbValue lb_address_from_load_or_generate_local(lbProcedure *p, lbValue value) {
|
||||||
@@ -6985,7 +7003,7 @@ lbValue lb_emit_deep_field_ev(lbProcedure *p, lbValue e, Selection sel) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void lb_build_defer_stmt(lbProcedure *p, lbDefer d) {
|
void lb_build_defer_stmt(lbProcedure *p, lbDefer 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
|
||||||
LLVMValueRef last_instr = LLVMGetLastInstruction(p->curr_block->block);
|
LLVMValueRef last_instr = LLVMGetLastInstruction(p->curr_block->block);
|
||||||
if (last_instr != nullptr && LLVMIsAReturnInst(last_instr)) {
|
if (last_instr != nullptr && LLVMIsAReturnInst(last_instr)) {
|
||||||
@@ -6994,10 +7012,10 @@ void lb_build_defer_stmt(lbProcedure *p, lbDefer d) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
defer (p->context_stack.count = prev_context_stack_count);
|
defer (p->context_stack.count = prev_context_stack_count);
|
||||||
p->context_stack.count = d.context_stack_count;
|
p->context_stack.count = d.context_stack_count;
|
||||||
|
|
||||||
|
|
||||||
lbBlock *b = lb_create_block(p, "defer");
|
lbBlock *b = lb_create_block(p, "defer");
|
||||||
if (last_instr == nullptr || !LLVMIsATerminatorInst(last_instr)) {
|
if (last_instr == nullptr || !LLVMIsATerminatorInst(last_instr)) {
|
||||||
lb_emit_jump(p, b);
|
lb_emit_jump(p, b);
|
||||||
@@ -7019,11 +7037,7 @@ void lb_emit_defer_stmts(lbProcedure *p, lbDeferExitKind kind, lbBlock *block) {
|
|||||||
isize count = p->defer_stmts.count;
|
isize count = p->defer_stmts.count;
|
||||||
isize i = count;
|
isize i = count;
|
||||||
while (i --> 0) {
|
while (i --> 0) {
|
||||||
lbDefer d = p->defer_stmts[i];
|
lbDefer const &d = p->defer_stmts[i];
|
||||||
|
|
||||||
isize prev_context_stack_count = p->context_stack.count;
|
|
||||||
defer (p->context_stack.count = prev_context_stack_count);
|
|
||||||
p->context_stack.count = d.context_stack_count;
|
|
||||||
|
|
||||||
if (kind == lbDeferExit_Default) {
|
if (kind == lbDeferExit_Default) {
|
||||||
if (p->scope_index == d.scope_index &&
|
if (p->scope_index == d.scope_index &&
|
||||||
@@ -7046,24 +7060,35 @@ void lb_emit_defer_stmts(lbProcedure *p, lbDeferExitKind kind, lbBlock *block) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lbDefer lb_add_defer_node(lbProcedure *p, isize scope_index, Ast *stmt) {
|
void lb_add_defer_node(lbProcedure *p, isize scope_index, Ast *stmt) {
|
||||||
lbDefer d = {lbDefer_Node};
|
Type *pt = base_type(p->type);
|
||||||
d.scope_index = scope_index;
|
GB_ASSERT(pt->kind == Type_Proc);
|
||||||
d.context_stack_count = p->context_stack.count;
|
if (pt->Proc.calling_convention == ProcCC_Odin) {
|
||||||
d.block = p->curr_block;
|
GB_ASSERT(p->context_stack.count != 0);
|
||||||
d.stmt = stmt;
|
}
|
||||||
array_add(&p->defer_stmts, d);
|
|
||||||
return d;
|
lbDefer *d = array_add_and_get(&p->defer_stmts);
|
||||||
|
d->kind = lbDefer_Node;
|
||||||
|
d->scope_index = scope_index;
|
||||||
|
d->context_stack_count = p->context_stack.count;
|
||||||
|
d->block = p->curr_block;
|
||||||
|
d->stmt = stmt;
|
||||||
}
|
}
|
||||||
|
|
||||||
lbDefer lb_add_defer_proc(lbProcedure *p, isize scope_index, lbValue deferred, Array<lbValue> const &result_as_args) {
|
void lb_add_defer_proc(lbProcedure *p, isize scope_index, lbValue deferred, Array<lbValue> const &result_as_args) {
|
||||||
lbDefer d = {lbDefer_Proc};
|
Type *pt = base_type(p->type);
|
||||||
d.scope_index = p->scope_index;
|
GB_ASSERT(pt->kind == Type_Proc);
|
||||||
d.block = p->curr_block;
|
if (pt->Proc.calling_convention == ProcCC_Odin) {
|
||||||
d.proc.deferred = deferred;
|
GB_ASSERT(p->context_stack.count != 0);
|
||||||
d.proc.result_as_args = result_as_args;
|
}
|
||||||
array_add(&p->defer_stmts, d);
|
|
||||||
return d;
|
lbDefer *d = array_add_and_get(&p->defer_stmts);
|
||||||
|
d->kind = lbDefer_Proc;
|
||||||
|
d->scope_index = p->scope_index;
|
||||||
|
d->block = p->curr_block;
|
||||||
|
d->context_stack_count = p->context_stack.count;
|
||||||
|
d->proc.deferred = deferred;
|
||||||
|
d->proc.result_as_args = result_as_args;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -315,7 +315,8 @@ lbValue lb_build_call_expr(lbProcedure *p, Ast *expr);
|
|||||||
|
|
||||||
|
|
||||||
lbAddr lb_find_or_generate_context_ptr(lbProcedure *p);
|
lbAddr lb_find_or_generate_context_ptr(lbProcedure *p);
|
||||||
void lb_push_context_onto_stack(lbProcedure *p, lbAddr ctx);
|
lbContextData *lb_push_context_onto_stack(lbProcedure *p, lbAddr ctx);
|
||||||
|
lbContextData *lb_push_context_onto_stack_from_implicit_parameter(lbProcedure *p);
|
||||||
|
|
||||||
|
|
||||||
lbAddr lb_add_global_generated(lbModule *m, Type *type, lbValue value={});
|
lbAddr lb_add_global_generated(lbModule *m, Type *type, lbValue value={});
|
||||||
@@ -327,7 +328,7 @@ lbValue lb_typeid(lbModule *m, Type *type);
|
|||||||
|
|
||||||
lbValue lb_address_from_load_or_generate_local(lbProcedure *p, lbValue value);
|
lbValue lb_address_from_load_or_generate_local(lbProcedure *p, lbValue value);
|
||||||
lbValue lb_address_from_load(lbProcedure *p, lbValue value);
|
lbValue lb_address_from_load(lbProcedure *p, lbValue value);
|
||||||
lbDefer lb_add_defer_node(lbProcedure *p, isize scope_index, Ast *stmt);
|
void lb_add_defer_node(lbProcedure *p, isize scope_index, Ast *stmt);
|
||||||
lbAddr lb_add_local_generated(lbProcedure *p, Type *type, bool zero_init);
|
lbAddr lb_add_local_generated(lbProcedure *p, Type *type, bool zero_init);
|
||||||
|
|
||||||
lbValue lb_emit_runtime_call(lbProcedure *p, char const *c_name, Array<lbValue> const &args);
|
lbValue lb_emit_runtime_call(lbProcedure *p, char const *c_name, Array<lbValue> const &args);
|
||||||
|
|||||||
Reference in New Issue
Block a user