diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2019-08-06 16:37:25 -0400 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2019-08-06 16:53:22 -0400 |
| commit | 400500a3afafca8178f13a7e4e1cd0ae7808aff2 (patch) | |
| tree | f6ee011721206db3cda4952dd2eccaeb71c7e632 /src/ir_print.cpp | |
| parent | 20f63e588e62c4a7250bc96c9e5b54c8106ad1af (diff) | |
| download | zig-400500a3afafca8178f13a7e4e1cd0ae7808aff2.tar.gz zig-400500a3afafca8178f13a7e4e1cd0ae7808aff2.zip | |
improve async function semantics
* add safety panic for resuming a function which is returning, pending
an await
* remove IrInstructionResultPtr
* add IrInstructionReturnBegin. This does the early return in async
functions; does nothing in normal functions.
* `await` gets a result location
* `analyze_fn_async` will call `analyze_fn_body` if necessary.
* async function frames have a result pointer field for themselves
to access and one for the awaiter to supply before the atomic rmw.
when returning, async functions copy the result to the awaiter result
pointer, if it is non-null.
* async function frames have a stack trace pointer which is supplied by
the awaiter before the atomicrmw. Later in the frame is a stack trace
struct and addresses, which is used for its own calls and awaits.
* when awaiting an async function, if an early return occurred, the
awaiter tail resumes the frame.
* when an async function returns, early return does a suspend
(in IrInstructionReturnBegin) before copying
the error return trace data, result, and running the defers.
After the last defer runs, the frame will no longer be accessed.
* proper acquire/release atomic ordering attributes in async functions.
Diffstat (limited to 'src/ir_print.cpp')
| -rw-r--r-- | src/ir_print.cpp | 45 |
1 files changed, 27 insertions, 18 deletions
diff --git a/src/ir_print.cpp b/src/ir_print.cpp index bc9d09b30c..c56a660e29 100644 --- a/src/ir_print.cpp +++ b/src/ir_print.cpp @@ -64,11 +64,15 @@ static void ir_print_other_block(IrPrint *irp, IrBasicBlock *bb) { } } -static void ir_print_return(IrPrint *irp, IrInstructionReturn *return_instruction) { +static void ir_print_return_begin(IrPrint *irp, IrInstructionReturnBegin *instruction) { + fprintf(irp->f, "@returnBegin("); + ir_print_other_instruction(irp, instruction->operand); + fprintf(irp->f, ")"); +} + +static void ir_print_return(IrPrint *irp, IrInstructionReturn *instruction) { fprintf(irp->f, "return "); - if (return_instruction->value != nullptr) { - ir_print_other_instruction(irp, return_instruction->value); - } + ir_print_other_instruction(irp, instruction->operand); } static void ir_print_const(IrPrint *irp, IrInstructionConst *const_instruction) { @@ -1329,14 +1333,6 @@ static void ir_print_reset_result(IrPrint *irp, IrInstructionResetResult *instru fprintf(irp->f, ")"); } -static void ir_print_result_ptr(IrPrint *irp, IrInstructionResultPtr *instruction) { - fprintf(irp->f, "ResultPtr("); - ir_print_result_loc(irp, instruction->result_loc); - fprintf(irp->f, ","); - ir_print_other_instruction(irp, instruction->result); - fprintf(irp->f, ")"); -} - static void ir_print_opaque_type(IrPrint *irp, IrInstructionOpaqueType *instruction) { fprintf(irp->f, "@OpaqueType()"); } @@ -1538,9 +1534,19 @@ static void ir_print_coro_resume(IrPrint *irp, IrInstructionCoroResume *instruct fprintf(irp->f, ")"); } -static void ir_print_await(IrPrint *irp, IrInstructionAwait *instruction) { +static void ir_print_await_src(IrPrint *irp, IrInstructionAwaitSrc *instruction) { fprintf(irp->f, "@await("); ir_print_other_instruction(irp, instruction->frame); + fprintf(irp->f, ","); + ir_print_result_loc(irp, instruction->result_loc); + fprintf(irp->f, ")"); +} + +static void ir_print_await_gen(IrPrint *irp, IrInstructionAwaitGen *instruction) { + fprintf(irp->f, "@await("); + ir_print_other_instruction(irp, instruction->frame); + fprintf(irp->f, ","); + ir_print_other_instruction(irp, instruction->result_loc); fprintf(irp->f, ")"); } @@ -1549,6 +1555,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { switch (instruction->id) { case IrInstructionIdInvalid: zig_unreachable(); + case IrInstructionIdReturnBegin: + ir_print_return_begin(irp, (IrInstructionReturnBegin *)instruction); + break; case IrInstructionIdReturn: ir_print_return(irp, (IrInstructionReturn *)instruction); break; @@ -1921,9 +1930,6 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { case IrInstructionIdResetResult: ir_print_reset_result(irp, (IrInstructionResetResult *)instruction); break; - case IrInstructionIdResultPtr: - ir_print_result_ptr(irp, (IrInstructionResultPtr *)instruction); - break; case IrInstructionIdOpaqueType: ir_print_opaque_type(irp, (IrInstructionOpaqueType *)instruction); break; @@ -2020,8 +2026,11 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { case IrInstructionIdCoroResume: ir_print_coro_resume(irp, (IrInstructionCoroResume *)instruction); break; - case IrInstructionIdAwait: - ir_print_await(irp, (IrInstructionAwait *)instruction); + case IrInstructionIdAwaitSrc: + ir_print_await_src(irp, (IrInstructionAwaitSrc *)instruction); + break; + case IrInstructionIdAwaitGen: + ir_print_await_gen(irp, (IrInstructionAwaitGen *)instruction); break; } fprintf(irp->f, "\n"); |
