| ... | @@ -668,6 +668,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroBegin *) { | ... | @@ -668,6 +668,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroBegin *) { |
| 668 | return IrInstructionIdCoroBegin; | 668 | return IrInstructionIdCoroBegin; |
| 669 | } | 669 | } |
| 670 | | 670 | |
| | 671 | static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroAllocFail *) { |
| | 672 | return IrInstructionIdCoroAllocFail; |
| | 673 | } |
| | 674 | |
| 671 | template<typename T> | 675 | template<typename T> |
| 672 | static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) { | 676 | static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) { |
| 673 | T *special_instruction = allocate<T>(1); | 677 | T *special_instruction = allocate<T>(1); |
| ... | @@ -810,6 +814,14 @@ static IrInstruction *ir_build_const_usize(IrBuilder *irb, Scope *scope, AstNode | ... | @@ -810,6 +814,14 @@ static IrInstruction *ir_build_const_usize(IrBuilder *irb, Scope *scope, AstNode |
| 810 | return &const_instruction->base; | 814 | return &const_instruction->base; |
| 811 | } | 815 | } |
| 812 | | 816 | |
| | 817 | static IrInstruction *ir_build_const_u29(IrBuilder *irb, Scope *scope, AstNode *source_node, uint32_t value) { |
| | 818 | IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); |
| | 819 | const_instruction->base.value.type = irb->codegen->builtin_types.entry_u29; |
| | 820 | const_instruction->base.value.special = ConstValSpecialStatic; |
| | 821 | bigint_init_unsigned(&const_instruction->base.value.data.x_bigint, value); |
| | 822 | return &const_instruction->base; |
| | 823 | } |
| | 824 | |
| 813 | static IrInstruction *ir_create_const_type(IrBuilder *irb, Scope *scope, AstNode *source_node, | 825 | static IrInstruction *ir_create_const_type(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 814 | TypeTableEntry *type_entry) | 826 | TypeTableEntry *type_entry) |
| 815 | { | 827 | { |
| ... | @@ -2471,6 +2483,17 @@ static IrInstruction *ir_build_coro_begin(IrBuilder *irb, Scope *scope, AstNode | ... | @@ -2471,6 +2483,17 @@ static IrInstruction *ir_build_coro_begin(IrBuilder *irb, Scope *scope, AstNode |
| 2471 | return &instruction->base; | 2483 | return &instruction->base; |
| 2472 | } | 2484 | } |
| 2473 | | 2485 | |
| | 2486 | static IrInstruction *ir_build_coro_alloc_fail(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *err_val) { |
| | 2487 | IrInstructionCoroAllocFail *instruction = ir_build_instruction<IrInstructionCoroAllocFail>(irb, scope, source_node); |
| | 2488 | instruction->base.value.type = irb->codegen->builtin_types.entry_unreachable; |
| | 2489 | instruction->base.value.special = ConstValSpecialStatic; |
| | 2490 | instruction->err_val = err_val; |
| | 2491 | |
| | 2492 | ir_ref_instruction(err_val, irb->current_basic_block); |
| | 2493 | |
| | 2494 | return &instruction->base; |
| | 2495 | } |
| | 2496 | |
| 2474 | static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) { | 2497 | static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) { |
| 2475 | results[ReturnKindUnconditional] = 0; | 2498 | results[ReturnKindUnconditional] = 0; |
| 2476 | results[ReturnKindError] = 0; | 2499 | results[ReturnKindError] = 0; |
| ... | @@ -5854,23 +5877,22 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec | ... | @@ -5854,23 +5877,22 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 5854 | Buf *alloc_field_name = buf_create_from_str(ASYNC_ALLOC_FIELD_NAME); | 5877 | Buf *alloc_field_name = buf_create_from_str(ASYNC_ALLOC_FIELD_NAME); |
| 5855 | IrInstruction *alloc_fn_ptr = ir_build_field_ptr(irb, scope, node, implicit_allocator_ptr, alloc_field_name); | 5878 | IrInstruction *alloc_fn_ptr = ir_build_field_ptr(irb, scope, node, implicit_allocator_ptr, alloc_field_name); |
| 5856 | IrInstruction *alloc_fn = ir_build_load_ptr(irb, scope, node, alloc_fn_ptr); | 5879 | IrInstruction *alloc_fn = ir_build_load_ptr(irb, scope, node, alloc_fn_ptr); |
| 5857 | IrInstruction *implicit_allocator = ir_build_load_ptr(irb, scope, node, implicit_allocator_ptr); | 5880 | IrInstruction *alignment = ir_build_const_u29(irb, scope, node, irb->codegen->pointer_size_bytes * 2); |
| 5858 | IrInstruction *alignment = ir_build_const_usize(irb, scope, node, irb->codegen->pointer_size_bytes * 2); | | |
| 5859 | size_t arg_count = 3; | 5881 | size_t arg_count = 3; |
| 5860 | IrInstruction **args = allocate<IrInstruction *>(arg_count); | 5882 | IrInstruction **args = allocate<IrInstruction *>(arg_count); |
| 5861 | args[0] = implicit_allocator; // self | 5883 | args[0] = implicit_allocator_ptr; // self |
| 5862 | args[1] = coro_size; // byte_count | 5884 | args[1] = coro_size; // byte_count |
| 5863 | args[2] = alignment; // alignment | 5885 | args[2] = alignment; // alignment |
| 5864 | IrInstruction *alloc_result = ir_build_call(irb, scope, node, nullptr, alloc_fn, arg_count, args, false, FnInlineAuto, false, nullptr); | 5886 | IrInstruction *alloc_result = ir_build_call(irb, scope, node, nullptr, alloc_fn, arg_count, args, false, FnInlineAuto, false, nullptr); |
| 5865 | IrInstruction *alloc_result_ptr = ir_build_ref(irb, scope, node, alloc_result, true, false); | 5887 | IrInstruction *alloc_result_ptr = ir_build_ref(irb, scope, node, alloc_result, true, false); |
| 5866 | IrInstruction *alloc_result_is_err = ir_build_test_err(irb, scope, node, alloc_result_ptr); | 5888 | IrInstruction *alloc_result_is_err = ir_build_test_err(irb, scope, node, alloc_result); |
| 5867 | IrBasicBlock *alloc_err_block = ir_create_basic_block(irb, scope, "AllocError"); | 5889 | IrBasicBlock *alloc_err_block = ir_create_basic_block(irb, scope, "AllocError"); |
| 5868 | IrBasicBlock *alloc_ok_block = ir_create_basic_block(irb, scope, "AllocOk"); | 5890 | IrBasicBlock *alloc_ok_block = ir_create_basic_block(irb, scope, "AllocOk"); |
| 5869 | ir_build_cond_br(irb, scope, node, alloc_result_is_err, alloc_err_block, alloc_ok_block, is_comptime_false); | 5891 | ir_build_cond_br(irb, scope, node, alloc_result_is_err, alloc_err_block, alloc_ok_block, is_comptime_false); |
| 5870 | | 5892 | |
| 5871 | ir_set_cursor_at_end_and_append_block(irb, alloc_err_block); | 5893 | ir_set_cursor_at_end_and_append_block(irb, alloc_err_block); |
| 5872 | IrInstruction *err_val = ir_build_unwrap_err_code(irb, scope, node, alloc_result_ptr); | 5894 | IrInstruction *err_val = ir_build_unwrap_err_code(irb, scope, node, alloc_result_ptr); |
| 5873 | ir_build_return(irb, scope, node, err_val); | 5895 | ir_build_coro_alloc_fail(irb, scope, node, err_val); |
| 5874 | | 5896 | |
| 5875 | ir_set_cursor_at_end_and_append_block(irb, alloc_ok_block); | 5897 | ir_set_cursor_at_end_and_append_block(irb, alloc_ok_block); |
| 5876 | IrInstruction *unwrapped_mem_ptr = ir_build_unwrap_err_payload(irb, scope, node, alloc_result_ptr, false); | 5898 | IrInstruction *unwrapped_mem_ptr = ir_build_unwrap_err_payload(irb, scope, node, alloc_result_ptr, false); |
| ... | @@ -16826,18 +16848,47 @@ static TypeTableEntry *ir_analyze_instruction_coro_alloc(IrAnalyze *ira, IrInstr | ... | @@ -16826,18 +16848,47 @@ static TypeTableEntry *ir_analyze_instruction_coro_alloc(IrAnalyze *ira, IrInstr |
| 16826 | } | 16848 | } |
| 16827 | | 16849 | |
| 16828 | static TypeTableEntry *ir_analyze_instruction_coro_size(IrAnalyze *ira, IrInstructionCoroSize *instruction) { | 16850 | static TypeTableEntry *ir_analyze_instruction_coro_size(IrAnalyze *ira, IrInstructionCoroSize *instruction) { |
| 16829 | zig_panic("TODO ir_analyze_instruction_coro_size"); | 16851 | IrInstruction *result = ir_build_coro_size(&ira->new_irb, instruction->base.scope, instruction->base.source_node); |
| | 16852 | ir_link_new_instruction(result, &instruction->base); |
| | 16853 | result->value.type = ira->codegen->builtin_types.entry_usize; |
| | 16854 | return result->value.type; |
| 16830 | } | 16855 | } |
| 16831 | | 16856 | |
| 16832 | static TypeTableEntry *ir_analyze_instruction_coro_begin(IrAnalyze *ira, IrInstructionCoroBegin *instruction) { | 16857 | static TypeTableEntry *ir_analyze_instruction_coro_begin(IrAnalyze *ira, IrInstructionCoroBegin *instruction) { |
| 16833 | zig_panic("TODO ir_analyze_instruction_coro_begin"); | 16858 | IrInstruction *coro_id = instruction->coro_id->other; |
| | 16859 | if (type_is_invalid(coro_id->value.type)) |
| | 16860 | return ira->codegen->builtin_types.entry_invalid; |
| | 16861 | |
| | 16862 | IrInstruction *coro_mem_ptr = instruction->coro_mem_ptr->other; |
| | 16863 | if (type_is_invalid(coro_mem_ptr->value.type)) |
| | 16864 | return ira->codegen->builtin_types.entry_invalid; |
| | 16865 | |
| | 16866 | FnTableEntry *fn_entry = exec_fn_entry(ira->new_irb.exec); |
| | 16867 | assert(fn_entry != nullptr); |
| | 16868 | IrInstruction *result = ir_build_coro_begin(&ira->new_irb, instruction->base.scope, instruction->base.source_node, |
| | 16869 | coro_id, coro_mem_ptr); |
| | 16870 | ir_link_new_instruction(result, &instruction->base); |
| | 16871 | result->value.type = get_promise_type(ira->codegen, fn_entry->type_entry->data.fn.fn_type_id.return_type); |
| | 16872 | return result->value.type; |
| 16834 | } | 16873 | } |
| 16835 | | 16874 | |
| 16836 | static TypeTableEntry *ir_analyze_instruction_get_implicit_allocator(IrAnalyze *ira, IrInstructionGetImplicitAllocator *instruction) { | 16875 | static TypeTableEntry *ir_analyze_instruction_get_implicit_allocator(IrAnalyze *ira, IrInstructionGetImplicitAllocator *instruction) { |
| 16837 | IrInstruction *result = ir_get_implicit_allocator(ira, &instruction->base); | 16876 | IrInstruction *result = ir_get_implicit_allocator(ira, &instruction->base); |
| | 16877 | ir_link_new_instruction(result, &instruction->base); |
| 16838 | return result->value.type; | 16878 | return result->value.type; |
| 16839 | } | 16879 | } |
| 16840 | | 16880 | |
| | 16881 | static TypeTableEntry *ir_analyze_instruction_coro_alloc_fail(IrAnalyze *ira, IrInstructionCoroAllocFail *instruction) { |
| | 16882 | IrInstruction *err_val = instruction->err_val->other; |
| | 16883 | if (type_is_invalid(err_val->value.type)) |
| | 16884 | return ir_unreach_error(ira); |
| | 16885 | |
| | 16886 | IrInstruction *result = ir_build_coro_alloc_fail(&ira->new_irb, instruction->base.scope, instruction->base.source_node, err_val); |
| | 16887 | ir_link_new_instruction(result, &instruction->base); |
| | 16888 | result->value.type = ira->codegen->builtin_types.entry_unreachable; |
| | 16889 | return ir_finish_anal(ira, result->value.type); |
| | 16890 | } |
| | 16891 | |
| 16841 | static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) { | 16892 | static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) { |
| 16842 | switch (instruction->id) { | 16893 | switch (instruction->id) { |
| 16843 | case IrInstructionIdInvalid: | 16894 | case IrInstructionIdInvalid: |
| ... | @@ -17052,6 +17103,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi | ... | @@ -17052,6 +17103,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi |
| 17052 | return ir_analyze_instruction_coro_begin(ira, (IrInstructionCoroBegin *)instruction); | 17103 | return ir_analyze_instruction_coro_begin(ira, (IrInstructionCoroBegin *)instruction); |
| 17053 | case IrInstructionIdGetImplicitAllocator: | 17104 | case IrInstructionIdGetImplicitAllocator: |
| 17054 | return ir_analyze_instruction_get_implicit_allocator(ira, (IrInstructionGetImplicitAllocator *)instruction); | 17105 | return ir_analyze_instruction_get_implicit_allocator(ira, (IrInstructionGetImplicitAllocator *)instruction); |
| | 17106 | case IrInstructionIdCoroAllocFail: |
| | 17107 | return ir_analyze_instruction_coro_alloc_fail(ira, (IrInstructionCoroAllocFail *)instruction); |
| 17055 | } | 17108 | } |
| 17056 | zig_unreachable(); | 17109 | zig_unreachable(); |
| 17057 | } | 17110 | } |
| ... | @@ -17168,6 +17221,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -17168,6 +17221,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 17168 | case IrInstructionIdCancel: | 17221 | case IrInstructionIdCancel: |
| 17169 | case IrInstructionIdCoroId: | 17222 | case IrInstructionIdCoroId: |
| 17170 | case IrInstructionIdCoroBegin: | 17223 | case IrInstructionIdCoroBegin: |
| | 17224 | case IrInstructionIdCoroAllocFail: |
| 17171 | return true; | 17225 | return true; |
| 17172 | | 17226 | |
| 17173 | case IrInstructionIdPhi: | 17227 | case IrInstructionIdPhi: |