authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-07-21 20:54:08-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-07-21 20:54:08-04:00
log11bd50f2b2a74ce25d841a15ba67d042d41b71c2
tree8221af0a57e853be09b7dea942ba2f44261f8270
parent78e03c466c6641571adef4bb3931d6cc6f425eb4
signaturelock-open Commit is signed but in an unrecognized format.

implement coroutine resume


5 files changed, 67 insertions(+), 2 deletions(-)

src/all_types.hpp+7
...@@ -2322,6 +2322,7 @@ enum IrInstructionId {...@@ -2322,6 +2322,7 @@ enum IrInstructionId {
2322 IrInstructionIdUnionInitNamedField,2322 IrInstructionIdUnionInitNamedField,
2323 IrInstructionIdSuspendBegin,2323 IrInstructionIdSuspendBegin,
2324 IrInstructionIdSuspendBr,2324 IrInstructionIdSuspendBr,
2325 IrInstructionIdCoroResume,
2325};2326};
23262327
2327struct IrInstruction {2328struct IrInstruction {
...@@ -3548,6 +3549,12 @@ struct IrInstructionSuspendBr {...@@ -3548,6 +3549,12 @@ struct IrInstructionSuspendBr {
3548 IrBasicBlock *resume_block;3549 IrBasicBlock *resume_block;
3549};3550};
35503551
3552struct IrInstructionCoroResume {
3553 IrInstruction base;
3554
3555 IrInstruction *frame;
3556};
3557
3551enum ResultLocId {3558enum ResultLocId {
3552 ResultLocIdInvalid,3559 ResultLocIdInvalid,
3553 ResultLocIdNone,3560 ResultLocIdNone,
src/codegen.cpp+14
...@@ -4969,6 +4969,18 @@ static LLVMValueRef ir_render_suspend_br(CodeGen *g, IrExecutable *executable,...@@ -4969,6 +4969,18 @@ static LLVMValueRef ir_render_suspend_br(CodeGen *g, IrExecutable *executable,
4969 return nullptr;4969 return nullptr;
4970}4970}
49714971
4972static LLVMValueRef ir_render_coro_resume(CodeGen *g, IrExecutable *executable,
4973 IrInstructionCoroResume *instruction)
4974{
4975 LLVMValueRef frame = ir_llvm_value(g, instruction->frame);
4976 ZigType *frame_type = instruction->frame->value.type;
4977 assert(frame_type->id == ZigTypeIdCoroFrame);
4978 ZigFn *fn = frame_type->data.frame.fn;
4979 LLVMValueRef fn_val = fn_llvm_value(g, fn);
4980 LLVMBuildCall(g->builder, fn_val, &frame, 1, "");
4981 return nullptr;
4982}
4983
4972static void set_debug_location(CodeGen *g, IrInstruction *instruction) {4984static void set_debug_location(CodeGen *g, IrInstruction *instruction) {
4973 AstNode *source_node = instruction->source_node;4985 AstNode *source_node = instruction->source_node;
4974 Scope *scope = instruction->scope;4986 Scope *scope = instruction->scope;
...@@ -5213,6 +5225,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,...@@ -5213,6 +5225,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
5213 return ir_render_suspend_begin(g, executable, (IrInstructionSuspendBegin *)instruction);5225 return ir_render_suspend_begin(g, executable, (IrInstructionSuspendBegin *)instruction);
5214 case IrInstructionIdSuspendBr:5226 case IrInstructionIdSuspendBr:
5215 return ir_render_suspend_br(g, executable, (IrInstructionSuspendBr *)instruction);5227 return ir_render_suspend_br(g, executable, (IrInstructionSuspendBr *)instruction);
5228 case IrInstructionIdCoroResume:
5229 return ir_render_coro_resume(g, executable, (IrInstructionCoroResume *)instruction);
5216 }5230 }
5217 zig_unreachable();5231 zig_unreachable();
5218}5232}
src/ir.cpp+34-1
...@@ -1035,6 +1035,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionSuspendBr *) {...@@ -1035,6 +1035,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionSuspendBr *) {
1035 return IrInstructionIdSuspendBr;1035 return IrInstructionIdSuspendBr;
1036}1036}
10371037
1038static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroResume *) {
1039 return IrInstructionIdCoroResume;
1040}
1041
1038template<typename T>1042template<typename T>
1039static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) {1043static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) {
1040 T *special_instruction = allocate<T>(1);1044 T *special_instruction = allocate<T>(1);
...@@ -3216,6 +3220,18 @@ static IrInstruction *ir_build_suspend_br(IrBuilder *irb, Scope *scope, AstNode...@@ -3216,6 +3220,18 @@ static IrInstruction *ir_build_suspend_br(IrBuilder *irb, Scope *scope, AstNode
3216 return &instruction->base;3220 return &instruction->base;
3217}3221}
32183222
3223static IrInstruction *ir_build_coro_resume(IrBuilder *irb, Scope *scope, AstNode *source_node,
3224 IrInstruction *frame)
3225{
3226 IrInstructionCoroResume *instruction = ir_build_instruction<IrInstructionCoroResume>(irb, scope, source_node);
3227 instruction->base.value.type = irb->codegen->builtin_types.entry_void;
3228 instruction->frame = frame;
3229
3230 ir_ref_instruction(frame, irb->current_basic_block);
3231
3232 return &instruction->base;
3233}
3234
3219static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) {3235static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) {
3220 results[ReturnKindUnconditional] = 0;3236 results[ReturnKindUnconditional] = 0;
3221 results[ReturnKindError] = 0;3237 results[ReturnKindError] = 0;
...@@ -7675,7 +7691,7 @@ static IrInstruction *ir_gen_resume(IrBuilder *irb, Scope *scope, AstNode *node)...@@ -7675,7 +7691,7 @@ static IrInstruction *ir_gen_resume(IrBuilder *irb, Scope *scope, AstNode *node)
7675 if (target_inst == irb->codegen->invalid_instruction)7691 if (target_inst == irb->codegen->invalid_instruction)
7676 return irb->codegen->invalid_instruction;7692 return irb->codegen->invalid_instruction;
76777693
7678 zig_panic("TODO ir_gen_resume");7694 return ir_build_coro_resume(irb, scope, node, target_inst);
7679}7695}
76807696
7681static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *node) {7697static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *node) {
...@@ -24134,6 +24150,20 @@ static IrInstruction *ir_analyze_instruction_suspend_br(IrAnalyze *ira, IrInstru...@@ -24134,6 +24150,20 @@ static IrInstruction *ir_analyze_instruction_suspend_br(IrAnalyze *ira, IrInstru
24134 return ir_finish_anal(ira, result);24150 return ir_finish_anal(ira, result);
24135}24151}
2413624152
24153static IrInstruction *ir_analyze_instruction_coro_resume(IrAnalyze *ira, IrInstructionCoroResume *instruction) {
24154 IrInstruction *frame = instruction->frame->child;
24155 if (type_is_invalid(frame->value.type))
24156 return ira->codegen->invalid_instruction;
24157
24158 if (frame->value.type->id != ZigTypeIdCoroFrame) {
24159 ir_add_error(ira, instruction->frame,
24160 buf_sprintf("expected frame, found '%s'", buf_ptr(&frame->value.type->name)));
24161 return ira->codegen->invalid_instruction;
24162 }
24163
24164 return ir_build_coro_resume(&ira->new_irb, instruction->base.scope, instruction->base.source_node, frame);
24165}
24166
24137static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction *instruction) {24167static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction *instruction) {
24138 switch (instruction->id) {24168 switch (instruction->id) {
24139 case IrInstructionIdInvalid:24169 case IrInstructionIdInvalid:
...@@ -24421,6 +24451,8 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction...@@ -24421,6 +24451,8 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction
24421 return ir_analyze_instruction_suspend_begin(ira, (IrInstructionSuspendBegin *)instruction);24451 return ir_analyze_instruction_suspend_begin(ira, (IrInstructionSuspendBegin *)instruction);
24422 case IrInstructionIdSuspendBr:24452 case IrInstructionIdSuspendBr:
24423 return ir_analyze_instruction_suspend_br(ira, (IrInstructionSuspendBr *)instruction);24453 return ir_analyze_instruction_suspend_br(ira, (IrInstructionSuspendBr *)instruction);
24454 case IrInstructionIdCoroResume:
24455 return ir_analyze_instruction_coro_resume(ira, (IrInstructionCoroResume *)instruction);
24424 }24456 }
24425 zig_unreachable();24457 zig_unreachable();
24426}24458}
...@@ -24555,6 +24587,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -24555,6 +24587,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
24555 case IrInstructionIdResetResult:24587 case IrInstructionIdResetResult:
24556 case IrInstructionIdSuspendBegin:24588 case IrInstructionIdSuspendBegin:
24557 case IrInstructionIdSuspendBr:24589 case IrInstructionIdSuspendBr:
24590 case IrInstructionIdCoroResume:
24558 return true;24591 return true;
2455924592
24560 case IrInstructionIdPhi:24593 case IrInstructionIdPhi:
src/ir_print.cpp+9
...@@ -1513,6 +1513,12 @@ static void ir_print_suspend_br(IrPrint *irp, IrInstructionSuspendBr *instructio...@@ -1513,6 +1513,12 @@ static void ir_print_suspend_br(IrPrint *irp, IrInstructionSuspendBr *instructio
1513 fprintf(irp->f, ")");1513 fprintf(irp->f, ")");
1514}1514}
15151515
1516static void ir_print_coro_resume(IrPrint *irp, IrInstructionCoroResume *instruction) {
1517 fprintf(irp->f, "@coroResume(");
1518 ir_print_other_instruction(irp, instruction->frame);
1519 fprintf(irp->f, ")");
1520}
1521
1516static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {1522static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
1517 ir_print_prefix(irp, instruction);1523 ir_print_prefix(irp, instruction);
1518 switch (instruction->id) {1524 switch (instruction->id) {
...@@ -1977,6 +1983,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {...@@ -1977,6 +1983,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
1977 case IrInstructionIdSuspendBr:1983 case IrInstructionIdSuspendBr:
1978 ir_print_suspend_br(irp, (IrInstructionSuspendBr *)instruction);1984 ir_print_suspend_br(irp, (IrInstructionSuspendBr *)instruction);
1979 break;1985 break;
1986 case IrInstructionIdCoroResume:
1987 ir_print_coro_resume(irp, (IrInstructionCoroResume *)instruction);
1988 break;
1980 }1989 }
1981 fprintf(irp->f, "\n");1990 fprintf(irp->f, "\n");
1982}1991}
test/stage1/behavior/coroutines.zig+3-1
...@@ -4,9 +4,11 @@ const expect = std.testing.expect;...@@ -4,9 +4,11 @@ const expect = std.testing.expect;
44
5var x: i32 = 1;5var x: i32 = 1;
66
7test "simple coroutine suspend" {7test "simple coroutine suspend and resume" {
8 const p = async simpleAsyncFn();8 const p = async simpleAsyncFn();
9 expect(x == 2);9 expect(x == 2);
10 resume p;
11 expect(x == 3);
10}12}
11fn simpleAsyncFn() void {13fn simpleAsyncFn() void {
12 x += 1;14 x += 1;