authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-02-08 15:27:45-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-02-08 15:28:12-05:00
log24d197b037f93d57e5c9b7d1c84cdc9ec7313081
tree55740974a4b81fdb768ca49366ddec51ecca7ba1
parentd80db3546cf49b8af434005de0e74509d07b4855
signaturelock-open Commit is signed but in an unrecognized format.

solve previous commit a better way


4 files changed, 36 insertions(+), 3 deletions(-)

src/all_types.hpp+3
...@@ -2490,6 +2490,9 @@ struct ScopeExpr {...@@ -2490,6 +2490,9 @@ struct ScopeExpr {
2490 size_t children_len;2490 size_t children_len;
24912491
2492 MemoizedBool need_spill;2492 MemoizedBool need_spill;
2493 // This is a hack. I apologize for this, I need this to work so that I
2494 // can make progress on other fronts. I'll pay off this tech debt eventually.
2495 bool spill_harder;
2493};2496};
24942497
2495// synchronized with code in define_builtin_compile_vars2498// synchronized with code in define_builtin_compile_vars
src/analyze.cpp+4-1
...@@ -6104,11 +6104,14 @@ static void mark_suspension_point(Scope *scope) {...@@ -6104,11 +6104,14 @@ static void mark_suspension_point(Scope *scope) {
6104 continue;6104 continue;
6105 }6105 }
6106 case ScopeIdExpr: {6106 case ScopeIdExpr: {
6107 ScopeExpr *parent_expr_scope = reinterpret_cast<ScopeExpr *>(scope);
6107 if (!looking_for_exprs) {6108 if (!looking_for_exprs) {
6109 if (parent_expr_scope->spill_harder) {
6110 parent_expr_scope->need_spill = MemoizedBoolTrue;
6111 }
6108 // Now we're only looking for a block, to see if it's in a loop (see the case ScopeIdBlock)6112 // Now we're only looking for a block, to see if it's in a loop (see the case ScopeIdBlock)
6109 continue;6113 continue;
6110 }6114 }
6111 ScopeExpr *parent_expr_scope = reinterpret_cast<ScopeExpr *>(scope);
6112 if (child_expr_scope != nullptr) {6115 if (child_expr_scope != nullptr) {
6113 for (size_t i = 0; parent_expr_scope->children_ptr[i] != child_expr_scope; i += 1) {6116 for (size_t i = 0; parent_expr_scope->children_ptr[i] != child_expr_scope; i += 1) {
6114 assert(i < parent_expr_scope->children_len);6117 assert(i < parent_expr_scope->children_len);
src/ir.cpp+5-2
...@@ -8874,7 +8874,10 @@ static IrInstSrc *ir_gen_if_optional_expr(IrBuilderSrc *irb, Scope *scope, AstNo...@@ -8874,7 +8874,10 @@ static IrInstSrc *ir_gen_if_optional_expr(IrBuilderSrc *irb, Scope *scope, AstNo
8874 AstNode *else_node = node->data.test_expr.else_node;8874 AstNode *else_node = node->data.test_expr.else_node;
8875 bool var_is_ptr = node->data.test_expr.var_is_ptr;8875 bool var_is_ptr = node->data.test_expr.var_is_ptr;
88768876
8877 IrInstSrc *maybe_val_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr);8877 ScopeExpr *spill_scope = create_expr_scope(irb->codegen, expr_node, scope);
8878 spill_scope->spill_harder = true;
8879
8880 IrInstSrc *maybe_val_ptr = ir_gen_node_extra(irb, expr_node, &spill_scope->base, LValPtr, nullptr);
8878 if (maybe_val_ptr == irb->codegen->invalid_inst_src)8881 if (maybe_val_ptr == irb->codegen->invalid_inst_src)
8879 return maybe_val_ptr;8882 return maybe_val_ptr;
88808883
...@@ -8899,7 +8902,7 @@ static IrInstSrc *ir_gen_if_optional_expr(IrBuilderSrc *irb, Scope *scope, AstNo...@@ -8899,7 +8902,7 @@ static IrInstSrc *ir_gen_if_optional_expr(IrBuilderSrc *irb, Scope *scope, AstNo
88998902
8900 ir_set_cursor_at_end_and_append_block(irb, then_block);8903 ir_set_cursor_at_end_and_append_block(irb, then_block);
89018904
8902 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime);8905 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, &spill_scope->base, is_comptime);
8903 Scope *var_scope;8906 Scope *var_scope;
8904 if (var_symbol) {8907 if (var_symbol) {
8905 bool is_shadowable = false;8908 bool is_shadowable = false;
test/stage1/behavior/async_fn.zig+24
...@@ -1416,3 +1416,27 @@ test "async function call resolves target fn frame, runtime func" {...@@ -1416,3 +1416,27 @@ test "async function call resolves target fn frame, runtime func" {
1416 resume S.global_frame;1416 resume S.global_frame;
1417 expect(S.global_int == 10);1417 expect(S.global_int == 10);
1418}1418}
1419
1420test "properly spill optional payload capture value" {
1421 const S = struct {
1422 var global_frame: anyframe = undefined;
1423 var global_int: usize = 2;
1424
1425 fn foo() void {
1426 var opt: ?usize = 1234;
1427 if (opt) |x| {
1428 bar();
1429 global_int += x;
1430 }
1431 }
1432
1433 fn bar() void {
1434 global_frame = @frame();
1435 suspend;
1436 global_int += 1;
1437 }
1438 };
1439 _ = async S.foo();
1440 resume S.global_frame;
1441 expect(S.global_int == 1237);
1442}