diff options
| author | gingerBill <bill@gingerbill.org> | 2019-12-15 11:10:50 +0000 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2019-12-15 11:10:50 +0000 |
| commit | 7f5021c8e95e2861388c89d9d467d773339d5f4a (patch) | |
| tree | a47b0593e862ba1f730a2a943b9cc5d1d1a2f1e1 /src/ir.cpp | |
| parent | 8bec32477995f5a48fdb784bebe522015aedb036 (diff) | |
Disallow procedure calls with an associated deferred procedure to be used in logical binary expressions (short-circuiting)
Diffstat (limited to 'src/ir.cpp')
| -rw-r--r-- | src/ir.cpp | 51 |
1 files changed, 40 insertions, 11 deletions
diff --git a/src/ir.cpp b/src/ir.cpp index 6a9835636..19fa94485 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -91,6 +91,7 @@ enum irDeferExitKind { enum irDeferKind { irDefer_Node, irDefer_Instr, + irDefer_Proc, }; struct irDefer { @@ -102,6 +103,10 @@ struct irDefer { Ast *stmt; // NOTE(bill): 'instr' will be copied every time to create a new one irValue *instr; + struct { + irValue *deferred; + Array<irValue *> result_as_args; + } proc; }; }; @@ -1554,6 +1559,17 @@ irDefer ir_add_defer_instr(irProcedure *proc, isize scope_index, irValue *instr) return d; } +irDefer ir_add_defer_proc(irProcedure *proc, isize scope_index, irValue *deferred, Array<irValue *> const &result_as_args) { + irDefer d = {irDefer_Proc}; + d.scope_index = proc->scope_index; + d.block = proc->curr_block; + d.proc.deferred = deferred; + d.proc.result_as_args = result_as_args; + array_add(&proc->defer_stmts, d); + return d; +} + + irValue *ir_add_module_constant(irModule *m, Type *type, ExactValue value) { @@ -3202,8 +3218,7 @@ irValue *ir_emit_call(irProcedure *p, irValue *value, Array<irValue *> const &ar break; } - irValue *deferred_call = ir_de_emit(p, ir_emit_call(p, deferred, result_as_args)); - ir_add_defer_instr(p, p->scope_index, deferred_call); + ir_add_defer_proc(p, p->scope_index, deferred, result_as_args); } } @@ -3271,21 +3286,34 @@ void ir_open_scope(irProcedure *proc) { proc->scope_index++; } -void ir_close_scope(irProcedure *proc, irDeferExitKind kind, irBlock *block) { +void ir_close_scope(irProcedure *proc, irDeferExitKind kind, irBlock *block, bool pop_stack=true) { ir_emit_defer_stmts(proc, kind, block); GB_ASSERT(proc->scope_index > 0); // NOTE(bill): Remove `context`s made in that scope + + isize end_idx = proc->context_stack.count-1; + isize pop_count = 0; + for (;;) { - irContextData *end = array_end_ptr(&proc->context_stack); + if (end_idx < 0) { + break; + } + irContextData *end = &proc->context_stack[end_idx]; if (end == nullptr) { break; } if (end->scope_index != proc->scope_index) { break; } - array_pop(&proc->context_stack); + end_idx -= 1; + pop_count += 1; + } + if (pop_stack) { + for (isize i = 0; i < pop_count; i++) { + array_pop(&proc->context_stack); + } } @@ -6256,6 +6284,8 @@ void ir_build_defer_stmt(irProcedure *proc, irDefer d) { // NOTE(bill): Need to make a new copy irValue *instr = cast(irValue *)gb_alloc_copy(ir_allocator(), d.instr, gb_size_of(irValue)); ir_emit(proc, instr); + } else if (d.kind == irDefer_Proc) { + ir_emit_call(proc, d.proc.deferred, d.proc.result_as_args); } } @@ -6959,11 +6989,6 @@ irValue *ir_build_expr_internal(irProcedure *proc, Ast *expr) { return nullptr; case_end; - case_ast_node(re, RunExpr, expr); - // TODO(bill): Run Expression - return ir_build_expr(proc, re->expr); - case_end; - case_ast_node(de, DerefExpr, expr); return ir_addr_load(proc, ir_build_addr(proc, expr)); case_end; @@ -9499,7 +9524,6 @@ void ir_build_stmt_internal(irProcedure *proc, Ast *node) { case_ast_node(is, IfStmt, node); ir_emit_comment(proc, str_lit("IfStmt")); ir_open_scope(proc); // Scope #1 - defer (ir_close_scope(proc, irDeferExit_Default, nullptr)); if (is->init != nullptr) { // TODO(bill): Should this have a separate block to begin with? @@ -9525,7 +9549,9 @@ void ir_build_stmt_internal(irProcedure *proc, Ast *node) { tl->is_block = true; } + // ir_open_scope(proc); ir_build_stmt(proc, is->body); + // ir_close_scope(proc, irDeferExit_Default, nullptr); ir_emit_jump(proc, done); @@ -9539,7 +9565,10 @@ void ir_build_stmt_internal(irProcedure *proc, Ast *node) { ir_emit_jump(proc, done); } + ir_start_block(proc, done); + ir_close_scope(proc, irDeferExit_Default, nullptr); + case_end; case_ast_node(fs, ForStmt, node); |