| ... | ... | @@ -5983,6 +5983,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 5983 | 5983 | IrInstruction *coro_id; |
| 5984 | 5984 | IrInstruction *coro_promise_ptr; |
| 5985 | 5985 | IrInstruction *coro_result_field_ptr; |
| 5986 | IrInstruction *coro_need_dyn_alloc; |
| 5986 | 5987 | TypeTableEntry *return_type; |
| 5987 | 5988 | Buf *result_ptr_field_name; |
| 5988 | 5989 | if (is_async) { |
| ... | ... | @@ -6012,13 +6013,13 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 6012 | 6013 | get_pointer_to_type(irb->codegen, irb->codegen->builtin_types.entry_u8, false)); |
| 6013 | 6014 | IrInstruction *promise_as_u8_ptr = ir_build_ptr_cast(irb, scope, node, u8_ptr_type, coro_promise_ptr); |
| 6014 | 6015 | coro_id = ir_build_coro_id(irb, scope, node, promise_as_u8_ptr); |
| 6015 | | IrInstruction *need_dyn_alloc = ir_build_coro_alloc(irb, scope, node, coro_id); |
| 6016 | coro_need_dyn_alloc = ir_build_coro_alloc(irb, scope, node, coro_id); |
| 6016 | 6017 | IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); |
| 6017 | 6018 | IrInstruction *null_ptr = ir_build_int_to_ptr(irb, scope, node, u8_ptr_type, zero); |
| 6018 | 6019 | |
| 6019 | 6020 | IrBasicBlock *dyn_alloc_block = ir_create_basic_block(irb, scope, "DynAlloc"); |
| 6020 | 6021 | IrBasicBlock *coro_begin_block = ir_create_basic_block(irb, scope, "CoroBegin"); |
| 6021 | | ir_build_cond_br(irb, scope, node, need_dyn_alloc, dyn_alloc_block, coro_begin_block, const_bool_false); |
| 6022 | ir_build_cond_br(irb, scope, node, coro_need_dyn_alloc, dyn_alloc_block, coro_begin_block, const_bool_false); |
| 6022 | 6023 | |
| 6023 | 6024 | ir_set_cursor_at_end_and_append_block(irb, dyn_alloc_block); |
| 6024 | 6025 | IrInstruction *coro_size = ir_build_coro_size(irb, scope, node); |
| ... | ... | @@ -6047,22 +6048,34 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 6047 | 6048 | ir_build_coro_alloc_fail(irb, scope, node, err_val); |
| 6048 | 6049 | |
| 6049 | 6050 | ir_set_cursor_at_end_and_append_block(irb, alloc_ok_block); |
| 6050 | | coro_unwrapped_mem_ptr = ir_build_unwrap_err_payload(irb, scope, node, alloc_result_ptr, false); |
| 6051 | IrInstruction *unwrapped_mem_ptr = ir_build_unwrap_err_payload(irb, scope, node, alloc_result_ptr, false); |
| 6051 | 6052 | Buf *ptr_field_name = buf_create_from_str("ptr"); |
| 6052 | | IrInstruction *coro_mem_ptr_field = ir_build_field_ptr(irb, scope, node, coro_unwrapped_mem_ptr, |
| 6053 | IrInstruction *coro_mem_ptr_field = ir_build_field_ptr(irb, scope, node, unwrapped_mem_ptr, |
| 6053 | 6054 | ptr_field_name); |
| 6054 | 6055 | IrInstruction *coro_mem_ptr = ir_build_load_ptr(irb, scope, node, coro_mem_ptr_field); |
| 6055 | 6056 | ir_build_br(irb, scope, node, coro_begin_block, const_bool_false); |
| 6056 | 6057 | |
| 6057 | 6058 | ir_set_cursor_at_end_and_append_block(irb, coro_begin_block); |
| 6058 | | IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); |
| 6059 | | IrInstruction **incoming_values = allocate<IrInstruction *>(2); |
| 6060 | | incoming_blocks[0] = entry_block; |
| 6061 | | incoming_values[0] = null_ptr; |
| 6062 | | incoming_blocks[1] = alloc_ok_block; |
| 6063 | | incoming_values[1] = coro_mem_ptr; |
| 6064 | | IrInstruction *coro_mem = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); |
| 6059 | |
| 6060 | IrBasicBlock **coro_mem_incoming_blocks = allocate<IrBasicBlock *>(2); |
| 6061 | IrInstruction **coro_mem_incoming_values = allocate<IrInstruction *>(2); |
| 6062 | coro_mem_incoming_blocks[0] = entry_block; |
| 6063 | coro_mem_incoming_values[0] = null_ptr; |
| 6064 | coro_mem_incoming_blocks[1] = alloc_ok_block; |
| 6065 | coro_mem_incoming_values[1] = coro_mem_ptr; |
| 6066 | IrInstruction *coro_mem = ir_build_phi(irb, scope, node, 2, coro_mem_incoming_blocks, coro_mem_incoming_values); |
| 6067 | |
| 6068 | IrBasicBlock **unwrapped_mem_ptr_incoming_blocks = allocate<IrBasicBlock *>(2); |
| 6069 | IrInstruction **unwrapped_mem_ptr_incoming_values = allocate<IrInstruction *>(2); |
| 6070 | unwrapped_mem_ptr_incoming_blocks[0] = entry_block; |
| 6071 | unwrapped_mem_ptr_incoming_values[0] = ir_build_const_undefined(irb, scope, node); |
| 6072 | unwrapped_mem_ptr_incoming_blocks[1] = alloc_ok_block; |
| 6073 | unwrapped_mem_ptr_incoming_values[1] = unwrapped_mem_ptr; |
| 6074 | coro_unwrapped_mem_ptr = ir_build_phi(irb, scope, node, 2, |
| 6075 | unwrapped_mem_ptr_incoming_blocks, unwrapped_mem_ptr_incoming_values); |
| 6076 | |
| 6065 | 6077 | irb->exec->coro_handle = ir_build_coro_begin(irb, scope, node, coro_id, coro_mem); |
| 6078 | |
| 6066 | 6079 | irb->exec->coro_early_final = ir_create_basic_block(irb, scope, "CoroEarlyFinal"); |
| 6067 | 6080 | irb->exec->coro_normal_final = ir_create_basic_block(irb, scope, "CoroNormalFinal"); |
| 6068 | 6081 | } |
| ... | ... | @@ -6123,11 +6136,9 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 6123 | 6136 | incoming_blocks[1] = irb->exec->coro_normal_final; |
| 6124 | 6137 | incoming_values[1] = const_bool_true; |
| 6125 | 6138 | IrInstruction *resume_awaiter = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); |
| 6126 | | IrInstruction *mem_to_free = ir_build_coro_free(irb, scope, node, coro_id, irb->exec->coro_handle); |
| 6127 | | IrInstruction *is_non_null = ir_build_test_nonnull(irb, scope, node, mem_to_free); |
| 6128 | 6139 | IrBasicBlock *dyn_free_block = ir_create_basic_block(irb, scope, "DynFree"); |
| 6129 | 6140 | IrBasicBlock *end_free_block = ir_create_basic_block(irb, scope, "EndFree"); |
| 6130 | | ir_build_cond_br(irb, scope, node, is_non_null, dyn_free_block, end_free_block, const_bool_false); |
| 6141 | ir_build_cond_br(irb, scope, node, coro_need_dyn_alloc, dyn_free_block, end_free_block, const_bool_false); |
| 6131 | 6142 | |
| 6132 | 6143 | ir_set_cursor_at_end_and_append_block(irb, dyn_free_block); |
| 6133 | 6144 | Buf *free_field_name = buf_create_from_str(ASYNC_FREE_FIELD_NAME); |