Commit 58dc2b719c

Andrew Kelley <superjoe30@gmail.com>
2018-03-01 00:22:43
better coroutine codegen, now passing first coro test
we have to use the Suspend block with llvm.coro.end to return from the coro
1 parent ad2a29c
Changed files (3)
src/ir.cpp
@@ -6225,19 +6225,14 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
         ir_build_call(irb, scope, node, nullptr, free_fn, arg_count, args, false, FnInlineAuto, false, nullptr);
 
         IrBasicBlock *resume_block = ir_create_basic_block(irb, scope, "Resume");
-        IrBasicBlock *return_block = ir_create_basic_block(irb, scope, "Return");
-        ir_build_cond_br(irb, scope, node, resume_awaiter, resume_block, return_block, const_bool_false);
+        ir_build_cond_br(irb, scope, node, resume_awaiter, resume_block, irb->exec->coro_suspend_block, const_bool_false);
 
         ir_set_cursor_at_end_and_append_block(irb, resume_block);
         IrInstruction *unwrapped_await_handle_ptr = ir_build_unwrap_maybe(irb, scope, node,
                 irb->exec->coro_awaiter_field_ptr, false);
         IrInstruction *awaiter_handle = ir_build_load_ptr(irb, scope, node, unwrapped_await_handle_ptr);
         ir_build_coro_resume(irb, scope, node, awaiter_handle);
-        ir_build_br(irb, scope, node, return_block, const_bool_false);
-
-        ir_set_cursor_at_end_and_append_block(irb, return_block);
-        IrInstruction *undef = ir_build_const_undefined(irb, scope, node);
-        ir_build_return(irb, scope, node, undef);
+        ir_build_br(irb, scope, node, irb->exec->coro_suspend_block, const_bool_false);
     }
 
     return true;
test/cases/coroutines.zig
@@ -0,0 +1,16 @@
+const std = @import("std");
+const assert = std.debug.assert;
+
+var x: i32 = 1;
+
+test "create a coroutine and cancel it" {
+    const p = try (async(std.debug.global_allocator) emptyAsyncFn());
+    cancel p;
+    assert(x == 2);
+}
+
+async fn emptyAsyncFn() void {
+    x += 1;
+    suspend;
+    x += 1;
+}
test/behavior.zig
@@ -11,6 +11,7 @@ comptime {
     _ = @import("cases/bugs/656.zig");
     _ = @import("cases/cast.zig");
     _ = @import("cases/const_slice_child.zig");
+    _ = @import("cases/coroutines.zig");
     _ = @import("cases/defer.zig");
     _ = @import("cases/enum.zig");
     _ = @import("cases/enum_with_members.zig");
@@ -34,8 +35,8 @@ comptime {
     _ = @import("cases/sizeof_and_typeof.zig");
     _ = @import("cases/slice.zig");
     _ = @import("cases/struct.zig");
-    _ = @import("cases/struct_contains_slice_of_itself.zig");
     _ = @import("cases/struct_contains_null_ptr_itself.zig");
+    _ = @import("cases/struct_contains_slice_of_itself.zig");
     _ = @import("cases/switch.zig");
     _ = @import("cases/switch_prong_err_enum.zig");
     _ = @import("cases/switch_prong_implicit_cast.zig");