| author | |
| committer | |
| log | 58dc2b719c8e5a13c91ebbbbf476998c7f3e925b |
| tree | 34ae2eb4d0624b69045ae79f23716357d0b2393b |
| parent | ad2a29ccf25af189fc180cba6843c20b9dd029d1 |
we have to use the Suspend block with llvm.coro.end to
return from the coro3 files changed, 20 insertions(+), 8 deletions(-)
src/ir.cpp+2-7| ... | ... | @@ -6225,19 +6225,14 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 6225 | 6225 | ir_build_call(irb, scope, node, nullptr, free_fn, arg_count, args, false, FnInlineAuto, false, nullptr); |
| 6226 | 6226 | |
| 6227 | 6227 | IrBasicBlock *resume_block = ir_create_basic_block(irb, scope, "Resume"); |
| 6228 | IrBasicBlock *return_block = ir_create_basic_block(irb, scope, "Return"); | |
| 6229 | ir_build_cond_br(irb, scope, node, resume_awaiter, resume_block, return_block, const_bool_false); | |
| 6228 | ir_build_cond_br(irb, scope, node, resume_awaiter, resume_block, irb->exec->coro_suspend_block, const_bool_false); | |
| 6230 | 6229 | |
| 6231 | 6230 | ir_set_cursor_at_end_and_append_block(irb, resume_block); |
| 6232 | 6231 | IrInstruction *unwrapped_await_handle_ptr = ir_build_unwrap_maybe(irb, scope, node, |
| 6233 | 6232 | irb->exec->coro_awaiter_field_ptr, false); |
| 6234 | 6233 | IrInstruction *awaiter_handle = ir_build_load_ptr(irb, scope, node, unwrapped_await_handle_ptr); |
| 6235 | 6234 | ir_build_coro_resume(irb, scope, node, awaiter_handle); |
| 6236 | ir_build_br(irb, scope, node, return_block, const_bool_false); | |
| 6237 | ||
| 6238 | ir_set_cursor_at_end_and_append_block(irb, return_block); | |
| 6239 | IrInstruction *undef = ir_build_const_undefined(irb, scope, node); | |
| 6240 | ir_build_return(irb, scope, node, undef); | |
| 6235 | ir_build_br(irb, scope, node, irb->exec->coro_suspend_block, const_bool_false); | |
| 6241 | 6236 | } |
| 6242 | 6237 | |
| 6243 | 6238 | return true; |
test/behavior.zig+2-1| ... | ... | @@ -11,6 +11,7 @@ comptime { |
| 11 | 11 | _ = @import("cases/bugs/656.zig"); |
| 12 | 12 | _ = @import("cases/cast.zig"); |
| 13 | 13 | _ = @import("cases/const_slice_child.zig"); |
| 14 | _ = @import("cases/coroutines.zig"); | |
| 14 | 15 | _ = @import("cases/defer.zig"); |
| 15 | 16 | _ = @import("cases/enum.zig"); |
| 16 | 17 | _ = @import("cases/enum_with_members.zig"); |
| ... | ... | @@ -34,8 +35,8 @@ comptime { |
| 34 | 35 | _ = @import("cases/sizeof_and_typeof.zig"); |
| 35 | 36 | _ = @import("cases/slice.zig"); |
| 36 | 37 | _ = @import("cases/struct.zig"); |
| 37 | _ = @import("cases/struct_contains_slice_of_itself.zig"); | |
| 38 | 38 | _ = @import("cases/struct_contains_null_ptr_itself.zig"); |
| 39 | _ = @import("cases/struct_contains_slice_of_itself.zig"); | |
| 39 | 40 | _ = @import("cases/switch.zig"); |
| 40 | 41 | _ = @import("cases/switch_prong_err_enum.zig"); |
| 41 | 42 | _ = @import("cases/switch_prong_implicit_cast.zig"); |
test/cases/coroutines.zig created+16| ... | ... | @@ -0,0 +1,16 @@ |
| 1 | const std = @import("std"); | |
| 2 | const assert = std.debug.assert; | |
| 3 | ||
| 4 | var x: i32 = 1; | |
| 5 | ||
| 6 | test "create a coroutine and cancel it" { | |
| 7 | const p = try (async(std.debug.global_allocator) emptyAsyncFn()); | |
| 8 | cancel p; | |
| 9 | assert(x == 2); | |
| 10 | } | |
| 11 | ||
| 12 | async fn emptyAsyncFn() void { | |
| 13 | x += 1; | |
| 14 | suspend; | |
| 15 | x += 1; | |
| 16 | } |