Commit 83f8906449

Andrew Kelley <superjoe30@gmail.com>
2018-02-25 23:34:05
codegen for coro_resume instruction
See #727
1 parent 4eac759
Changed files (3)
src/all_types.hpp
@@ -1617,6 +1617,7 @@ struct CodeGen {
     LLVMValueRef coro_suspend_fn_val;
     LLVMValueRef coro_end_fn_val;
     LLVMValueRef coro_free_fn_val;
+    LLVMValueRef coro_resume_fn_val;
     bool error_during_imports;
 
     const char **clang_argv;
src/codegen.cpp
@@ -1051,6 +1051,21 @@ static LLVMValueRef get_coro_free_fn_val(CodeGen *g) {
     return g->coro_free_fn_val;
 }
 
+static LLVMValueRef get_coro_resume_fn_val(CodeGen *g) {
+    if (g->coro_resume_fn_val)
+        return g->coro_resume_fn_val;
+
+    LLVMTypeRef param_types[] = {
+        LLVMPointerType(LLVMInt8Type(), 0),
+    };
+    LLVMTypeRef fn_type = LLVMFunctionType(LLVMVoidType(), param_types, 1, false);
+    Buf *name = buf_sprintf("llvm.coro.resume");
+    g->coro_resume_fn_val = LLVMAddFunction(g->module, buf_ptr(name), fn_type);
+    assert(LLVMGetIntrinsicID(g->coro_resume_fn_val));
+
+    return g->coro_resume_fn_val;
+}
+
 static LLVMValueRef get_return_address_fn_val(CodeGen *g) {
     if (g->return_address_fn_val)
         return g->return_address_fn_val;
@@ -3935,7 +3950,8 @@ static LLVMValueRef ir_render_coro_free(CodeGen *g, IrExecutable *executable, Ir
 }
 
 static LLVMValueRef ir_render_coro_resume(CodeGen *g, IrExecutable *executable, IrInstructionCoroResume *instruction) {
-    zig_panic("TODO ir_render_coro_resume");
+    LLVMValueRef awaiter_handle = ir_llvm_value(g, instruction->awaiter_handle);
+    return LLVMBuildCall(g->builder, get_coro_resume_fn_val(g), &awaiter_handle, 1, "");
 }
 
 static void set_debug_location(CodeGen *g, IrInstruction *instruction) {
src/ir.cpp
@@ -6143,14 +6143,19 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
 
         ir_set_cursor_at_end_and_append_block(irb, end_free_block);
         IrBasicBlock *resume_block = ir_create_basic_block(irb, scope, "Resume");
-        ir_build_cond_br(irb, scope, node, resume_awaiter, resume_block, suspend_block, const_bool_false);
+        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_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, suspend_block, const_bool_false);
+        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);
     }
 
     return true;