diff options
Diffstat (limited to 'src/ir.cpp')
| -rw-r--r-- | src/ir.cpp | 1539 |
1 files changed, 26 insertions, 1513 deletions
diff --git a/src/ir.cpp b/src/ir.cpp index be7a8e2e51..f23fe1b7d0 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -99,7 +99,6 @@ struct ConstCastOnly { ConstCastErrUnionErrSetMismatch *error_union_error_set; ConstCastTypeMismatch *type_mismatch; ConstCastOnly *return_type; - ConstCastOnly *async_allocator_type; ConstCastOnly *null_wrap_ptr_child; ConstCastArg fn_arg; ConstCastArgNoAlias arg_no_alias; @@ -318,7 +317,6 @@ static bool types_have_same_zig_comptime_repr(ZigType *a, ZigType *b) { case ZigTypeIdUnion: case ZigTypeIdFn: case ZigTypeIdArgTuple: - case ZigTypeIdPromise: case ZigTypeIdVector: return false; } @@ -564,10 +562,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionArrayType *) { return IrInstructionIdArrayType; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionPromiseType *) { - return IrInstructionIdPromiseType; -} - static constexpr IrInstructionId ir_instruction_id(IrInstructionSliceType *) { return IrInstructionIdSliceType; } @@ -964,58 +958,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionCancel *) { return IrInstructionIdCancel; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionGetImplicitAllocator *) { - return IrInstructionIdGetImplicitAllocator; -} - -static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroId *) { - return IrInstructionIdCoroId; -} - -static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroAlloc *) { - return IrInstructionIdCoroAlloc; -} - -static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroSize *) { - return IrInstructionIdCoroSize; -} - -static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroBegin *) { - return IrInstructionIdCoroBegin; -} - -static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroAllocFail *) { - return IrInstructionIdCoroAllocFail; -} - -static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroSuspend *) { - return IrInstructionIdCoroSuspend; -} - -static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroEnd *) { - return IrInstructionIdCoroEnd; -} - -static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroFree *) { - return IrInstructionIdCoroFree; -} - -static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroResume *) { - return IrInstructionIdCoroResume; -} - -static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroSave *) { - return IrInstructionIdCoroSave; -} - -static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroPromise *) { - return IrInstructionIdCoroPromise; -} - -static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroAllocHelper *) { - return IrInstructionIdCoroAllocHelper; -} - static constexpr IrInstructionId ir_instruction_id(IrInstructionAtomicRmw *) { return IrInstructionIdAtomicRmw; } @@ -1024,14 +966,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionAtomicLoad *) { return IrInstructionIdAtomicLoad; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionPromiseResultType *) { - return IrInstructionIdPromiseResultType; -} - -static constexpr IrInstructionId ir_instruction_id(IrInstructionAwaitBookkeeping *) { - return IrInstructionIdAwaitBookkeeping; -} - static constexpr IrInstructionId ir_instruction_id(IrInstructionSaveErrRetAddr *) { return IrInstructionIdSaveErrRetAddr; } @@ -1040,10 +974,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionAddImplicitRetur return IrInstructionIdAddImplicitReturnType; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionMergeErrRetTraces *) { - return IrInstructionIdMergeErrRetTraces; -} - static constexpr IrInstructionId ir_instruction_id(IrInstructionMarkErrRetTracePtr *) { return IrInstructionIdMarkErrRetTracePtr; } @@ -1213,14 +1143,6 @@ static IrInstruction *ir_build_const_usize(IrBuilder *irb, Scope *scope, AstNode return &const_instruction->base; } -static IrInstruction *ir_build_const_u8(IrBuilder *irb, Scope *scope, AstNode *source_node, uint8_t value) { - IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); - const_instruction->base.value.type = irb->codegen->builtin_types.entry_u8; - const_instruction->base.value.special = ConstValSpecialStatic; - bigint_init_unsigned(&const_instruction->base.value.data.x_bigint, value); - return &const_instruction->base; -} - static IrInstruction *ir_create_const_type(IrBuilder *irb, Scope *scope, AstNode *source_node, ZigType *type_entry) { @@ -1428,7 +1350,7 @@ static IrInstruction *ir_build_union_field_ptr(IrBuilder *irb, Scope *scope, Ast static IrInstruction *ir_build_call_src(IrBuilder *irb, Scope *scope, AstNode *source_node, ZigFn *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args, - bool is_comptime, FnInline fn_inline, bool is_async, IrInstruction *async_allocator, + bool is_comptime, FnInline fn_inline, bool is_async, IrInstruction *new_stack, ResultLoc *result_loc) { IrInstructionCallSrc *call_instruction = ir_build_instruction<IrInstructionCallSrc>(irb, scope, source_node); @@ -1439,14 +1361,12 @@ static IrInstruction *ir_build_call_src(IrBuilder *irb, Scope *scope, AstNode *s call_instruction->args = args; call_instruction->arg_count = arg_count; call_instruction->is_async = is_async; - call_instruction->async_allocator = async_allocator; call_instruction->new_stack = new_stack; call_instruction->result_loc = result_loc; if (fn_ref != nullptr) ir_ref_instruction(fn_ref, irb->current_basic_block); for (size_t i = 0; i < arg_count; i += 1) ir_ref_instruction(args[i], irb->current_basic_block); - if (async_allocator != nullptr) ir_ref_instruction(async_allocator, irb->current_basic_block); if (new_stack != nullptr) ir_ref_instruction(new_stack, irb->current_basic_block); return &call_instruction->base; @@ -1454,7 +1374,7 @@ static IrInstruction *ir_build_call_src(IrBuilder *irb, Scope *scope, AstNode *s static IrInstruction *ir_build_call_gen(IrAnalyze *ira, IrInstruction *source_instruction, ZigFn *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args, - FnInline fn_inline, bool is_async, IrInstruction *async_allocator, IrInstruction *new_stack, + FnInline fn_inline, bool is_async, IrInstruction *new_stack, IrInstruction *result_loc, ZigType *return_type) { IrInstructionCallGen *call_instruction = ir_build_instruction<IrInstructionCallGen>(&ira->new_irb, @@ -1466,14 +1386,12 @@ static IrInstruction *ir_build_call_gen(IrAnalyze *ira, IrInstruction *source_in call_instruction->args = args; call_instruction->arg_count = arg_count; call_instruction->is_async = is_async; - call_instruction->async_allocator = async_allocator; call_instruction->new_stack = new_stack; call_instruction->result_loc = result_loc; if (fn_ref != nullptr) ir_ref_instruction(fn_ref, ira->new_irb.current_basic_block); for (size_t i = 0; i < arg_count; i += 1) ir_ref_instruction(args[i], ira->new_irb.current_basic_block); - if (async_allocator != nullptr) ir_ref_instruction(async_allocator, ira->new_irb.current_basic_block); if (new_stack != nullptr) ir_ref_instruction(new_stack, ira->new_irb.current_basic_block); if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); @@ -1753,17 +1671,6 @@ static IrInstruction *ir_build_array_type(IrBuilder *irb, Scope *scope, AstNode return &instruction->base; } -static IrInstruction *ir_build_promise_type(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *payload_type) -{ - IrInstructionPromiseType *instruction = ir_build_instruction<IrInstructionPromiseType>(irb, scope, source_node); - instruction->payload_type = payload_type; - - if (payload_type != nullptr) ir_ref_instruction(payload_type, irb->current_basic_block); - - return &instruction->base; -} - static IrInstruction *ir_build_slice_type(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *child_type, bool is_const, bool is_volatile, IrInstruction *align_value, bool is_allow_zero) { @@ -2595,13 +2502,12 @@ static IrInstruction *ir_build_unwrap_err_payload(IrBuilder *irb, Scope *scope, static IrInstruction *ir_build_fn_proto(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction **param_types, IrInstruction *align_value, IrInstruction *return_type, - IrInstruction *async_allocator_type_value, bool is_var_args) + bool is_var_args) { IrInstructionFnProto *instruction = ir_build_instruction<IrInstructionFnProto>(irb, scope, source_node); instruction->param_types = param_types; instruction->align_value = align_value; instruction->return_type = return_type; - instruction->async_allocator_type_value = async_allocator_type_value; instruction->is_var_args = is_var_args; assert(source_node->type == NodeTypeFnProto); @@ -2611,7 +2517,6 @@ static IrInstruction *ir_build_fn_proto(IrBuilder *irb, Scope *scope, AstNode *s if (param_types[i] != nullptr) ir_ref_instruction(param_types[i], irb->current_basic_block); } if (align_value != nullptr) ir_ref_instruction(align_value, irb->current_basic_block); - if (async_allocator_type_value != nullptr) ir_ref_instruction(async_allocator_type_value, irb->current_basic_block); ir_ref_instruction(return_type, irb->current_basic_block); return &instruction->base; @@ -3055,149 +2960,6 @@ static IrInstruction *ir_build_error_union(IrBuilder *irb, Scope *scope, AstNode return &instruction->base; } -static IrInstruction *ir_build_cancel(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *target) -{ - IrInstructionCancel *instruction = ir_build_instruction<IrInstructionCancel>(irb, scope, source_node); - instruction->target = target; - - ir_ref_instruction(target, irb->current_basic_block); - - return &instruction->base; -} - -static IrInstruction *ir_build_get_implicit_allocator(IrBuilder *irb, Scope *scope, AstNode *source_node, - ImplicitAllocatorId id) -{ - IrInstructionGetImplicitAllocator *instruction = ir_build_instruction<IrInstructionGetImplicitAllocator>(irb, scope, source_node); - instruction->id = id; - - return &instruction->base; -} - -static IrInstruction *ir_build_coro_id(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *promise_ptr) { - IrInstructionCoroId *instruction = ir_build_instruction<IrInstructionCoroId>(irb, scope, source_node); - instruction->promise_ptr = promise_ptr; - - ir_ref_instruction(promise_ptr, irb->current_basic_block); - - return &instruction->base; -} - -static IrInstruction *ir_build_coro_alloc(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *coro_id) { - IrInstructionCoroAlloc *instruction = ir_build_instruction<IrInstructionCoroAlloc>(irb, scope, source_node); - instruction->coro_id = coro_id; - - ir_ref_instruction(coro_id, irb->current_basic_block); - - return &instruction->base; -} - -static IrInstruction *ir_build_coro_size(IrBuilder *irb, Scope *scope, AstNode *source_node) { - IrInstructionCoroSize *instruction = ir_build_instruction<IrInstructionCoroSize>(irb, scope, source_node); - - return &instruction->base; -} - -static IrInstruction *ir_build_coro_begin(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *coro_id, IrInstruction *coro_mem_ptr) { - IrInstructionCoroBegin *instruction = ir_build_instruction<IrInstructionCoroBegin>(irb, scope, source_node); - instruction->coro_id = coro_id; - instruction->coro_mem_ptr = coro_mem_ptr; - - ir_ref_instruction(coro_id, irb->current_basic_block); - ir_ref_instruction(coro_mem_ptr, irb->current_basic_block); - - return &instruction->base; -} - -static IrInstruction *ir_build_coro_alloc_fail(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *err_val) { - IrInstructionCoroAllocFail *instruction = ir_build_instruction<IrInstructionCoroAllocFail>(irb, scope, source_node); - instruction->base.value.type = irb->codegen->builtin_types.entry_unreachable; - instruction->base.value.special = ConstValSpecialStatic; - instruction->err_val = err_val; - - ir_ref_instruction(err_val, irb->current_basic_block); - - return &instruction->base; -} - -static IrInstruction *ir_build_coro_suspend(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *save_point, IrInstruction *is_final) -{ - IrInstructionCoroSuspend *instruction = ir_build_instruction<IrInstructionCoroSuspend>(irb, scope, source_node); - instruction->save_point = save_point; - instruction->is_final = is_final; - - if (save_point != nullptr) ir_ref_instruction(save_point, irb->current_basic_block); - ir_ref_instruction(is_final, irb->current_basic_block); - - return &instruction->base; -} - -static IrInstruction *ir_build_coro_end(IrBuilder *irb, Scope *scope, AstNode *source_node) { - IrInstructionCoroEnd *instruction = ir_build_instruction<IrInstructionCoroEnd>(irb, scope, source_node); - return &instruction->base; -} - -static IrInstruction *ir_build_coro_free(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *coro_id, IrInstruction *coro_handle) -{ - IrInstructionCoroFree *instruction = ir_build_instruction<IrInstructionCoroFree>(irb, scope, source_node); - instruction->coro_id = coro_id; - instruction->coro_handle = coro_handle; - - ir_ref_instruction(coro_id, irb->current_basic_block); - ir_ref_instruction(coro_handle, irb->current_basic_block); - - return &instruction->base; -} - -static IrInstruction *ir_build_coro_resume(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *awaiter_handle) -{ - IrInstructionCoroResume *instruction = ir_build_instruction<IrInstructionCoroResume>(irb, scope, source_node); - instruction->awaiter_handle = awaiter_handle; - - ir_ref_instruction(awaiter_handle, irb->current_basic_block); - - return &instruction->base; -} - -static IrInstruction *ir_build_coro_save(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *coro_handle) -{ - IrInstructionCoroSave *instruction = ir_build_instruction<IrInstructionCoroSave>(irb, scope, source_node); - instruction->coro_handle = coro_handle; - - ir_ref_instruction(coro_handle, irb->current_basic_block); - - return &instruction->base; -} - -static IrInstruction *ir_build_coro_promise(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *coro_handle) -{ - IrInstructionCoroPromise *instruction = ir_build_instruction<IrInstructionCoroPromise>(irb, scope, source_node); - instruction->coro_handle = coro_handle; - - ir_ref_instruction(coro_handle, irb->current_basic_block); - - return &instruction->base; -} - -static IrInstruction *ir_build_coro_alloc_helper(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *realloc_fn, IrInstruction *coro_size) -{ - IrInstructionCoroAllocHelper *instruction = ir_build_instruction<IrInstructionCoroAllocHelper>(irb, scope, source_node); - instruction->realloc_fn = realloc_fn; - instruction->coro_size = coro_size; - - ir_ref_instruction(realloc_fn, irb->current_basic_block); - ir_ref_instruction(coro_size, irb->current_basic_block); - - return &instruction->base; -} - static IrInstruction *ir_build_atomic_rmw(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *operand_type, IrInstruction *ptr, IrInstruction *op, IrInstruction *operand, IrInstruction *ordering, AtomicRmwOp resolved_op, AtomicOrder resolved_ordering) @@ -3237,28 +2999,6 @@ static IrInstruction *ir_build_atomic_load(IrBuilder *irb, Scope *scope, AstNode return &instruction->base; } -static IrInstruction *ir_build_promise_result_type(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *promise_type) -{ - IrInstructionPromiseResultType *instruction = ir_build_instruction<IrInstructionPromiseResultType>(irb, scope, source_node); - instruction->promise_type = promise_type; - - ir_ref_instruction(promise_type, irb->current_basic_block); - - return &instruction->base; -} - -static IrInstruction *ir_build_await_bookkeeping(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *promise_result_type) -{ - IrInstructionAwaitBookkeeping *instruction = ir_build_instruction<IrInstructionAwaitBookkeeping>(irb, scope, source_node); - instruction->promise_result_type = promise_result_type; - - ir_ref_instruction(promise_result_type, irb->current_basic_block); - - return &instruction->base; -} - static IrInstruction *ir_build_save_err_ret_addr(IrBuilder *irb, Scope *scope, AstNode *source_node) { IrInstructionSaveErrRetAddr *instruction = ir_build_instruction<IrInstructionSaveErrRetAddr>(irb, scope, source_node); return &instruction->base; @@ -3275,21 +3015,6 @@ static IrInstruction *ir_build_add_implicit_return_type(IrBuilder *irb, Scope *s return &instruction->base; } -static IrInstruction *ir_build_merge_err_ret_traces(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *coro_promise_ptr, IrInstruction *src_err_ret_trace_ptr, IrInstruction *dest_err_ret_trace_ptr) -{ - IrInstructionMergeErrRetTraces *instruction = ir_build_instruction<IrInstructionMergeErrRetTraces>(irb, scope, source_node); - instruction->coro_promise_ptr = coro_promise_ptr; - instruction->src_err_ret_trace_ptr = src_err_ret_trace_ptr; - instruction->dest_err_ret_trace_ptr = dest_err_ret_trace_ptr; - - ir_ref_instruction(coro_promise_ptr, irb->current_basic_block); - ir_ref_instruction(src_err_ret_trace_ptr, irb->current_basic_block); - ir_ref_instruction(dest_err_ret_trace_ptr, irb->current_basic_block); - - return &instruction->base; -} - static IrInstruction *ir_build_mark_err_ret_trace_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *err_ret_trace_ptr) { IrInstructionMarkErrRetTracePtr *instruction = ir_build_instruction<IrInstructionMarkErrRetTracePtr>(irb, scope, source_node); instruction->err_ret_trace_ptr = err_ret_trace_ptr; @@ -3488,7 +3213,6 @@ static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_sco continue; case ScopeIdDeferExpr: case ScopeIdCImport: - case ScopeIdCoroPrelude: zig_unreachable(); } } @@ -3544,7 +3268,6 @@ static bool ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_scope, Scope *o continue; case ScopeIdDeferExpr: case ScopeIdCImport: - case ScopeIdCoroPrelude: zig_unreachable(); } } @@ -3563,18 +3286,6 @@ static void ir_set_cursor_at_end_and_append_block(IrBuilder *irb, IrBasicBlock * ir_set_cursor_at_end(irb, basic_block); } -static ScopeSuspend *get_scope_suspend(Scope *scope) { - while (scope) { - if (scope->id == ScopeIdSuspend) - return (ScopeSuspend *)scope; - if (scope->id == ScopeIdFnDef) - return nullptr; - - scope = scope->parent; - } - return nullptr; -} - static ScopeDeferExpr *get_scope_defer_expr(Scope *scope) { while (scope) { if (scope->id == ScopeIdDeferExpr) @@ -3604,47 +3315,7 @@ static IrInstruction *ir_gen_async_return(IrBuilder *irb, Scope *scope, AstNode return return_inst; } - IrBasicBlock *suspended_block = ir_create_basic_block(irb, scope, "Suspended"); - IrBasicBlock *not_suspended_block = ir_create_basic_block(irb, scope, "NotSuspended"); - IrBasicBlock *store_awaiter_block = ir_create_basic_block(irb, scope, "StoreAwaiter"); - IrBasicBlock *check_canceled_block = ir_create_basic_block(irb, scope, "CheckCanceled"); - - IrInstruction *inverted_ptr_mask = ir_build_const_usize(irb, scope, node, 0x7); // 0b111 - IrInstruction *ptr_mask = ir_build_un_op(irb, scope, node, IrUnOpBinNot, inverted_ptr_mask); // 0b111...000 - IrInstruction *is_canceled_mask = ir_build_const_usize(irb, scope, node, 0x1); // 0b001 - IrInstruction *is_suspended_mask = ir_build_const_usize(irb, scope, node, 0x2); // 0b010 - IrInstruction *promise_type_val = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_promise); - IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, false); - IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); - - ir_build_store_ptr(irb, scope, node, irb->exec->coro_result_field_ptr, return_value); - IrInstruction *usize_type_val = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_usize); - IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node, - usize_type_val, irb->exec->atomic_state_field_ptr, nullptr, ptr_mask, nullptr, - AtomicRmwOp_or, AtomicOrderSeqCst); - - IrInstruction *is_suspended_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, is_suspended_mask, false); - IrInstruction *is_suspended_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_suspended_value, zero, false); - ir_build_cond_br(irb, scope, node, is_suspended_bool, suspended_block, not_suspended_block, is_comptime); - - ir_set_cursor_at_end_and_append_block(irb, suspended_block); - ir_build_unreachable(irb, scope, node); - - ir_set_cursor_at_end_and_append_block(irb, not_suspended_block); - IrInstruction *await_handle_addr = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, ptr_mask, false); - // if we ever add null checking safety to the ptrtoint instruction, it needs to be disabled here - IrInstruction *have_await_handle = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, await_handle_addr, zero, false); - ir_build_cond_br(irb, scope, node, have_await_handle, store_awaiter_block, check_canceled_block, is_comptime); - - ir_set_cursor_at_end_and_append_block(irb, store_awaiter_block); - IrInstruction *await_handle = ir_build_int_to_ptr(irb, scope, node, promise_type_val, await_handle_addr); - ir_build_store_ptr(irb, scope, node, irb->exec->await_handle_var_ptr, await_handle); - ir_build_br(irb, scope, node, irb->exec->coro_normal_final, is_comptime); - - ir_set_cursor_at_end_and_append_block(irb, check_canceled_block); - IrInstruction *is_canceled_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, is_canceled_mask, false); - IrInstruction *is_canceled_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_canceled_value, zero, false); - return ir_build_cond_br(irb, scope, node, is_canceled_bool, irb->exec->coro_final_cleanup_block, irb->exec->coro_early_final, is_comptime); + zig_panic("TODO async return"); } static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { @@ -5386,7 +5057,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo FnInline fn_inline = (builtin_fn->id == BuiltinFnIdInlineCall) ? FnInlineAlways : FnInlineNever; IrInstruction *call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, false, - fn_inline, false, nullptr, nullptr, result_loc); + fn_inline, false, nullptr, result_loc); return ir_lval_wrap(irb, scope, call, lval, result_loc); } case BuiltinFnIdNewStackCall: @@ -5417,7 +5088,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo } IrInstruction *call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, false, - FnInlineAuto, false, nullptr, new_stack, result_loc); + FnInlineAuto, false, new_stack, result_loc); return ir_lval_wrap(irb, scope, call, lval, result_loc); } case BuiltinFnIdTypeId: @@ -5722,17 +5393,12 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node } bool is_async = node->data.fn_call_expr.is_async; - IrInstruction *async_allocator = nullptr; if (is_async) { - if (node->data.fn_call_expr.async_allocator) { - async_allocator = ir_gen_node(irb, node->data.fn_call_expr.async_allocator, scope); - if (async_allocator == irb->codegen->invalid_instruction) - return async_allocator; - } + zig_panic("TODO async fn call"); } IrInstruction *fn_call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, false, FnInlineAuto, - is_async, async_allocator, nullptr, result_loc); + is_async, nullptr, result_loc); return ir_lval_wrap(irb, scope, fn_call, lval, result_loc); } @@ -6751,22 +6417,6 @@ static IrInstruction *ir_gen_array_type(IrBuilder *irb, Scope *scope, AstNode *n } } -static IrInstruction *ir_gen_promise_type(IrBuilder *irb, Scope *scope, AstNode *node) { - assert(node->type == NodeTypePromiseType); - - AstNode *payload_type_node = node->data.promise_type.payload_type; - IrInstruction *payload_type_value = nullptr; - - if (payload_type_node != nullptr) { - payload_type_value = ir_gen_node(irb, payload_type_node, scope); - if (payload_type_value == irb->codegen->invalid_instruction) - return payload_type_value; - - } - - return ir_build_promise_type(irb, scope, node, payload_type_value); -} - static IrInstruction *ir_gen_undefined_literal(IrBuilder *irb, Scope *scope, AstNode *node) { assert(node->type == NodeTypeUndefinedLiteral); return ir_build_const_undefined(irb, scope, node); @@ -7969,87 +7619,7 @@ static IrInstruction *ir_gen_fn_proto(IrBuilder *irb, Scope *parent_scope, AstNo //return_type = nullptr; } - IrInstruction *async_allocator_type_value = nullptr; - if (node->data.fn_proto.async_allocator_type != nullptr) { - async_allocator_type_value = ir_gen_node(irb, node->data.fn_proto.async_allocator_type, parent_scope); - if (async_allocator_type_value == irb->codegen->invalid_instruction) - return irb->codegen->invalid_instruction; - } - - return ir_build_fn_proto(irb, parent_scope, node, param_types, align_value, return_type, - async_allocator_type_value, is_var_args); -} - -static IrInstruction *ir_gen_cancel_target(IrBuilder *irb, Scope *scope, AstNode *node, - IrInstruction *target_inst, bool cancel_non_suspended, bool cancel_awaited) -{ - IrBasicBlock *done_block = ir_create_basic_block(irb, scope, "CancelDone"); - IrBasicBlock *not_canceled_block = ir_create_basic_block(irb, scope, "NotCanceled"); - IrBasicBlock *pre_return_block = ir_create_basic_block(irb, scope, "PreReturn"); - IrBasicBlock *post_return_block = ir_create_basic_block(irb, scope, "PostReturn"); - IrBasicBlock *do_cancel_block = ir_create_basic_block(irb, scope, "DoCancel"); - - IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); - IrInstruction *usize_type_val = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_usize); - IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, false); - IrInstruction *is_canceled_mask = ir_build_const_usize(irb, scope, node, 0x1); // 0b001 - IrInstruction *promise_T_type_val = ir_build_const_type(irb, scope, node, - get_promise_type(irb->codegen, irb->codegen->builtin_types.entry_void)); - IrInstruction *inverted_ptr_mask = ir_build_const_usize(irb, scope, node, 0x7); // 0b111 - IrInstruction *ptr_mask = ir_build_un_op(irb, scope, node, IrUnOpBinNot, inverted_ptr_mask); // 0b111...000 - IrInstruction *await_mask = ir_build_const_usize(irb, scope, node, 0x4); // 0b100 - IrInstruction *is_suspended_mask = ir_build_const_usize(irb, scope, node, 0x2); // 0b010 - - // TODO relies on Zig not re-ordering fields - IrInstruction *casted_target_inst = ir_build_ptr_cast_src(irb, scope, node, promise_T_type_val, target_inst, - false); - IrInstruction *coro_promise_ptr = ir_build_coro_promise(irb, scope, node, casted_target_inst); - Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME); - IrInstruction *atomic_state_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, - atomic_state_field_name, false); - - // set the is_canceled bit - IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node, - usize_type_val, atomic_state_ptr, nullptr, is_canceled_mask, nullptr, - AtomicRmwOp_or, AtomicOrderSeqCst); - - IrInstruction *is_canceled_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, is_canceled_mask, false); - IrInstruction *is_canceled_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_canceled_value, zero, false); - ir_build_cond_br(irb, scope, node, is_canceled_bool, done_block, not_canceled_block, is_comptime); - - ir_set_cursor_at_end_and_append_block(irb, not_canceled_block); - IrInstruction *awaiter_addr = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, ptr_mask, false); - IrInstruction *is_returned_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpEq, awaiter_addr, ptr_mask, false); - ir_build_cond_br(irb, scope, node, is_returned_bool, post_return_block, pre_return_block, is_comptime); - - ir_set_cursor_at_end_and_append_block(irb, post_return_block); - if (cancel_awaited) { - ir_build_br(irb, scope, node, do_cancel_block, is_comptime); - } else { - IrInstruction *is_awaited_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, await_mask, false); - IrInstruction *is_awaited_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_awaited_value, zero, false); - ir_build_cond_br(irb, scope, node, is_awaited_bool, done_block, do_cancel_block, is_comptime); - } - - ir_set_cursor_at_end_and_append_block(irb, pre_return_block); - if (cancel_awaited) { - if (cancel_non_suspended) { - ir_build_br(irb, scope, node, do_cancel_block, is_comptime); - } else { - IrInstruction *is_suspended_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, is_suspended_mask, false); - IrInstruction *is_suspended_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_suspended_value, zero, false); - ir_build_cond_br(irb, scope, node, is_suspended_bool, do_cancel_block, done_block, is_comptime); - } - } else { - ir_build_br(irb, scope, node, done_block, is_comptime); - } - - ir_set_cursor_at_end_and_append_block(irb, do_cancel_block); - ir_build_cancel(irb, scope, node, target_inst); - ir_build_br(irb, scope, node, done_block, is_comptime); - - ir_set_cursor_at_end_and_append_block(irb, done_block); - return ir_build_const_void(irb, scope, node); + return ir_build_fn_proto(irb, parent_scope, node, param_types, align_value, return_type, is_var_args); } static IrInstruction *ir_gen_cancel(IrBuilder *irb, Scope *scope, AstNode *node) { @@ -8059,57 +7629,7 @@ static IrInstruction *ir_gen_cancel(IrBuilder *irb, Scope *scope, AstNode *node) if (target_inst == irb->codegen->invalid_instruction) return irb->codegen->invalid_instruction; - return ir_gen_cancel_target(irb, scope, node, target_inst, false, true); -} - -static IrInstruction *ir_gen_resume_target(IrBuilder *irb, Scope *scope, AstNode *node, - IrInstruction *target_inst) -{ - IrBasicBlock *done_block = ir_create_basic_block(irb, scope, "ResumeDone"); - IrBasicBlock *not_canceled_block = ir_create_basic_block(irb, scope, "NotCanceled"); - IrBasicBlock *suspended_block = ir_create_basic_block(irb, scope, "IsSuspended"); - IrBasicBlock *not_suspended_block = ir_create_basic_block(irb, scope, "IsNotSuspended"); - - IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); - IrInstruction *is_canceled_mask = ir_build_const_usize(irb, scope, node, 0x1); // 0b001 - IrInstruction *is_suspended_mask = ir_build_const_usize(irb, scope, node, 0x2); // 0b010 - IrInstruction *and_mask = ir_build_un_op(irb, scope, node, IrUnOpBinNot, is_suspended_mask); - IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, false); - IrInstruction *usize_type_val = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_usize); - IrInstruction *promise_T_type_val = ir_build_const_type(irb, scope, node, - get_promise_type(irb->codegen, irb->codegen->builtin_types.entry_void)); - - // TODO relies on Zig not re-ordering fields - IrInstruction *casted_target_inst = ir_build_ptr_cast_src(irb, scope, node, promise_T_type_val, target_inst, - false); - IrInstruction *coro_promise_ptr = ir_build_coro_promise(irb, scope, node, casted_target_inst); - Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME); - IrInstruction *atomic_state_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, - atomic_state_field_name, false); - - // clear the is_suspended bit - IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node, - usize_type_val, atomic_state_ptr, nullptr, and_mask, nullptr, - AtomicRmwOp_and, AtomicOrderSeqCst); - - IrInstruction *is_canceled_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, is_canceled_mask, false); - IrInstruction *is_canceled_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_canceled_value, zero, false); - ir_build_cond_br(irb, scope, node, is_canceled_bool, done_block, not_canceled_block, is_comptime); - - ir_set_cursor_at_end_and_append_block(irb, not_canceled_block); - IrInstruction *is_suspended_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, is_suspended_mask, false); - IrInstruction *is_suspended_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_suspended_value, zero, false); - ir_build_cond_br(irb, scope, node, is_suspended_bool, suspended_block, not_suspended_block, is_comptime); - - ir_set_cursor_at_end_and_append_block(irb, not_suspended_block); - ir_build_unreachable(irb, scope, node); - - ir_set_cursor_at_end_and_append_block(irb, suspended_block); - ir_build_coro_resume(irb, scope, node, target_inst); - ir_build_br(irb, scope, node, done_block, is_comptime); - - ir_set_cursor_at_end_and_append_block(irb, done_block); - return ir_build_const_void(irb, scope, node); + zig_panic("TODO ir_gen_cancel"); } static IrInstruction *ir_gen_resume(IrBuilder *irb, Scope *scope, AstNode *node) { @@ -8119,7 +7639,7 @@ static IrInstruction *ir_gen_resume(IrBuilder *irb, Scope *scope, AstNode *node) if (target_inst == irb->codegen->invalid_instruction) return irb->codegen->invalid_instruction; - return ir_gen_resume_target(irb, scope, node, target_inst); + zig_panic("TODO ir_gen_resume"); } static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *node) { @@ -8129,298 +7649,13 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n if (target_inst == irb->codegen->invalid_instruction) return irb->codegen->invalid_instruction; - ZigFn *fn_entry = exec_fn_entry(irb->exec); - if (!fn_entry) { - add_node_error(irb->codegen, node, buf_sprintf("await outside function definition")); - return irb->codegen->invalid_instruction; - } - if (fn_entry->type_entry->data.fn.fn_type_id.cc != CallingConventionAsync) { - add_node_error(irb->codegen, node, buf_sprintf("await in non-async function")); - return irb->codegen->invalid_instruction; - } - - ScopeDeferExpr *scope_defer_expr = get_scope_defer_expr(scope); - if (scope_defer_expr) { - if (!scope_defer_expr->reported_err) { - add_node_error(irb->codegen, node, buf_sprintf("cannot await inside defer expression")); - scope_defer_expr->reported_err = true; - } - return irb->codegen->invalid_instruction; - } - - Scope *outer_scope = irb->exec->begin_scope; - - IrInstruction *coro_promise_ptr = ir_build_coro_promise(irb, scope, node, target_inst); - Buf *result_ptr_field_name = buf_create_from_str(RESULT_PTR_FIELD_NAME); - IrInstruction *result_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_ptr_field_name, false); - - if (irb->codegen->have_err_ret_tracing) { - IrInstruction *err_ret_trace_ptr = ir_build_error_return_trace(irb, scope, node, IrInstructionErrorReturnTrace::NonNull); - Buf *err_ret_trace_ptr_field_name = buf_create_from_str(ERR_RET_TRACE_PTR_FIELD_NAME); - IrInstruction *err_ret_trace_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_ptr_field_name, false); - ir_build_store_ptr(irb, scope, node, err_ret_trace_ptr_field_ptr, err_ret_trace_ptr); - } - - IrBasicBlock *already_awaited_block = ir_create_basic_block(irb, scope, "AlreadyAwaited"); - IrBasicBlock *not_awaited_block = ir_create_basic_block(irb, scope, "NotAwaited"); - IrBasicBlock *not_canceled_block = ir_create_basic_block(irb, scope, "NotCanceled"); - IrBasicBlock *yes_suspend_block = ir_create_basic_block(irb, scope, "YesSuspend"); - IrBasicBlock *no_suspend_block = ir_create_basic_block(irb, scope, "NoSuspend"); - IrBasicBlock *merge_block = ir_create_basic_block(irb, scope, "MergeSuspend"); - IrBasicBlock *cleanup_block = ir_create_basic_block(irb, scope, "SuspendCleanup"); - IrBasicBlock *resume_block = ir_create_basic_block(irb, scope, "SuspendResume"); - IrBasicBlock *cancel_target_block = ir_create_basic_block(irb, scope, "CancelTarget"); - IrBasicBlock *do_cancel_block = ir_create_basic_block(irb, scope, "DoCancel"); - IrBasicBlock *do_defers_block = ir_create_basic_block(irb, scope, "DoDefers"); - IrBasicBlock *destroy_block = ir_create_basic_block(irb, scope, "DestroyBlock"); - IrBasicBlock *my_suspended_block = ir_create_basic_block(irb, scope, "AlreadySuspended"); - IrBasicBlock *my_not_suspended_block = ir_create_basic_block(irb, scope, "NotAlreadySuspended"); - IrBasicBlock *do_suspend_block = ir_create_basic_block(irb, scope, "DoSuspend"); - - Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME); - IrInstruction *atomic_state_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, - atomic_state_field_name, false); - - IrInstruction *promise_type_val = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_promise); - IrInstruction *const_bool_false = ir_build_const_bool(irb, scope, node, false); - IrInstruction *undef = ir_build_const_undefined(irb, scope, node); - IrInstruction *usize_type_val = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_usize); - IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); - IrInstruction *inverted_ptr_mask = ir_build_const_usize(irb, scope, node, 0x7); // 0b111 - IrInstruction *ptr_mask = ir_build_un_op(irb, scope, node, IrUnOpBinNot, inverted_ptr_mask); // 0b111...000 - IrInstruction *await_mask = ir_build_const_usize(irb, scope, node, 0x4); // 0b100 - IrInstruction *is_canceled_mask = ir_build_const_usize(irb, scope, node, 0x1); // 0b001 - IrInstruction *is_suspended_mask = ir_build_const_usize(irb, scope, node, 0x2); // 0b010 - - ZigVar *result_var = ir_create_var(irb, node, scope, nullptr, - false, false, true, const_bool_false); - IrInstruction *target_promise_type = ir_build_typeof(irb, scope, node, target_inst); - IrInstruction *promise_result_type = ir_build_promise_result_type(irb, scope, node, target_promise_type); - ir_build_await_bookkeeping(irb, scope, node, promise_result_type); - IrInstruction *undef_promise_result = ir_build_implicit_cast(irb, scope, node, promise_result_type, undef, nullptr); - build_decl_var_and_init(irb, scope, node, result_var, undef_promise_result, "result", const_bool_false); - IrInstruction *my_result_var_ptr = ir_build_var_ptr(irb, scope, node, result_var); - ir_build_store_ptr(irb, scope, node, result_ptr_field_ptr, my_result_var_ptr); - IrInstruction *save_token = ir_build_coro_save(irb, scope, node, irb->exec->coro_handle); - - IrInstruction *coro_handle_addr = ir_build_ptr_to_int(irb, scope, node, irb->exec->coro_handle); - IrInstruction *mask_bits = ir_build_bin_op(irb, scope, node, IrBinOpBinOr, coro_handle_addr, await_mask, false); - IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node, - usize_type_val, atomic_state_ptr, nullptr, mask_bits, nullptr, - AtomicRmwOp_or, AtomicOrderSeqCst); - - IrInstruction *is_awaited_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, await_mask, false); - IrInstruction *is_awaited_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_awaited_value, zero, false); - ir_build_cond_br(irb, scope, node, is_awaited_bool, already_awaited_block, not_awaited_block, const_bool_false); - - ir_set_cursor_at_end_and_append_block(irb, already_awaited_block); - ir_build_unreachable(irb, scope, node); - - ir_set_cursor_at_end_and_append_block(irb, not_awaited_block); - IrInstruction *await_handle_addr = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, ptr_mask, false); - IrInstruction *is_non_null = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, await_handle_addr, zero, false); - IrInstruction *is_canceled_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, is_canceled_mask, false); - IrInstruction *is_canceled_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_canceled_value, zero, false); - ir_build_cond_br(irb, scope, node, is_canceled_bool, cancel_target_block, not_canceled_block, const_bool_false); - - ir_set_cursor_at_end_and_append_block(irb, not_canceled_block); - ir_build_cond_br(irb, scope, node, is_non_null, no_suspend_block, yes_suspend_block, const_bool_false); - - ir_set_cursor_at_end_and_append_block(irb, cancel_target_block); - ir_build_cancel(irb, scope, node, target_inst); - ir_mark_gen(ir_build_br(irb, scope, node, cleanup_block, const_bool_false)); - - ir_set_cursor_at_end_and_append_block(irb, no_suspend_block); - if (irb->codegen->have_err_ret_tracing) { - Buf *err_ret_trace_field_name = buf_create_from_str(ERR_RET_TRACE_FIELD_NAME); - IrInstruction *src_err_ret_trace_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_field_name, false); - IrInstruction *dest_err_ret_trace_ptr = ir_build_error_return_trace(irb, scope, node, IrInstructionErrorReturnTrace::NonNull); - ir_build_merge_err_ret_traces(irb, scope, node, coro_promise_ptr, src_err_ret_trace_ptr, dest_err_ret_trace_ptr); - } - Buf *result_field_name = buf_create_from_str(RESULT_FIELD_NAME); - IrInstruction *promise_result_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_field_name, false); - // If the type of the result handle_is_ptr then this does not actually perform a load. But we need it to, - // because we're about to destroy the memory. So we store it into our result variable. - IrInstruction *no_suspend_result = ir_build_load_ptr(irb, scope, node, promise_result_ptr); - ir_build_store_ptr(irb, scope, node, my_result_var_ptr, no_suspend_result); - ir_build_cancel(irb, scope, node, target_inst); - ir_build_br(irb, scope, node, merge_block, const_bool_false); - - - ir_set_cursor_at_end_and_append_block(irb, yes_suspend_block); - IrInstruction *my_prev_atomic_value = ir_build_atomic_rmw(irb, scope, node, - usize_type_val, irb->exec->atomic_state_field_ptr, nullptr, is_suspended_mask, nullptr, - AtomicRmwOp_or, AtomicOrderSeqCst); - IrInstruction *my_is_suspended_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, my_prev_atomic_value, is_suspended_mask, false); - IrInstruction *my_is_suspended_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, my_is_suspended_value, zero, false); - ir_build_cond_br(irb, scope, node, my_is_suspended_bool, my_suspended_block, my_not_suspended_block, const_bool_false); - - ir_set_cursor_at_end_and_append_block(irb, my_suspended_block); - ir_build_unreachable(irb, scope, node); - - ir_set_cursor_at_end_and_append_block(irb, my_not_suspended_block); - IrInstruction *my_is_canceled_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, my_prev_atomic_value, is_canceled_mask, false); - IrInstruction *my_is_canceled_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, my_is_canceled_value, zero, false); - ir_build_cond_br(irb, scope, node, my_is_canceled_bool, cleanup_block, do_suspend_block, const_bool_false); - - ir_set_cursor_at_end_and_append_block(irb, do_suspend_block); - IrInstruction *suspend_code = ir_build_coro_suspend(irb, scope, node, save_token, const_bool_false); - - IrInstructionSwitchBrCase *cases = allocate<IrInstructionSwitchBrCase>(2); - cases[0].value = ir_build_const_u8(irb, scope, node, 0); - cases[0].block = resume_block; - cases[1].value = ir_build_const_u8(irb, scope, node, 1); - cases[1].block = destroy_block; - ir_build_switch_br(irb, scope, node, suspend_code, irb->exec->coro_suspend_block, - 2, cases, const_bool_false, nullptr); - - ir_set_cursor_at_end_and_append_block(irb, destroy_block); - ir_gen_cancel_target(irb, scope, node, target_inst, false, true); - ir_mark_gen(ir_build_br(irb, scope, node, cleanup_block, const_bool_false)); - - ir_set_cursor_at_end_and_append_block(irb, cleanup_block); - IrInstruction *my_mask_bits = ir_build_bin_op(irb, scope, node, IrBinOpBinOr, ptr_mask, is_canceled_mask, false); - IrInstruction *b_my_prev_atomic_value = ir_build_atomic_rmw(irb, scope, node, - usize_type_val, irb->exec->atomic_state_field_ptr, nullptr, my_mask_bits, nullptr, - AtomicRmwOp_or, AtomicOrderSeqCst); - IrInstruction *my_await_handle_addr = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, b_my_prev_atomic_value, ptr_mask, false); - IrInstruction *dont_have_my_await_handle = ir_build_bin_op(irb, scope, node, IrBinOpCmpEq, my_await_handle_addr, zero, false); - IrInstruction *dont_destroy_ourselves = ir_build_bin_op(irb, scope, node, IrBinOpBoolAnd, dont_have_my_await_handle, is_canceled_bool, false); - ir_build_cond_br(irb, scope, node, dont_have_my_await_handle, do_defers_block, do_cancel_block, const_bool_false); - - ir_set_cursor_at_end_and_append_block(irb, do_cancel_block); - IrInstruction *my_await_handle = ir_build_int_to_ptr(irb, scope, node, promise_type_val, my_await_handle_addr); - ir_gen_cancel_target(irb, scope, node, my_await_handle, true, false); - ir_mark_gen(ir_build_br(irb, scope, node, do_defers_block, const_bool_false)); - - ir_set_cursor_at_end_and_append_block(irb, do_defers_block); - ir_gen_defers_for_block(irb, scope, outer_scope, true); - ir_mark_gen(ir_build_cond_br(irb, scope, node, dont_destroy_ourselves, irb->exec->coro_early_final, irb->exec->coro_final_cleanup_block, const_bool_false)); - - ir_set_cursor_at_end_and_append_block(irb, resume_block); - ir_build_br(irb, scope, node, merge_block, const_bool_false); - - ir_set_cursor_at_end_and_append_block(irb, merge_block); - return ir_build_load_ptr(irb, scope, node, my_result_var_ptr); + zig_panic("TODO ir_gen_await_expr"); } static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNode *node) { assert(node->type == NodeTypeSuspend); - ZigFn *fn_entry = exec_fn_entry(irb->exec); - if (!fn_entry) { - add_node_error(irb->codegen, node, buf_sprintf("suspend outside function definition")); - return irb->codegen->invalid_instruction; - } - if (fn_entry->type_entry->data.fn.fn_type_id.cc != CallingConventionAsync) { - add_node_error(irb->codegen, node, buf_sprintf("suspend in non-async function")); - return irb->codegen->invalid_instruction; - } - - ScopeDeferExpr *scope_defer_expr = get_scope_defer_expr(parent_scope); - if (scope_defer_expr) { - if (!scope_defer_expr->reported_err) { - ErrorMsg *msg = add_node_error(irb->codegen, node, buf_sprintf("cannot suspend inside defer expression")); - add_error_note(irb->codegen, msg, scope_defer_expr->base.source_node, buf_sprintf("defer here")); - scope_defer_expr->reported_err = true; - } - return irb->codegen->invalid_instruction; - } - ScopeSuspend *existing_suspend_scope = get_scope_suspend(parent_scope); - if (existing_suspend_scope) { - if (!existing_suspend_scope->reported_err) { - ErrorMsg *msg = add_node_error(irb->codegen, node, buf_sprintf("cannot suspend inside suspend block")); - add_error_note(irb->codegen, msg, existing_suspend_scope->base.source_node, buf_sprintf("other suspend block here")); - existing_suspend_scope->reported_err = true; - } - return irb->codegen->invalid_instruction; - } - - Scope *outer_scope = irb->exec->begin_scope; - - IrBasicBlock *cleanup_block = ir_create_basic_block(irb, parent_scope, "SuspendCleanup"); - IrBasicBlock *resume_block = ir_create_basic_block(irb, parent_scope, "SuspendResume"); - IrBasicBlock *suspended_block = ir_create_basic_block(irb, parent_scope, "AlreadySuspended"); - IrBasicBlock *canceled_block = ir_create_basic_block(irb, parent_scope, "IsCanceled"); - IrBasicBlock *not_canceled_block = ir_create_basic_block(irb, parent_scope, "NotCanceled"); - IrBasicBlock *not_suspended_block = ir_create_basic_block(irb, parent_scope, "NotAlreadySuspended"); - IrBasicBlock *cancel_awaiter_block = ir_create_basic_block(irb, parent_scope, "CancelAwaiter"); - - IrInstruction *promise_type_val = ir_build_const_type(irb, parent_scope, node, irb->codegen->builtin_types.entry_promise); - IrInstruction *const_bool_true = ir_build_const_bool(irb, parent_scope, node, true); - IrInstruction *const_bool_false = ir_build_const_bool(irb, parent_scope, node, false); - IrInstruction *usize_type_val = ir_build_const_type(irb, parent_scope, node, irb->codegen->builtin_types.entry_usize); - IrInstruction *is_canceled_mask = ir_build_const_usize(irb, parent_scope, node, 0x1); // 0b001 - IrInstruction *is_suspended_mask = ir_build_const_usize(irb, parent_scope, node, 0x2); // 0b010 - IrInstruction *zero = ir_build_const_usize(irb, parent_scope, node, 0); - IrInstruction *inverted_ptr_mask = ir_build_const_usize(irb, parent_scope, node, 0x7); // 0b111 - IrInstruction *ptr_mask = ir_build_un_op(irb, parent_scope, node, IrUnOpBinNot, inverted_ptr_mask); // 0b111...000 - - IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, parent_scope, node, - usize_type_val, irb->exec->atomic_state_field_ptr, nullptr, is_suspended_mask, nullptr, - AtomicRmwOp_or, AtomicOrderSeqCst); - - IrInstruction *is_canceled_value = ir_build_bin_op(irb, parent_scope, node, IrBinOpBinAnd, prev_atomic_value, is_canceled_mask, false); - IrInstruction *is_canceled_bool = ir_build_bin_op(irb, parent_scope, node, IrBinOpCmpNotEq, is_canceled_value, zero, false); - ir_build_cond_br(irb, parent_scope, node, is_canceled_bool, canceled_block, not_canceled_block, const_bool_false); - - ir_set_cursor_at_end_and_append_block(irb, canceled_block); - IrInstruction *await_handle_addr = ir_build_bin_op(irb, parent_scope, node, IrBinOpBinAnd, prev_atomic_value, ptr_mask, false); - IrInstruction *have_await_handle = ir_build_bin_op(irb, parent_scope, node, IrBinOpCmpNotEq, await_handle_addr, zero, false); - IrBasicBlock *post_canceled_block = irb->current_basic_block; - ir_build_cond_br(irb, parent_scope, node, have_await_handle, cancel_awaiter_block, cleanup_block, const_bool_false); - - ir_set_cursor_at_end_and_append_block(irb, cancel_awaiter_block); - IrInstruction *await_handle = ir_build_int_to_ptr(irb, parent_scope, node, promise_type_val, await_handle_addr); - ir_gen_cancel_target(irb, parent_scope, node, await_handle, true, false); - IrBasicBlock *post_cancel_awaiter_block = irb->current_basic_block; - ir_build_br(irb, parent_scope, node, cleanup_block, const_bool_false); - - ir_set_cursor_at_end_and_append_block(irb, not_canceled_block); - IrInstruction *is_suspended_value = ir_build_bin_op(irb, parent_scope, node, IrBinOpBinAnd, prev_atomic_value, is_suspended_mask, false); - IrInstruction *is_suspended_bool = ir_build_bin_op(irb, parent_scope, node, IrBinOpCmpNotEq, is_suspended_value, zero, false); - ir_build_cond_br(irb, parent_scope, node, is_suspended_bool, suspended_block, not_suspended_block, const_bool_false); - - ir_set_cursor_at_end_and_append_block(irb, suspended_block); - ir_build_unreachable(irb, parent_scope, node); - - ir_set_cursor_at_end_and_append_block(irb, not_suspended_block); - IrInstruction *suspend_code; - if (node->data.suspend.block == nullptr) { - suspend_code = ir_build_coro_suspend(irb, parent_scope, node, nullptr, const_bool_false); - } else { - Scope *child_scope; - ScopeSuspend *suspend_scope = create_suspend_scope(irb->codegen, node, parent_scope); - suspend_scope->resume_block = resume_block; - child_scope = &suspend_scope->base; - IrInstruction *save_token = ir_build_coro_save(irb, child_scope, node, irb->exec->coro_handle); - ir_gen_node(irb, node->data.suspend.block, child_scope); - suspend_code = ir_mark_gen(ir_build_coro_suspend(irb, parent_scope, node, save_token, const_bool_false)); - } - - IrInstructionSwitchBrCase *cases = allocate<IrInstructionSwitchBrCase>(2); - cases[0].value = ir_mark_gen(ir_build_const_u8(irb, parent_scope, node, 0)); - cases[0].block = resume_block; - cases[1].value = ir_mark_gen(ir_build_const_u8(irb, parent_scope, node, 1)); - cases[1].block = canceled_block; - IrInstructionSwitchBr *switch_br = ir_build_switch_br(irb, parent_scope, node, suspend_code, - irb->exec->coro_suspend_block, 2, cases, const_bool_false, nullptr); - ir_mark_gen(&switch_br->base); - - ir_set_cursor_at_end_and_append_block(irb, cleanup_block); - IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); - IrInstruction **incoming_values = allocate<IrInstruction *>(2); - incoming_blocks[0] = post_canceled_block; - incoming_values[0] = const_bool_true; - incoming_blocks[1] = post_cancel_awaiter_block; - incoming_values[1] = const_bool_false; - IrInstruction *destroy_ourselves = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values, - nullptr); - ir_gen_defers_for_block(irb, parent_scope, outer_scope, true); - ir_mark_gen(ir_build_cond_br(irb, parent_scope, node, destroy_ourselves, irb->exec->coro_final_cleanup_block, irb->exec->coro_early_final, const_bool_false)); - - ir_set_cursor_at_end_and_append_block(irb, resume_block); - return ir_mark_gen(ir_build_const_void(irb, parent_scope, node)); + zig_panic("TODO ir_gen_suspend"); } static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scope, @@ -8512,8 +7747,6 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop return ir_lval_wrap(irb, scope, ir_gen_array_type(irb, scope, node), lval, result_loc); case NodeTypePointerType: return ir_lval_wrap(irb, scope, ir_gen_pointer_type(irb, scope, node), lval, result_loc); - case NodeTypePromiseType: - return ir_lval_wrap(irb, scope, ir_gen_promise_type(irb, scope, node), lval, result_loc); case NodeTypeStringLiteral: return ir_lval_wrap(irb, scope, ir_gen_string_literal(irb, scope, node), lval, result_loc); case NodeTypeUndefinedLiteral: @@ -8624,105 +7857,8 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec ZigFn *fn_entry = exec_fn_entry(irb->exec); bool is_async = fn_entry != nullptr && fn_entry->type_entry->data.fn.fn_type_id.cc == CallingConventionAsync; - IrInstruction *coro_id; - IrInstruction *u8_ptr_type; - IrInstruction *const_bool_false; - IrInstruction *coro_promise_ptr; - IrInstruction *err_ret_trace_ptr; - ZigType *return_type; - Buf *result_ptr_field_name; - ZigVar *coro_size_var; if (is_async) { - // create the coro promise - Scope *coro_scope = create_coro_prelude_scope(irb->codegen, node, scope); - const_bool_false = ir_build_const_bool(irb, coro_scope, node, false); - ZigVar *promise_var = ir_create_var(irb, node, coro_scope, nullptr, false, false, true, const_bool_false); - - return_type = fn_entry->type_entry->data.fn.fn_type_id.return_type; - IrInstruction *undef = ir_build_const_undefined(irb, coro_scope, node); - // TODO mark this var decl as "no safety" e.g. disable initializing the undef value to 0xaa - ZigType *coro_frame_type = get_promise_frame_type(irb->codegen, return_type); - IrInstruction *coro_frame_type_value = ir_build_const_type(irb, coro_scope, node, coro_frame_type); - IrInstruction *undef_coro_frame = ir_build_implicit_cast(irb, coro_scope, node, coro_frame_type_value, undef, nullptr); - build_decl_var_and_init(irb, coro_scope, node, promise_var, undef_coro_frame, "promise", const_bool_false); - coro_promise_ptr = ir_build_var_ptr(irb, coro_scope, node, promise_var); - - ZigVar *await_handle_var = ir_create_var(irb, node, coro_scope, nullptr, false, false, true, const_bool_false); - IrInstruction *null_value = ir_build_const_null(irb, coro_scope, node); - IrInstruction *await_handle_type_val = ir_build_const_type(irb, coro_scope, node, - get_optional_type(irb->codegen, irb->codegen->builtin_types.entry_promise)); - IrInstruction *null_await_handle = ir_build_implicit_cast(irb, coro_scope, node, await_handle_type_val, null_value, nullptr); - build_decl_var_and_init(irb, coro_scope, node, await_handle_var, null_await_handle, "await_handle", const_bool_false); - irb->exec->await_handle_var_ptr = ir_build_var_ptr(irb, coro_scope, node, await_handle_var); - - u8_ptr_type = ir_build_const_type(irb, coro_scope, node, - get_pointer_to_type(irb->codegen, irb->codegen->builtin_types.entry_u8, false)); - IrInstruction *promise_as_u8_ptr = ir_build_ptr_cast_src(irb, coro_scope, node, u8_ptr_type, - coro_promise_ptr, false); - coro_id = ir_build_coro_id(irb, coro_scope, node, promise_as_u8_ptr); - coro_size_var = ir_create_var(irb, node, coro_scope, nullptr, false, false, true, const_bool_false); - IrInstruction *coro_size = ir_build_coro_size(irb, coro_scope, node); - build_decl_var_and_init(irb, coro_scope, node, coro_size_var, coro_size, "coro_size", const_bool_false); - IrInstruction *implicit_allocator_ptr = ir_build_get_implicit_allocator(irb, coro_scope, node, - ImplicitAllocatorIdArg); - irb->exec->coro_allocator_var = ir_create_var(irb, node, coro_scope, nullptr, true, true, true, const_bool_false); - build_decl_var_and_init(irb, coro_scope, node, irb->exec->coro_allocator_var, implicit_allocator_ptr, - "allocator", const_bool_false); - Buf *realloc_field_name = buf_create_from_str(ASYNC_REALLOC_FIELD_NAME); - IrInstruction *realloc_fn_ptr = ir_build_field_ptr(irb, coro_scope, node, implicit_allocator_ptr, realloc_field_name, false); - IrInstruction *realloc_fn = ir_build_load_ptr(irb, coro_scope, node, realloc_fn_ptr); - IrInstruction *maybe_coro_mem_ptr = ir_build_coro_alloc_helper(irb, coro_scope, node, realloc_fn, coro_size); - IrInstruction *alloc_result_is_ok = ir_build_test_nonnull(irb, coro_scope, node, maybe_coro_mem_ptr); - IrBasicBlock *alloc_err_block = ir_create_basic_block(irb, coro_scope, "AllocError"); - IrBasicBlock *alloc_ok_block = ir_create_basic_block(irb, coro_scope, "AllocOk"); - ir_build_cond_br(irb, coro_scope, node, alloc_result_is_ok, alloc_ok_block, alloc_err_block, const_bool_false); - - ir_set_cursor_at_end_and_append_block(irb, alloc_err_block); - // we can return undefined here, because the caller passes a pointer to the error struct field - // in the error union result, and we populate it in case of allocation failure. - ir_build_return(irb, coro_scope, node, undef); - - ir_set_cursor_at_end_and_append_block(irb, alloc_ok_block); - IrInstruction *coro_mem_ptr = ir_build_ptr_cast_src(irb, coro_scope, node, u8_ptr_type, maybe_coro_mem_ptr, - false); - irb->exec->coro_handle = ir_build_coro_begin(irb, coro_scope, node, coro_id, coro_mem_ptr); - - Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME); - irb->exec->atomic_state_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, - atomic_state_field_name, false); - IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); - ir_build_store_ptr(irb, scope, node, irb->exec->atomic_state_field_ptr, zero); - Buf *result_field_name = buf_create_from_str(RESULT_FIELD_NAME); - irb->exec->coro_result_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_field_name, false); - result_ptr_field_name = buf_create_from_str(RESULT_PTR_FIELD_NAME); - irb->exec->coro_result_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_ptr_field_name, false); - ir_build_store_ptr(irb, scope, node, irb->exec->coro_result_ptr_field_ptr, irb->exec->coro_result_field_ptr); - if (irb->codegen->have_err_ret_tracing) { - // initialize the error return trace - Buf *return_addresses_field_name = buf_create_from_str(RETURN_ADDRESSES_FIELD_NAME); - IrInstruction *return_addresses_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, return_addresses_field_name, false); - - Buf *err_ret_trace_field_name = buf_create_from_str(ERR_RET_TRACE_FIELD_NAME); - err_ret_trace_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_field_name, false); - ir_build_mark_err_ret_trace_ptr(irb, scope, node, err_ret_trace_ptr); - - // coordinate with builtin.zig - Buf *index_name = buf_create_from_str("index"); - IrInstruction *index_ptr = ir_build_field_ptr(irb, scope, node, err_ret_trace_ptr, index_name, false); - ir_build_store_ptr(irb, scope, node, index_ptr, zero); - - Buf *instruction_addresses_name = buf_create_from_str("instruction_addresses"); - IrInstruction *addrs_slice_ptr = ir_build_field_ptr(irb, scope, node, err_ret_trace_ptr, instruction_addresses_name, false); - - IrInstruction *slice_value = ir_build_slice_src(irb, scope, node, return_addresses_ptr, zero, nullptr, false, no_result_loc()); - ir_build_store_ptr(irb, scope, node, addrs_slice_ptr, slice_value); - } - - - irb->exec->coro_early_final = ir_create_basic_block(irb, scope, "CoroEarlyFinal"); - irb->exec->coro_normal_final = ir_create_basic_block(irb, scope, "CoroNormalFinal"); - irb->exec->coro_suspend_block = ir_create_basic_block(irb, scope, "Suspend"); - irb->exec->coro_final_cleanup_block = ir_create_basic_block(irb, scope, "FinalCleanup"); + zig_panic("ir_gen async fn"); } IrInstruction *result = ir_gen_node_extra(irb, node, scope, LValNone, nullptr); @@ -8735,117 +7871,6 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec ir_gen_async_return(irb, scope, result->source_node, result, true); } - if (is_async) { - IrBasicBlock *invalid_resume_block = ir_create_basic_block(irb, scope, "InvalidResume"); - IrBasicBlock *check_free_block = ir_create_basic_block(irb, scope, "CheckFree"); - - ir_set_cursor_at_end_and_append_block(irb, irb->exec->coro_early_final); - IrInstruction *const_bool_true = ir_build_const_bool(irb, scope, node, true); - IrInstruction *suspend_code = ir_build_coro_suspend(irb, scope, node, nullptr, const_bool_true); - IrInstructionSwitchBrCase *cases = allocate<IrInstructionSwitchBrCase>(2); - cases[0].value = ir_build_const_u8(irb, scope, node, 0); - cases[0].block = invalid_resume_block; - cases[1].value = ir_build_const_u8(irb, scope, node, 1); - cases[1].block = irb->exec->coro_final_cleanup_block; - ir_build_switch_br(irb, scope, node, suspend_code, irb->exec->coro_suspend_block, 2, cases, const_bool_false, nullptr); - - ir_set_cursor_at_end_and_append_block(irb, irb->exec->coro_suspend_block); - ir_build_coro_end(irb, scope, node); - ir_build_return(irb, scope, node, irb->exec->coro_handle); - - ir_set_cursor_at_end_and_append_block(irb, invalid_resume_block); - ir_build_unreachable(irb, scope, node); - - ir_set_cursor_at_end_and_append_block(irb, irb->exec->coro_normal_final); - if (type_has_bits(return_type)) { - IrInstruction *u8_ptr_type_unknown_len = ir_build_const_type(irb, scope, node, - get_pointer_to_type_extra(irb->codegen, irb->codegen->builtin_types.entry_u8, - false, false, PtrLenUnknown, 0, 0, 0, false)); - IrInstruction *result_ptr = ir_build_load_ptr(irb, scope, node, irb->exec->coro_result_ptr_field_ptr); - IrInstruction *result_ptr_as_u8_ptr = ir_build_ptr_cast_src(irb, scope, node, u8_ptr_type_unknown_len, - result_ptr, false); - IrInstruction *return_value_ptr_as_u8_ptr = ir_build_ptr_cast_src(irb, scope, node, - u8_ptr_type_unknown_len, irb->exec->coro_result_field_ptr, false); - IrInstruction *return_type_inst = ir_build_const_type(irb, scope, node, - fn_entry->type_entry->data.fn.fn_type_id.return_type); - IrInstruction *size_of_ret_val = ir_build_size_of(irb, scope, node, return_type_inst); - ir_build_memcpy(irb, scope, node, result_ptr_as_u8_ptr, return_value_ptr_as_u8_ptr, size_of_ret_val); - } - if (irb->codegen->have_err_ret_tracing) { - Buf *err_ret_trace_ptr_field_name = buf_create_from_str(ERR_RET_TRACE_PTR_FIELD_NAME); - IrInstruction *err_ret_trace_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_ptr_field_name, false); - IrInstruction *dest_err_ret_trace_ptr = ir_build_load_ptr(irb, scope, node, err_ret_trace_ptr_field_ptr); - ir_build_merge_err_ret_traces(irb, scope, node, coro_promise_ptr, err_ret_trace_ptr, dest_err_ret_trace_ptr); - } - // Before we destroy the coroutine frame, we need to load the target promise into - // a register or local variable which does not get spilled into the frame, - // otherwise llvm tries to access memory inside the destroyed frame. - IrInstruction *unwrapped_await_handle_ptr = ir_build_optional_unwrap_ptr(irb, scope, node, - irb->exec->await_handle_var_ptr, false, false); - IrInstruction *await_handle_in_block = ir_build_load_ptr(irb, scope, node, unwrapped_await_handle_ptr); - ir_build_br(irb, scope, node, check_free_block, const_bool_false); - - ir_set_cursor_at_end_and_append_block(irb, irb->exec->coro_final_cleanup_block); - ir_build_br(irb, scope, node, check_free_block, const_bool_false); - - ir_set_cursor_at_end_and_append_block(irb, check_free_block); - IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); - IrInstruction **incoming_values = allocate<IrInstruction *>(2); - incoming_blocks[0] = irb->exec->coro_final_cleanup_block; - incoming_values[0] = const_bool_false; - incoming_blocks[1] = irb->exec->coro_normal_final; - incoming_values[1] = const_bool_true; - IrInstruction *resume_awaiter = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, nullptr); - - IrBasicBlock **merge_incoming_blocks = allocate<IrBasicBlock *>(2); - IrInstruction **merge_incoming_values = allocate<IrInstruction *>(2); - merge_incoming_blocks[0] = irb->exec->coro_final_cleanup_block; - merge_incoming_values[0] = ir_build_const_undefined(irb, scope, node); - merge_incoming_blocks[1] = irb->exec->coro_normal_final; - merge_incoming_values[1] = await_handle_in_block; - IrInstruction *awaiter_handle = ir_build_phi(irb, scope, node, 2, merge_incoming_blocks, merge_incoming_values, nullptr); - - Buf *shrink_field_name = buf_create_from_str(ASYNC_SHRINK_FIELD_NAME); - IrInstruction *implicit_allocator_ptr = ir_build_get_implicit_allocator(irb, scope, node, - ImplicitAllocatorIdLocalVar); - IrInstruction *shrink_fn_ptr = ir_build_field_ptr(irb, scope, node, implicit_allocator_ptr, shrink_field_name, false); - IrInstruction *shrink_fn = ir_build_load_ptr(irb, scope, node, shrink_fn_ptr); - IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); - IrInstruction *coro_mem_ptr_maybe = ir_build_coro_free(irb, scope, node, coro_id, irb->exec->coro_handle); - IrInstruction *u8_ptr_type_unknown_len = ir_build_const_type(irb, scope, node, - get_pointer_to_type_extra(irb->codegen, irb->codegen->builtin_types.entry_u8, - false, false, PtrLenUnknown, 0, 0, 0, false)); - IrInstruction *coro_mem_ptr = ir_build_ptr_cast_src(irb, scope, node, u8_ptr_type_unknown_len, - coro_mem_ptr_maybe, false); - IrInstruction *coro_mem_ptr_ref = ir_build_ref(irb, scope, node, coro_mem_ptr, true, false); - IrInstruction *coro_size_ptr = ir_build_var_ptr(irb, scope, node, coro_size_var); - IrInstruction *coro_size = ir_build_load_ptr(irb, scope, node, coro_size_ptr); - IrInstruction *mem_slice = ir_build_slice_src(irb, scope, node, coro_mem_ptr_ref, zero, coro_size, false, - no_result_loc()); - size_t arg_count = 5; - IrInstruction **args = allocate<IrInstruction *>(arg_count); - args[0] = implicit_allocator_ptr; // self - args[1] = mem_slice; // old_mem - args[2] = ir_build_const_usize(irb, scope, node, 8); // old_align - // TODO: intentional memory leak here. If this is set to 0 then there is an issue where a coroutine - // calls the function and it frees its own stack frame, but then the return value is a slice, which - // is implemented as an sret struct. writing to the return pointer causes invalid memory write. - // We could work around it by having a global helper function which has a void return type - // and calling that instead. But instead this hack will suffice until I rework coroutines to be - // non-allocating. Basically coroutines are not supported right now until they are reworked. - args[3] = ir_build_const_usize(irb, scope, node, 1); // new_size - args[4] = ir_build_const_usize(irb, scope, node, 1); // new_align - ir_build_call_src(irb, scope, node, nullptr, shrink_fn, arg_count, args, false, FnInlineAuto, false, nullptr, - nullptr, no_result_loc()); - - IrBasicBlock *resume_block = ir_create_basic_block(irb, scope, "Resume"); - 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); - ir_gen_resume_target(irb, scope, node, awaiter_handle); - ir_build_br(irb, scope, node, irb->exec->coro_suspend_block, const_bool_false); - } - return true; } @@ -10189,12 +9214,6 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted return result; } - if (wanted_type == ira->codegen->builtin_types.entry_promise && - actual_type->id == ZigTypeIdPromise) - { - return result; - } - // fn if (wanted_type->id == ZigTypeIdFn && actual_type->id == ZigTypeIdFn) @@ -10229,20 +9248,6 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted return result; } } - if (!wanted_type->data.fn.is_generic && wanted_type->data.fn.fn_type_id.cc == CallingConventionAsync) { - ConstCastOnly child = types_match_const_cast_only(ira, - actual_type->data.fn.fn_type_id.async_allocator_type, - wanted_type->data.fn.fn_type_id.async_allocator_type, - source_node, false); - if (child.id == ConstCastResultIdInvalid) - return child; - if (child.id != ConstCastResultIdOk) { - result.id = ConstCastResultIdAsyncAllocatorType; - result.data.async_allocator_type = allocate_nonzero<ConstCastOnly>(1); - *result.data.async_allocator_type = child; - return result; - } - } if (wanted_type->data.fn.fn_type_id.param_count != actual_type->data.fn.fn_type_id.param_count) { result.id = ConstCastResultIdFnArgCount; return result; @@ -12559,12 +11564,10 @@ static IrInstruction *ir_analyze_int_to_c_ptr(IrAnalyze *ira, IrInstruction *sou static bool is_pointery_and_elem_is_not_pointery(ZigType *ty) { if (ty->id == ZigTypeIdPointer) return ty->data.pointer.child_type->id != ZigTypeIdPointer; if (ty->id == ZigTypeIdFn) return true; - if (ty->id == ZigTypeIdPromise) return true; if (ty->id == ZigTypeIdOptional) { ZigType *ptr_ty = ty->data.maybe.child_type; if (ptr_ty->id == ZigTypeIdPointer) return ptr_ty->data.pointer.child_type->id != ZigTypeIdPointer; if (ptr_ty->id == ZigTypeIdFn) return true; - if (ptr_ty->id == ZigTypeIdPromise) return true; } return false; } @@ -13640,7 +12643,6 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp * case ZigTypeIdOpaque: case ZigTypeIdBoundFn: case ZigTypeIdArgTuple: - case ZigTypeIdPromise: case ZigTypeIdEnum: case ZigTypeIdEnumLiteral: operator_allowed = is_equality_cmp; @@ -15021,7 +14023,6 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio case ZigTypeIdBoundFn: case ZigTypeIdArgTuple: case ZigTypeIdOpaque: - case ZigTypeIdPromise: ir_add_error(ira, target, buf_sprintf("invalid export target '%s'", buf_ptr(&type_value->name))); break; @@ -15045,7 +14046,6 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio case ZigTypeIdBoundFn: case ZigTypeIdArgTuple: case ZigTypeIdOpaque: - case ZigTypeIdPromise: case ZigTypeIdEnumLiteral: ir_add_error(ira, target, buf_sprintf("invalid export target type '%s'", buf_ptr(&target->value.type->name))); @@ -15124,42 +14124,6 @@ static IrInstruction *ir_analyze_instruction_error_union(IrAnalyze *ira, return ir_const_type(ira, &instruction->base, result_type); } -IrInstruction *ir_get_implicit_allocator(IrAnalyze *ira, IrInstruction *source_instr, ImplicitAllocatorId id) { - ZigFn *parent_fn_entry = exec_fn_entry(ira->new_irb.exec); - if (parent_fn_entry == nullptr) { - ir_add_error(ira, source_instr, buf_sprintf("no implicit allocator available")); - return ira->codegen->invalid_instruction; - } - - FnTypeId *parent_fn_type = &parent_fn_entry->type_entry->data.fn.fn_type_id; - if (parent_fn_type->cc != CallingConventionAsync) { - ir_add_error(ira, source_instr, buf_sprintf("async function call from non-async caller requires allocator parameter")); - return ira->codegen->invalid_instruction; - } - - assert(parent_fn_type->async_allocator_type != nullptr); - - switch (id) { - case ImplicitAllocatorIdArg: - { - IrInstruction *result = ir_build_get_implicit_allocator(&ira->new_irb, source_instr->scope, - source_instr->source_node, ImplicitAllocatorIdArg); - result->value.type = parent_fn_type->async_allocator_type; - return result; - } - case ImplicitAllocatorIdLocalVar: - { - ZigVar *coro_allocator_var = ira->old_irb.exec->coro_allocator_var; - assert(coro_allocator_var != nullptr); - IrInstruction *var_ptr_inst = ir_get_var_ptr(ira, source_instr, coro_allocator_var); - IrInstruction *result = ir_get_deref(ira, source_instr, var_ptr_inst, nullptr); - assert(result->value.type != nullptr); - return result; - } - } - zig_unreachable(); -} - static IrInstruction *ir_analyze_alloca(IrAnalyze *ira, IrInstruction *source_inst, ZigType *var_type, uint32_t align, const char *name_hint, bool force_comptime) { @@ -15589,50 +14553,6 @@ static IrInstruction *ir_analyze_instruction_reset_result(IrAnalyze *ira, IrInst return ir_const_void(ira, &instruction->base); } -static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction, ZigFn *fn_entry, - ZigType *fn_type, IrInstruction *fn_ref, IrInstruction **casted_args, size_t arg_count, - IrInstruction *async_allocator_inst) -{ - Buf *realloc_field_name = buf_create_from_str(ASYNC_REALLOC_FIELD_NAME); - ir_assert(async_allocator_inst->value.type->id == ZigTypeIdPointer, &call_instruction->base); - ZigType *container_type = async_allocator_inst->value.type->data.pointer.child_type; - IrInstruction *field_ptr_inst = ir_analyze_container_field_ptr(ira, realloc_field_name, &call_instruction->base, - async_allocator_inst, container_type, false); - if (type_is_invalid(field_ptr_inst->value.type)) { - return ira->codegen->invalid_instruction; - } - ZigType *ptr_to_realloc_fn_type = field_ptr_inst->value.type; - ir_assert(ptr_to_realloc_fn_type->id == ZigTypeIdPointer, &call_instruction->base); - - ZigType *realloc_fn_type = ptr_to_realloc_fn_type->data.pointer.child_type; - if (realloc_fn_type->id != ZigTypeIdFn) { - ir_add_error(ira, &call_instruction->base, - buf_sprintf("expected reallocation function, found '%s'", buf_ptr(&realloc_fn_type->name))); - return ira->codegen->invalid_instruction; - } - - ZigType *realloc_fn_return_type = realloc_fn_type->data.fn.fn_type_id.return_type; - if (realloc_fn_return_type->id != ZigTypeIdErrorUnion) { - ir_add_error(ira, fn_ref, - buf_sprintf("expected allocation function to return error union, but it returns '%s'", buf_ptr(&realloc_fn_return_type->name))); - return ira->codegen->invalid_instruction; - } - ZigType *alloc_fn_error_set_type = realloc_fn_return_type->data.error_union.err_set_type; - ZigType *return_type = fn_type->data.fn.fn_type_id.return_type; - ZigType *promise_type = get_promise_type(ira->codegen, return_type); - ZigType *async_return_type = get_error_union_type(ira->codegen, alloc_fn_error_set_type, promise_type); - - IrInstruction *result_loc = ir_resolve_result(ira, &call_instruction->base, no_result_loc(), - async_return_type, nullptr, true, true); - if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) { - return result_loc; - } - - return ir_build_call_gen(ira, &call_instruction->base, fn_entry, fn_ref, arg_count, - casted_args, FnInlineAuto, true, async_allocator_inst, nullptr, result_loc, - async_return_type); -} - static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node, IrInstruction *arg, Scope **exec_scope, size_t *next_proto_i) { @@ -16330,32 +15250,8 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c break; } } - IrInstruction *async_allocator_inst = nullptr; if (call_instruction->is_async) { - AstNode *async_allocator_type_node = fn_proto_node->data.fn_proto.async_allocator_type; - if (async_allocator_type_node != nullptr) { - ZigType *async_allocator_type = ir_analyze_type_expr(ira, impl_fn->child_scope, async_allocator_type_node); - if (type_is_invalid(async_allocator_type)) - return ira->codegen->invalid_instruction; - inst_fn_type_id.async_allocator_type = async_allocator_type; - } - IrInstruction *uncasted_async_allocator_inst; - if (call_instruction->async_allocator == nullptr) { - uncasted_async_allocator_inst = ir_get_implicit_allocator(ira, &call_instruction->base, - ImplicitAllocatorIdLocalVar); - if (type_is_invalid(uncasted_async_allocator_inst->value.type)) - return ira->codegen->invalid_instruction; - } else { - uncasted_async_allocator_inst = call_instruction->async_allocator->child; - if (type_is_invalid(uncasted_async_allocator_inst->value.type)) - return ira->codegen->invalid_instruction; - } - if (inst_fn_type_id.async_allocator_type == nullptr) { - inst_fn_type_id.async_allocator_type = uncasted_async_allocator_inst->value.type; - } - async_allocator_inst = ir_implicit_cast(ira, uncasted_async_allocator_inst, inst_fn_type_id.async_allocator_type); - if (type_is_invalid(async_allocator_inst->value.type)) - return ira->codegen->invalid_instruction; + zig_panic("TODO async call"); } auto existing_entry = ira->codegen->generic_table.put_unique(generic_id, impl_fn); @@ -16398,15 +15294,12 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c size_t impl_param_count = impl_fn_type_id->param_count; if (call_instruction->is_async) { - IrInstruction *result = ir_analyze_async_call(ira, call_instruction, impl_fn, impl_fn->type_entry, - fn_ref, casted_args, impl_param_count, async_allocator_inst); - return ir_finish_anal(ira, result); + zig_panic("TODO async call"); } - assert(async_allocator_inst == nullptr); IrInstruction *new_call_instruction = ir_build_call_gen(ira, &call_instruction->base, impl_fn, nullptr, impl_param_count, casted_args, fn_inline, - call_instruction->is_async, nullptr, casted_new_stack, result_loc, + call_instruction->is_async, casted_new_stack, result_loc, impl_fn_type_id->return_type); return ir_finish_anal(ira, new_call_instruction); @@ -16474,25 +15367,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c return ira->codegen->invalid_instruction; if (call_instruction->is_async) { - IrInstruction *uncasted_async_allocator_inst; - if (call_instruction->async_allocator == nullptr) { - uncasted_async_allocator_inst = ir_get_implicit_allocator(ira, &call_instruction->base, - ImplicitAllocatorIdLocalVar); - if (type_is_invalid(uncasted_async_allocator_inst->value.type)) - return ira->codegen->invalid_instruction; - } else { - uncasted_async_allocator_inst = call_instruction->async_allocator->child; - if (type_is_invalid(uncasted_async_allocator_inst->value.type)) - return ira->codegen->invalid_instruction; - - } - IrInstruction *async_allocator_inst = ir_implicit_cast(ira, uncasted_async_allocator_inst, fn_type_id->async_allocator_type); - if (type_is_invalid(async_allocator_inst->value.type)) - return ira->codegen->invalid_instruction; - - IrInstruction *result = ir_analyze_async_call(ira, call_instruction, fn_entry, fn_type, fn_ref, - casted_args, call_param_count, async_allocator_inst); - return ir_finish_anal(ira, result); + zig_panic("TODO async call"); } if (fn_entry != nullptr && fn_entry->fn_inline == FnInlineAlways && fn_inline == FnInlineNever) { @@ -16513,7 +15388,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c } IrInstruction *new_call_instruction = ir_build_call_gen(ira, &call_instruction->base, fn_entry, fn_ref, - call_param_count, casted_args, fn_inline, false, nullptr, casted_new_stack, + call_param_count, casted_args, fn_inline, false, casted_new_stack, result_loc, return_type); return ir_finish_anal(ira, new_call_instruction); } @@ -16694,7 +15569,6 @@ static IrInstruction *ir_analyze_maybe(IrAnalyze *ira, IrInstructionUnOp *un_op_ case ZigTypeIdFn: case ZigTypeIdBoundFn: case ZigTypeIdArgTuple: - case ZigTypeIdPromise: return ir_const_type(ira, &un_op_instruction->base, get_optional_type(ira->codegen, type_entry)); case ZigTypeIdUnreachable: case ZigTypeIdOpaque: @@ -18465,7 +17339,6 @@ static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira, case ZigTypeIdUnion: case ZigTypeIdFn: case ZigTypeIdBoundFn: - case ZigTypeIdPromise: case ZigTypeIdVector: { ResolveStatus needed_status = (align_bytes == 0) ? @@ -18580,7 +17453,6 @@ static IrInstruction *ir_analyze_instruction_array_type(IrAnalyze *ira, case ZigTypeIdUnion: case ZigTypeIdFn: case ZigTypeIdBoundFn: - case ZigTypeIdPromise: case ZigTypeIdVector: { if ((err = ensure_complete_type(ira->codegen, child_type))) @@ -18592,22 +17464,6 @@ static IrInstruction *ir_analyze_instruction_array_type(IrAnalyze *ira, zig_unreachable(); } -static IrInstruction *ir_analyze_instruction_promise_type(IrAnalyze *ira, IrInstructionPromiseType *instruction) { - ZigType *promise_type; - - if (instruction->payload_type == nullptr) { - promise_type = ira->codegen->builtin_types.entry_promise; - } else { - ZigType *payload_type = ir_resolve_type(ira, instruction->payload_type->child); - if (type_is_invalid(payload_type)) - return ira->codegen->invalid_instruction; - - promise_type = get_promise_type(ira->codegen, payload_type); - } - - return ir_const_type(ira, &instruction->base, promise_type); -} - static IrInstruction *ir_analyze_instruction_size_of(IrAnalyze *ira, IrInstructionSizeOf *size_of_instruction) { @@ -18647,7 +17503,6 @@ static IrInstruction *ir_analyze_instruction_size_of(IrAnalyze *ira, case ZigTypeIdEnum: case ZigTypeIdUnion: case ZigTypeIdFn: - case ZigTypeIdPromise: case ZigTypeIdVector: { uint64_t size_in_bytes = type_size(ira->codegen, type_entry); @@ -19134,7 +17989,6 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira, case ZigTypeIdComptimeInt: case ZigTypeIdEnumLiteral: case ZigTypeIdPointer: - case ZigTypeIdPromise: case ZigTypeIdFn: case ZigTypeIdErrorSet: { if (pointee_val) { @@ -20647,32 +19501,6 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr break; } - case ZigTypeIdPromise: - { - result = create_const_vals(1); - result->special = ConstValSpecialStatic; - result->type = ir_type_info_get_type(ira, "Promise", nullptr); - - ConstExprValue *fields = create_const_vals(1); - result->data.x_struct.fields = fields; - - // child: ?type - ensure_field_index(result->type, "child", 0); - fields[0].special = ConstValSpecialStatic; - fields[0].type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); - - if (type_entry->data.promise.result_type == nullptr) - fields[0].data.x_optional = nullptr; - else { - ConstExprValue *child_type = create_const_vals(1); - child_type->special = ConstValSpecialStatic; - child_type->type = ira->codegen->builtin_types.entry_type; - child_type->data.x_type = type_entry->data.promise.result_type; - fields[0].data.x_optional = child_type; - } - - break; - } case ZigTypeIdEnum: { result = create_const_vals(1); @@ -20982,7 +19810,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr result->special = ConstValSpecialStatic; result->type = ir_type_info_get_type(ira, "Fn", nullptr); - ConstExprValue *fields = create_const_vals(6); + ConstExprValue *fields = create_const_vals(5); result->data.x_struct.fields = fields; // calling_convention: TypeInfo.CallingConvention @@ -21015,19 +19843,6 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr return_type->data.x_type = type_entry->data.fn.fn_type_id.return_type; fields[3].data.x_optional = return_type; } - // async_allocator_type: type - ensure_field_index(result->type, "async_allocator_type", 4); - fields[4].special = ConstValSpecialStatic; - fields[4].type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); - if (type_entry->data.fn.fn_type_id.async_allocator_type == nullptr) - fields[4].data.x_optional = nullptr; - else { - ConstExprValue *async_alloc_type = create_const_vals(1); - async_alloc_type->special = ConstValSpecialStatic; - async_alloc_type->type = ira->codegen->builtin_types.entry_type; - async_alloc_type->data.x_type = type_entry->data.fn.fn_type_id.async_allocator_type; - fields[4].data.x_optional = async_alloc_type; - } // args: []TypeInfo.FnArg ZigType *type_info_fn_arg_type = ir_type_info_get_type(ira, "FnArg", nullptr); if ((err = type_resolve(ira->codegen, type_info_fn_arg_type, ResolveStatusSizeKnown))) { @@ -21042,10 +19857,9 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr fn_arg_array->data.x_array.special = ConstArraySpecialNone; fn_arg_array->data.x_array.data.s_none.elements = create_const_vals(fn_arg_count); - init_const_slice(ira->codegen, &fields[5], fn_arg_array, 0, fn_arg_count, false); + init_const_slice(ira->codegen, &fields[4], fn_arg_array, 0, fn_arg_count, false); - for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++) - { + for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++) { FnTypeParamInfo *fn_param_info = &type_entry->data.fn.fn_type_id.param_info[fn_arg_index]; ConstExprValue *fn_arg_val = &fn_arg_array->data.x_array.data.s_none.elements[fn_arg_index]; @@ -22803,11 +21617,7 @@ static IrInstruction *ir_analyze_instruction_frame_address(IrAnalyze *ira, IrIns } static IrInstruction *ir_analyze_instruction_handle(IrAnalyze *ira, IrInstructionHandle *instruction) { - IrInstruction *result = ir_build_handle(&ira->new_irb, instruction->base.scope, instruction->base.source_node); - ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); - assert(fn_entry != nullptr); - result->value.type = get_promise_type(ira->codegen, fn_entry->type_entry->data.fn.fn_type_id.return_type); - return result; + zig_panic("TODO anlayze @handle()"); } static IrInstruction *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstructionAlignOf *instruction) { @@ -22841,7 +21651,6 @@ static IrInstruction *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstruct case ZigTypeIdInt: case ZigTypeIdFloat: case ZigTypeIdPointer: - case ZigTypeIdPromise: case ZigTypeIdArray: case ZigTypeIdStruct: case ZigTypeIdOptional: @@ -23401,15 +22210,7 @@ static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstruct } if (fn_type_id.cc == CallingConventionAsync) { - if (instruction->async_allocator_type_value == nullptr) { - ir_add_error(ira, &instruction->base, - buf_sprintf("async fn proto missing allocator type")); - return ira->codegen->invalid_instruction; - } - IrInstruction *async_allocator_type_value = instruction->async_allocator_type_value->child; - fn_type_id.async_allocator_type = ir_resolve_type(ira, async_allocator_type_value); - if (type_is_invalid(fn_type_id.async_allocator_type)) - return ira->codegen->invalid_instruction; + zig_panic("TODO"); } return ir_const_type(ira, &instruction->base, get_fn_type(ira->codegen, &fn_type_id)); @@ -23905,7 +22706,6 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue case ZigTypeIdEnumLiteral: case ZigTypeIdUndefined: case ZigTypeIdNull: - case ZigTypeIdPromise: case ZigTypeIdErrorUnion: case ZigTypeIdErrorSet: zig_unreachable(); @@ -24059,7 +22859,6 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou case ZigTypeIdEnumLiteral: case ZigTypeIdUndefined: case ZigTypeIdNull: - case ZigTypeIdPromise: zig_unreachable(); case ZigTypeIdVoid: return ErrorNone; @@ -24546,181 +23345,7 @@ static IrInstruction *ir_analyze_instruction_tag_type(IrAnalyze *ira, IrInstruct } static IrInstruction *ir_analyze_instruction_cancel(IrAnalyze *ira, IrInstructionCancel *instruction) { - IrInstruction *target_inst = instruction->target->child; - if (type_is_invalid(target_inst->value.type)) - return ira->codegen->invalid_instruction; - IrInstruction *casted_target = ir_implicit_cast(ira, target_inst, ira->codegen->builtin_types.entry_promise); - if (type_is_invalid(casted_target->value.type)) - return ira->codegen->invalid_instruction; - - IrInstruction *result = ir_build_cancel(&ira->new_irb, instruction->base.scope, instruction->base.source_node, casted_target); - result->value.type = ira->codegen->builtin_types.entry_void; - result->value.special = ConstValSpecialStatic; - return result; -} - -static IrInstruction *ir_analyze_instruction_coro_id(IrAnalyze *ira, IrInstructionCoroId *instruction) { - IrInstruction *promise_ptr = instruction->promise_ptr->child; - if (type_is_invalid(promise_ptr->value.type)) - return ira->codegen->invalid_instruction; - - IrInstruction *result = ir_build_coro_id(&ira->new_irb, instruction->base.scope, instruction->base.source_node, - promise_ptr); - result->value.type = ira->codegen->builtin_types.entry_usize; - return result; -} - -static IrInstruction *ir_analyze_instruction_coro_alloc(IrAnalyze *ira, IrInstructionCoroAlloc *instruction) { - IrInstruction *coro_id = instruction->coro_id->child; - if (type_is_invalid(coro_id->value.type)) - return ira->codegen->invalid_instruction; - - IrInstruction *result = ir_build_coro_alloc(&ira->new_irb, instruction->base.scope, instruction->base.source_node, - coro_id); - result->value.type = ira->codegen->builtin_types.entry_bool; - return result; -} - -static IrInstruction *ir_analyze_instruction_coro_size(IrAnalyze *ira, IrInstructionCoroSize *instruction) { - IrInstruction *result = ir_build_coro_size(&ira->new_irb, instruction->base.scope, instruction->base.source_node); - result->value.type = ira->codegen->builtin_types.entry_usize; - return result; -} - -static IrInstruction *ir_analyze_instruction_coro_begin(IrAnalyze *ira, IrInstructionCoroBegin *instruction) { - IrInstruction *coro_id = instruction->coro_id->child; - if (type_is_invalid(coro_id->value.type)) - return ira->codegen->invalid_instruction; - - IrInstruction *coro_mem_ptr = instruction->coro_mem_ptr->child; - if (type_is_invalid(coro_mem_ptr->value.type)) - return ira->codegen->invalid_instruction; - - ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); - ir_assert(fn_entry != nullptr, &instruction->base); - IrInstruction *result = ir_build_coro_begin(&ira->new_irb, instruction->base.scope, instruction->base.source_node, - coro_id, coro_mem_ptr); - result->value.type = get_promise_type(ira->codegen, fn_entry->type_entry->data.fn.fn_type_id.return_type); - return result; -} - -static IrInstruction *ir_analyze_instruction_get_implicit_allocator(IrAnalyze *ira, IrInstructionGetImplicitAllocator *instruction) { - return ir_get_implicit_allocator(ira, &instruction->base, instruction->id); -} - -static IrInstruction *ir_analyze_instruction_coro_alloc_fail(IrAnalyze *ira, IrInstructionCoroAllocFail *instruction) { - IrInstruction *err_val = instruction->err_val->child; - if (type_is_invalid(err_val->value.type)) - return ir_unreach_error(ira); - - IrInstruction *result = ir_build_coro_alloc_fail(&ira->new_irb, instruction->base.scope, instruction->base.source_node, err_val); - result->value.type = ira->codegen->builtin_types.entry_unreachable; - return ir_finish_anal(ira, result); -} - -static IrInstruction *ir_analyze_instruction_coro_suspend(IrAnalyze *ira, IrInstructionCoroSuspend *instruction) { - IrInstruction *save_point = nullptr; - if (instruction->save_point != nullptr) { - save_point = instruction->save_point->child; - if (type_is_invalid(save_point->value.type)) - return ira->codegen->invalid_instruction; - } - - IrInstruction *is_final = instruction->is_final->child; - if (type_is_invalid(is_final->value.type)) - return ira->codegen->invalid_instruction; - - IrInstruction *result = ir_build_coro_suspend(&ira->new_irb, instruction->base.scope, - instruction->base.source_node, save_point, is_final); - result->value.type = ira->codegen->builtin_types.entry_u8; - return result; -} - -static IrInstruction *ir_analyze_instruction_coro_end(IrAnalyze *ira, IrInstructionCoroEnd *instruction) { - IrInstruction *result = ir_build_coro_end(&ira->new_irb, instruction->base.scope, - instruction->base.source_node); - result->value.type = ira->codegen->builtin_types.entry_void; - return result; -} - -static IrInstruction *ir_analyze_instruction_coro_free(IrAnalyze *ira, IrInstructionCoroFree *instruction) { - IrInstruction *coro_id = instruction->coro_id->child; - if (type_is_invalid(coro_id->value.type)) - return ira->codegen->invalid_instruction; - - IrInstruction *coro_handle = instruction->coro_handle->child; - if (type_is_invalid(coro_handle->value.type)) - return ira->codegen->invalid_instruction; - - IrInstruction *result = ir_build_coro_free(&ira->new_irb, instruction->base.scope, - instruction->base.source_node, coro_id, coro_handle); - ZigType *ptr_type = get_pointer_to_type(ira->codegen, ira->codegen->builtin_types.entry_u8, false); - result->value.type = get_optional_type(ira->codegen, ptr_type); - return result; -} - -static IrInstruction *ir_analyze_instruction_coro_resume(IrAnalyze *ira, IrInstructionCoroResume *instruction) { - IrInstruction *awaiter_handle = instruction->awaiter_handle->child; - if (type_is_invalid(awaiter_handle->value.type)) - return ira->codegen->invalid_instruction; - - IrInstruction *casted_target = ir_implicit_cast(ira, awaiter_handle, ira->codegen->builtin_types.entry_promise); - if (type_is_invalid(casted_target->value.type)) - return ira->codegen->invalid_instruction; - - IrInstruction *result = ir_build_coro_resume(&ira->new_irb, instruction->base.scope, - instruction->base.source_node, casted_target); - result->value.type = ira->codegen->builtin_types.entry_void; - return result; -} - -static IrInstruction *ir_analyze_instruction_coro_save(IrAnalyze *ira, IrInstructionCoroSave *instruction) { - IrInstruction *coro_handle = instruction->coro_handle->child; - if (type_is_invalid(coro_handle->value.type)) - return ira->codegen->invalid_instruction; - - IrInstruction *result = ir_build_coro_save(&ira->new_irb, instruction->base.scope, - instruction->base.source_node, coro_handle); - result->value.type = ira->codegen->builtin_types.entry_usize; - return result; -} - -static IrInstruction *ir_analyze_instruction_coro_promise(IrAnalyze *ira, IrInstructionCoroPromise *instruction) { - IrInstruction *coro_handle = instruction->coro_handle->child; - if (type_is_invalid(coro_handle->value.type)) - return ira->codegen->invalid_instruction; - - if (coro_handle->value.type->id != ZigTypeIdPromise || - coro_handle->value.type->data.promise.result_type == nullptr) - { - ir_add_error(ira, &instruction->base, buf_sprintf("expected promise->T, found '%s'", - buf_ptr(&coro_handle->value.type->name))); - return ira->codegen->invalid_instruction; - } - - ZigType *coro_frame_type = get_promise_frame_type(ira->codegen, - coro_handle->value.type->data.promise.result_type); - - IrInstruction *result = ir_build_coro_promise(&ira->new_irb, instruction->base.scope, - instruction->base.source_node, coro_handle); - result->value.type = get_pointer_to_type(ira->codegen, coro_frame_type, false); - return result; -} - -static IrInstruction *ir_analyze_instruction_coro_alloc_helper(IrAnalyze *ira, IrInstructionCoroAllocHelper *instruction) { - IrInstruction *realloc_fn = instruction->realloc_fn->child; - if (type_is_invalid(realloc_fn->value.type)) - return ira->codegen->invalid_instruction; - - IrInstruction *coro_size = instruction->coro_size->child; - if (type_is_invalid(coro_size->value.type)) - return ira->codegen->invalid_instruction; - - IrInstruction *result = ir_build_coro_alloc_helper(&ira->new_irb, instruction->base.scope, - instruction->base.source_node, realloc_fn, coro_size); - ZigType *u8_ptr_type = get_pointer_to_type(ira->codegen, ira->codegen->builtin_types.entry_u8, false); - result->value.type = get_optional_type(ira->codegen, u8_ptr_type); - return result; + zig_panic("TODO analyze cancel"); } static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstruction *op) { @@ -24853,65 +23478,6 @@ static IrInstruction *ir_analyze_instruction_atomic_load(IrAnalyze *ira, IrInstr return result; } -static IrInstruction *ir_analyze_instruction_promise_result_type(IrAnalyze *ira, IrInstructionPromiseResultType *instruction) { - ZigType *promise_type = ir_resolve_type(ira, instruction->promise_type->child); - if (type_is_invalid(promise_type)) - return ira->codegen->invalid_instruction; - - if (promise_type->id != ZigTypeIdPromise || promise_type->data.promise.result_type == nullptr) { - ir_add_error(ira, &instruction->base, buf_sprintf("expected promise->T, found '%s'", - buf_ptr(&promise_type->name))); - return ira->codegen->invalid_instruction; - } - - return ir_const_type(ira, &instruction->base, promise_type->data.promise.result_type); -} - -static IrInstruction *ir_analyze_instruction_await_bookkeeping(IrAnalyze *ira, IrInstructionAwaitBookkeeping *instruction) { - ZigType *promise_result_type = ir_resolve_type(ira, instruction->promise_result_type->child); - if (type_is_invalid(promise_result_type)) - return ira->codegen->invalid_instruction; - - ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); - ir_assert(fn_entry != nullptr, &instruction->base); - - if (type_can_fail(promise_result_type)) { - fn_entry->calls_or_awaits_errorable_fn = true; - } - - return ir_const_void(ira, &instruction->base); -} - -static IrInstruction *ir_analyze_instruction_merge_err_ret_traces(IrAnalyze *ira, - IrInstructionMergeErrRetTraces *instruction) -{ - IrInstruction *coro_promise_ptr = instruction->coro_promise_ptr->child; - if (type_is_invalid(coro_promise_ptr->value.type)) - return ira->codegen->invalid_instruction; - - ir_assert(coro_promise_ptr->value.type->id == ZigTypeIdPointer, &instruction->base); - ZigType *promise_frame_type = coro_promise_ptr->value.type->data.pointer.child_type; - ir_assert(promise_frame_type->id == ZigTypeIdStruct, &instruction->base); - ZigType *promise_result_type = promise_frame_type->data.structure.fields[1].type_entry; - - if (!type_can_fail(promise_result_type)) { - return ir_const_void(ira, &instruction->base); - } - - IrInstruction *src_err_ret_trace_ptr = instruction->src_err_ret_trace_ptr->child; - if (type_is_invalid(src_err_ret_trace_ptr->value.type)) - return ira->codegen->invalid_instruction; - - IrInstruction *dest_err_ret_trace_ptr = instruction->dest_err_ret_trace_ptr->child; - if (type_is_invalid(dest_err_ret_trace_ptr->value.type)) - return ira->codegen->invalid_instruction; - - IrInstruction *result = ir_build_merge_err_ret_traces(&ira->new_irb, instruction->base.scope, - instruction->base.source_node, coro_promise_ptr, src_err_ret_trace_ptr, dest_err_ret_trace_ptr); - result->value.type = ira->codegen->builtin_types.entry_void; - return result; -} - static IrInstruction *ir_analyze_instruction_save_err_ret_addr(IrAnalyze *ira, IrInstructionSaveErrRetAddr *instruction) { IrInstruction *result = ir_build_save_err_ret_addr(&ira->new_irb, instruction->base.scope, instruction->base.source_node); @@ -25530,8 +24096,6 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction return ir_analyze_instruction_asm(ira, (IrInstructionAsm *)instruction); case IrInstructionIdArrayType: return ir_analyze_instruction_array_type(ira, (IrInstructionArrayType *)instruction); - case IrInstructionIdPromiseType: - return ir_analyze_instruction_promise_type(ira, (IrInstructionPromiseType *)instruction); case IrInstructionIdSizeOf: return ir_analyze_instruction_size_of(ira, (IrInstructionSizeOf *)instruction); case IrInstructionIdTestNonNull: @@ -25704,46 +24268,14 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction return ir_analyze_instruction_error_union(ira, (IrInstructionErrorUnion *)instruction); case IrInstructionIdCancel: return ir_analyze_instruction_cancel(ira, (IrInstructionCancel *)instruction); - case IrInstructionIdCoroId: - return ir_analyze_instruction_coro_id(ira, (IrInstructionCoroId *)instruction); - case IrInstructionIdCoroAlloc: - return ir_analyze_instruction_coro_alloc(ira, (IrInstructionCoroAlloc *)instruction); - case IrInstructionIdCoroSize: - return ir_analyze_instruction_coro_size(ira, (IrInstructionCoroSize *)instruction); - case IrInstructionIdCoroBegin: - return ir_analyze_instruction_coro_begin(ira, (IrInstructionCoroBegin *)instruction); - case IrInstructionIdGetImplicitAllocator: - return ir_analyze_instruction_get_implicit_allocator(ira, (IrInstructionGetImplicitAllocator *)instruction); - case IrInstructionIdCoroAllocFail: - return ir_analyze_instruction_coro_alloc_fail(ira, (IrInstructionCoroAllocFail *)instruction); - case IrInstructionIdCoroSuspend: - return ir_analyze_instruction_coro_suspend(ira, (IrInstructionCoroSuspend *)instruction); - case IrInstructionIdCoroEnd: - return ir_analyze_instruction_coro_end(ira, (IrInstructionCoroEnd *)instruction); - case IrInstructionIdCoroFree: - return ir_analyze_instruction_coro_free(ira, (IrInstructionCoroFree *)instruction); - case IrInstructionIdCoroResume: - return ir_analyze_instruction_coro_resume(ira, (IrInstructionCoroResume *)instruction); - case IrInstructionIdCoroSave: - return ir_analyze_instruction_coro_save(ira, (IrInstructionCoroSave *)instruction); - case IrInstructionIdCoroPromise: - return ir_analyze_instruction_coro_promise(ira, (IrInstructionCoroPromise *)instruction); - case IrInstructionIdCoroAllocHelper: - return ir_analyze_instruction_coro_alloc_helper(ira, (IrInstructionCoroAllocHelper *)instruction); case IrInstructionIdAtomicRmw: return ir_analyze_instruction_atomic_rmw(ira, (IrInstructionAtomicRmw *)instruction); case IrInstructionIdAtomicLoad: return ir_analyze_instruction_atomic_load(ira, (IrInstructionAtomicLoad *)instruction); - case IrInstructionIdPromiseResultType: - return ir_analyze_instruction_promise_result_type(ira, (IrInstructionPromiseResultType *)instruction); - case IrInstructionIdAwaitBookkeeping: - return ir_analyze_instruction_await_bookkeeping(ira, (IrInstructionAwaitBookkeeping *)instruction); case IrInstructionIdSaveErrRetAddr: return ir_analyze_instruction_save_err_ret_addr(ira, (IrInstructionSaveErrRetAddr *)instruction); case IrInstructionIdAddImplicitReturnType: return ir_analyze_instruction_add_implicit_return_type(ira, (IrInstructionAddImplicitReturnType *)instruction); - case IrInstructionIdMergeErrRetTraces: - return ir_analyze_instruction_merge_err_ret_traces(ira, (IrInstructionMergeErrRetTraces *)instruction); case IrInstructionIdMarkErrRetTracePtr: return ir_analyze_instruction_mark_err_ret_trace_ptr(ira, (IrInstructionMarkErrRetTracePtr *)instruction); case IrInstructionIdFloatOp: @@ -25788,9 +24320,7 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_ old_exec->analysis = ira; ira->codegen = codegen; - ZigFn *fn_entry = exec_fn_entry(old_exec); - bool is_async = fn_entry != nullptr && fn_entry->type_entry->data.fn.fn_type_id.cc == CallingConventionAsync; - ira->explicit_return_type = is_async ? get_promise_type(codegen, expected_type) : expected_type; + ira->explicit_return_type = expected_type; ira->explicit_return_type_source_node = expected_type_source_node; ira->old_irb.codegen = codegen; @@ -25889,17 +24419,8 @@ bool ir_has_side_effects(IrInstruction *instruction) { case IrInstructionIdSetAlignStack: case IrInstructionIdExport: case IrInstructionIdCancel: - case IrInstructionIdCoroId: - case IrInstructionIdCoroBegin: - case IrInstructionIdCoroAllocFail: - case IrInstructionIdCoroEnd: - case IrInstructionIdCoroResume: - case IrInstructionIdCoroSave: - case IrInstructionIdCoroAllocHelper: - case IrInstructionIdAwaitBookkeeping: case IrInstructionIdSaveErrRetAddr: case IrInstructionIdAddImplicitReturnType: - case IrInstructionIdMergeErrRetTraces: case IrInstructionIdMarkErrRetTracePtr: case IrInstructionIdAtomicRmw: case IrInstructionIdCmpxchgGen: @@ -25933,7 +24454,6 @@ bool ir_has_side_effects(IrInstruction *instruction) { case IrInstructionIdTypeOf: case IrInstructionIdStructFieldPtr: case IrInstructionIdArrayType: - case IrInstructionIdPromiseType: case IrInstructionIdSliceType: case IrInstructionIdSizeOf: case IrInstructionIdTestNonNull: @@ -25993,13 +24513,6 @@ bool ir_has_side_effects(IrInstruction *instruction) { case IrInstructionIdTagType: case IrInstructionIdErrorReturnTrace: case IrInstructionIdErrorUnion: - case IrInstructionIdGetImplicitAllocator: - case IrInstructionIdCoroAlloc: - case IrInstructionIdCoroSize: - case IrInstructionIdCoroSuspend: - case IrInstructionIdCoroFree: - case IrInstructionIdCoroPromise: - case IrInstructionIdPromiseResultType: case IrInstructionIdFloatOp: case IrInstructionIdMulAdd: case IrInstructionIdAtomicLoad: |
