authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-02-28 18:22:43-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-02-28 18:22:43-05:00
log58dc2b719c8e5a13c91ebbbbf476998c7f3e925b
tree34ae2eb4d0624b69045ae79f23716357d0b2393b
parentad2a29ccf25af189fc180cba6843c20b9dd029d1

better coroutine codegen, now passing first coro test

we have to use the Suspend block with llvm.coro.end to return from the coro

3 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,19 +6225,14 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
6225 ir_build_call(irb, scope, node, nullptr, free_fn, arg_count, args, false, FnInlineAuto, false, nullptr);6225 ir_build_call(irb, scope, node, nullptr, free_fn, arg_count, args, false, FnInlineAuto, false, nullptr);
62266226
6227 IrBasicBlock *resume_block = ir_create_basic_block(irb, scope, "Resume");6227 IrBasicBlock *resume_block = ir_create_basic_block(irb, scope, "Resume");
6228 IrBasicBlock *return_block = ir_create_basic_block(irb, scope, "Return");6228 ir_build_cond_br(irb, scope, node, resume_awaiter, resume_block, irb->exec->coro_suspend_block, const_bool_false);
6229 ir_build_cond_br(irb, scope, node, resume_awaiter, resume_block, return_block, const_bool_false);
62306229
6231 ir_set_cursor_at_end_and_append_block(irb, resume_block);6230 ir_set_cursor_at_end_and_append_block(irb, resume_block);
6232 IrInstruction *unwrapped_await_handle_ptr = ir_build_unwrap_maybe(irb, scope, node,6231 IrInstruction *unwrapped_await_handle_ptr = ir_build_unwrap_maybe(irb, scope, node,
6233 irb->exec->coro_awaiter_field_ptr, false);6232 irb->exec->coro_awaiter_field_ptr, false);
6234 IrInstruction *awaiter_handle = ir_build_load_ptr(irb, scope, node, unwrapped_await_handle_ptr);6233 IrInstruction *awaiter_handle = ir_build_load_ptr(irb, scope, node, unwrapped_await_handle_ptr);
6235 ir_build_coro_resume(irb, scope, node, awaiter_handle);6234 ir_build_coro_resume(irb, scope, node, awaiter_handle);
6236 ir_build_br(irb, scope, node, return_block, const_bool_false);6235 ir_build_br(irb, scope, node, irb->exec->coro_suspend_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);
6241 }6236 }
62426237
6243 return true;6238 return true;
test/behavior.zig+2-1
...@@ -11,6 +11,7 @@ comptime {...@@ -11,6 +11,7 @@ comptime {
11 _ = @import("cases/bugs/656.zig");11 _ = @import("cases/bugs/656.zig");
12 _ = @import("cases/cast.zig");12 _ = @import("cases/cast.zig");
13 _ = @import("cases/const_slice_child.zig");13 _ = @import("cases/const_slice_child.zig");
14 _ = @import("cases/coroutines.zig");
14 _ = @import("cases/defer.zig");15 _ = @import("cases/defer.zig");
15 _ = @import("cases/enum.zig");16 _ = @import("cases/enum.zig");
16 _ = @import("cases/enum_with_members.zig");17 _ = @import("cases/enum_with_members.zig");
...@@ -34,8 +35,8 @@ comptime {...@@ -34,8 +35,8 @@ comptime {
34 _ = @import("cases/sizeof_and_typeof.zig");35 _ = @import("cases/sizeof_and_typeof.zig");
35 _ = @import("cases/slice.zig");36 _ = @import("cases/slice.zig");
36 _ = @import("cases/struct.zig");37 _ = @import("cases/struct.zig");
37 _ = @import("cases/struct_contains_slice_of_itself.zig");
38 _ = @import("cases/struct_contains_null_ptr_itself.zig");38 _ = @import("cases/struct_contains_null_ptr_itself.zig");
39 _ = @import("cases/struct_contains_slice_of_itself.zig");
39 _ = @import("cases/switch.zig");40 _ = @import("cases/switch.zig");
40 _ = @import("cases/switch_prong_err_enum.zig");41 _ = @import("cases/switch_prong_err_enum.zig");
41 _ = @import("cases/switch_prong_implicit_cast.zig");42 _ = @import("cases/switch_prong_implicit_cast.zig");
test/cases/coroutines.zig created+16
...@@ -0,0 +1,16 @@
1const std = @import("std");
2const assert = std.debug.assert;
3
4var x: i32 = 1;
5
6test "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
12async fn emptyAsyncFn() void {
13 x += 1;
14 suspend;
15 x += 1;
16}