| ... | ... | @@ -729,6 +729,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionMergeErrRetTrace |
| 729 | 729 | return IrInstructionIdMergeErrRetTraces; |
| 730 | 730 | } |
| 731 | 731 | |
| 732 | static constexpr IrInstructionId ir_instruction_id(IrInstructionMarkErrRetTracePtr *) { |
| 733 | return IrInstructionIdMarkErrRetTracePtr; |
| 734 | } |
| 735 | |
| 732 | 736 | template<typename T> |
| 733 | 737 | static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) { |
| 734 | 738 | T *special_instruction = allocate<T>(1); |
| ... | ... | @@ -960,31 +964,6 @@ static IrInstruction *ir_build_const_c_str_lit(IrBuilder *irb, Scope *scope, Ast |
| 960 | 964 | return &const_instruction->base; |
| 961 | 965 | } |
| 962 | 966 | |
| 963 | | static IrInstruction *ir_build_const_promise_init(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 964 | | TypeTableEntry *return_type) |
| 965 | | { |
| 966 | | TypeTableEntry *struct_type = get_promise_frame_type(irb->codegen, return_type); |
| 967 | | |
| 968 | | IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); |
| 969 | | const_instruction->base.value.type = struct_type; |
| 970 | | const_instruction->base.value.special = ConstValSpecialStatic; |
| 971 | | const_instruction->base.value.data.x_struct.fields = allocate<ConstExprValue>(struct_type->data.structure.src_field_count); |
| 972 | | const_instruction->base.value.data.x_struct.fields[0].type = struct_type->data.structure.fields[0].type_entry; |
| 973 | | const_instruction->base.value.data.x_struct.fields[0].special = ConstValSpecialStatic; |
| 974 | | const_instruction->base.value.data.x_struct.fields[0].data.x_maybe = nullptr; |
| 975 | | const_instruction->base.value.data.x_struct.fields[1].type = return_type; |
| 976 | | const_instruction->base.value.data.x_struct.fields[1].special = ConstValSpecialUndef; |
| 977 | | const_instruction->base.value.data.x_struct.fields[2].type = struct_type->data.structure.fields[2].type_entry; |
| 978 | | const_instruction->base.value.data.x_struct.fields[2].special = ConstValSpecialUndef; |
| 979 | | if (irb->codegen->have_err_ret_tracing) { |
| 980 | | assert(struct_type->data.structure.src_field_count == 4); |
| 981 | | |
| 982 | | const_instruction->base.value.data.x_struct.fields[3].type = struct_type->data.structure.fields[3].type_entry; |
| 983 | | const_instruction->base.value.data.x_struct.fields[3].special = ConstValSpecialUndef; |
| 984 | | } |
| 985 | | return &const_instruction->base; |
| 986 | | } |
| 987 | | |
| 988 | 967 | static IrInstruction *ir_build_bin_op(IrBuilder *irb, Scope *scope, AstNode *source_node, IrBinOp op_id, |
| 989 | 968 | IrInstruction *op1, IrInstruction *op2, bool safety_check_on) |
| 990 | 969 | { |
| ... | ... | @@ -2729,13 +2708,23 @@ static IrInstruction *ir_build_add_implicit_return_type(IrBuilder *irb, Scope *s |
| 2729 | 2708 | } |
| 2730 | 2709 | |
| 2731 | 2710 | static IrInstruction *ir_build_merge_err_ret_traces(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 2732 | | IrInstruction *coro_promise_ptr, TypeStructField *resolved_field) |
| 2711 | IrInstruction *coro_promise_ptr, IrInstruction *err_ret_trace_ptr) |
| 2733 | 2712 | { |
| 2734 | 2713 | IrInstructionMergeErrRetTraces *instruction = ir_build_instruction<IrInstructionMergeErrRetTraces>(irb, scope, source_node); |
| 2735 | 2714 | instruction->coro_promise_ptr = coro_promise_ptr; |
| 2736 | | instruction->resolved_field = resolved_field; |
| 2715 | instruction->err_ret_trace_ptr = err_ret_trace_ptr; |
| 2737 | 2716 | |
| 2738 | 2717 | ir_ref_instruction(coro_promise_ptr, irb->current_basic_block); |
| 2718 | ir_ref_instruction(err_ret_trace_ptr, irb->current_basic_block); |
| 2719 | |
| 2720 | return &instruction->base; |
| 2721 | } |
| 2722 | |
| 2723 | static IrInstruction *ir_build_mark_err_ret_trace_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *err_ret_trace_ptr) { |
| 2724 | IrInstructionMarkErrRetTracePtr *instruction = ir_build_instruction<IrInstructionMarkErrRetTracePtr>(irb, scope, source_node); |
| 2725 | instruction->err_ret_trace_ptr = err_ret_trace_ptr; |
| 2726 | |
| 2727 | ir_ref_instruction(err_ret_trace_ptr, irb->current_basic_block); |
| 2739 | 2728 | |
| 2740 | 2729 | return &instruction->base; |
| 2741 | 2730 | } |
| ... | ... | @@ -6154,7 +6143,9 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *parent_scope, Ast |
| 6154 | 6143 | |
| 6155 | 6144 | ir_set_cursor_at_end_and_append_block(irb, no_suspend_block); |
| 6156 | 6145 | if (irb->codegen->have_err_ret_tracing) { |
| 6157 | | ir_build_merge_err_ret_traces(irb, parent_scope, node, coro_promise_ptr, nullptr); |
| 6146 | Buf *err_ret_trace_field_name = buf_create_from_str(ERR_RET_TRACE_FIELD_NAME); |
| 6147 | IrInstruction *err_ret_trace_ptr = ir_build_field_ptr(irb, parent_scope, node, coro_promise_ptr, err_ret_trace_field_name); |
| 6148 | ir_build_merge_err_ret_traces(irb, parent_scope, node, coro_promise_ptr, err_ret_trace_ptr); |
| 6158 | 6149 | } |
| 6159 | 6150 | Buf *result_field_name = buf_create_from_str(RESULT_FIELD_NAME); |
| 6160 | 6151 | IrInstruction *promise_result_ptr = ir_build_field_ptr(irb, parent_scope, node, coro_promise_ptr, result_field_name); |
| ... | ... | @@ -6421,8 +6412,11 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 6421 | 6412 | VariableTableEntry *promise_var = ir_create_var(irb, node, coro_scope, nullptr, false, false, true, const_bool_false); |
| 6422 | 6413 | |
| 6423 | 6414 | return_type = fn_entry->type_entry->data.fn.fn_type_id.return_type; |
| 6424 | | IrInstruction *promise_init = ir_build_const_promise_init(irb, coro_scope, node, return_type); |
| 6425 | | ir_build_var_decl(irb, coro_scope, node, promise_var, nullptr, nullptr, promise_init); |
| 6415 | IrInstruction *undef = ir_build_const_undefined(irb, coro_scope, node); |
| 6416 | TypeTableEntry *coro_frame_type = get_promise_frame_type(irb->codegen, return_type); |
| 6417 | IrInstruction *coro_frame_type_value = ir_build_const_type(irb, coro_scope, node, coro_frame_type); |
| 6418 | // TODO mark this var decl as "no safety" e.g. disable initializing the undef value to 0xaa |
| 6419 | ir_build_var_decl(irb, coro_scope, node, promise_var, coro_frame_type_value, nullptr, undef); |
| 6426 | 6420 | IrInstruction *coro_promise_ptr = ir_build_var_ptr(irb, coro_scope, node, promise_var, false, false); |
| 6427 | 6421 | |
| 6428 | 6422 | VariableTableEntry *await_handle_var = ir_create_var(irb, node, coro_scope, nullptr, false, false, true, const_bool_false); |
| ... | ... | @@ -6456,7 +6450,6 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 6456 | 6450 | ir_set_cursor_at_end_and_append_block(irb, alloc_err_block); |
| 6457 | 6451 | // we can return undefined here, because the caller passes a pointer to the error struct field |
| 6458 | 6452 | // in the error union result, and we populate it in case of allocation failure. |
| 6459 | | IrInstruction *undef = ir_build_const_undefined(irb, coro_scope, node); |
| 6460 | 6453 | ir_build_return(irb, coro_scope, node, undef); |
| 6461 | 6454 | |
| 6462 | 6455 | ir_set_cursor_at_end_and_append_block(irb, alloc_ok_block); |
| ... | ... | @@ -6466,16 +6459,32 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 6466 | 6459 | Buf *awaiter_handle_field_name = buf_create_from_str(AWAITER_HANDLE_FIELD_NAME); |
| 6467 | 6460 | irb->exec->coro_awaiter_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, |
| 6468 | 6461 | awaiter_handle_field_name); |
| 6462 | ir_build_store_ptr(irb, scope, node, irb->exec->coro_awaiter_field_ptr, null_value); |
| 6469 | 6463 | Buf *result_field_name = buf_create_from_str(RESULT_FIELD_NAME); |
| 6470 | 6464 | irb->exec->coro_result_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_field_name); |
| 6471 | 6465 | result_ptr_field_name = buf_create_from_str(RESULT_PTR_FIELD_NAME); |
| 6472 | 6466 | irb->exec->coro_result_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_ptr_field_name); |
| 6473 | 6467 | ir_build_store_ptr(irb, scope, node, irb->exec->coro_result_ptr_field_ptr, irb->exec->coro_result_field_ptr); |
| 6474 | 6468 | if (irb->codegen->have_err_ret_tracing) { |
| 6475 | | IrInstruction *err_ret_trace_ptr = ir_build_error_return_trace(irb, scope, node, IrInstructionErrorReturnTrace::NonNull); |
| 6476 | | Buf *err_ret_trace_ptr_field_name = buf_create_from_str(ERR_RET_TRACE_PTR_FIELD_NAME); |
| 6477 | | IrInstruction *coro_err_ret_trace_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_ptr_field_name); |
| 6478 | | ir_build_store_ptr(irb, scope, node, coro_err_ret_trace_ptr_field_ptr, err_ret_trace_ptr); |
| 6469 | // initialize the error return trace |
| 6470 | Buf *return_addresses_field_name = buf_create_from_str(RETURN_ADDRESSES_FIELD_NAME); |
| 6471 | IrInstruction *return_addresses_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, return_addresses_field_name); |
| 6472 | |
| 6473 | Buf *err_ret_trace_field_name = buf_create_from_str(ERR_RET_TRACE_FIELD_NAME); |
| 6474 | IrInstruction *err_ret_trace_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_field_name); |
| 6475 | ir_build_mark_err_ret_trace_ptr(irb, scope, node, err_ret_trace_ptr); |
| 6476 | |
| 6477 | // coordinate with builtin.zig |
| 6478 | Buf *index_name = buf_create_from_str("index"); |
| 6479 | IrInstruction *index_ptr = ir_build_field_ptr(irb, scope, node, err_ret_trace_ptr, index_name); |
| 6480 | IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); |
| 6481 | ir_build_store_ptr(irb, scope, node, index_ptr, zero); |
| 6482 | |
| 6483 | Buf *instruction_addresses_name = buf_create_from_str("instruction_addresses"); |
| 6484 | IrInstruction *addrs_slice_ptr = ir_build_field_ptr(irb, scope, node, err_ret_trace_ptr, instruction_addresses_name); |
| 6485 | |
| 6486 | IrInstruction *slice_value = ir_build_slice(irb, scope, node, return_addresses_ptr, zero, nullptr, false); |
| 6487 | ir_build_store_ptr(irb, scope, node, addrs_slice_ptr, slice_value); |
| 6479 | 6488 | } |
| 6480 | 6489 | |
| 6481 | 6490 | |
| ... | ... | @@ -17939,11 +17948,12 @@ static TypeTableEntry *ir_analyze_instruction_merge_err_ret_traces(IrAnalyze *ir |
| 17939 | 17948 | return out_val->type; |
| 17940 | 17949 | } |
| 17941 | 17950 | |
| 17942 | | TypeStructField *field = find_struct_type_field(promise_frame_type, buf_create_from_str(ERR_RET_TRACE_PTR_FIELD_NAME)); |
| 17943 | | assert(field != nullptr); |
| 17951 | IrInstruction *err_ret_trace_ptr = instruction->err_ret_trace_ptr->other; |
| 17952 | if (type_is_invalid(err_ret_trace_ptr->value.type)) |
| 17953 | return ira->codegen->builtin_types.entry_invalid; |
| 17944 | 17954 | |
| 17945 | 17955 | IrInstruction *result = ir_build_merge_err_ret_traces(&ira->new_irb, instruction->base.scope, |
| 17946 | | instruction->base.source_node, coro_promise_ptr, field); |
| 17956 | instruction->base.source_node, coro_promise_ptr, err_ret_trace_ptr); |
| 17947 | 17957 | ir_link_new_instruction(result, &instruction->base); |
| 17948 | 17958 | result->value.type = ira->codegen->builtin_types.entry_void; |
| 17949 | 17959 | return result->value.type; |
| ... | ... | @@ -17957,6 +17967,18 @@ static TypeTableEntry *ir_analyze_instruction_save_err_ret_addr(IrAnalyze *ira, |
| 17957 | 17967 | return result->value.type; |
| 17958 | 17968 | } |
| 17959 | 17969 | |
| 17970 | static TypeTableEntry *ir_analyze_instruction_mark_err_ret_trace_ptr(IrAnalyze *ira, IrInstructionMarkErrRetTracePtr *instruction) { |
| 17971 | IrInstruction *err_ret_trace_ptr = instruction->err_ret_trace_ptr->other; |
| 17972 | if (type_is_invalid(err_ret_trace_ptr->value.type)) |
| 17973 | return ira->codegen->builtin_types.entry_invalid; |
| 17974 | |
| 17975 | IrInstruction *result = ir_build_mark_err_ret_trace_ptr(&ira->new_irb, instruction->base.scope, |
| 17976 | instruction->base.source_node, err_ret_trace_ptr); |
| 17977 | ir_link_new_instruction(result, &instruction->base); |
| 17978 | result->value.type = ira->codegen->builtin_types.entry_void; |
| 17979 | return result->value.type; |
| 17980 | } |
| 17981 | |
| 17960 | 17982 | static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) { |
| 17961 | 17983 | switch (instruction->id) { |
| 17962 | 17984 | case IrInstructionIdInvalid: |
| ... | ... | @@ -18202,6 +18224,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi |
| 18202 | 18224 | return ir_analyze_instruction_add_implicit_return_type(ira, (IrInstructionAddImplicitReturnType *)instruction); |
| 18203 | 18225 | case IrInstructionIdMergeErrRetTraces: |
| 18204 | 18226 | return ir_analyze_instruction_merge_err_ret_traces(ira, (IrInstructionMergeErrRetTraces *)instruction); |
| 18227 | case IrInstructionIdMarkErrRetTracePtr: |
| 18228 | return ir_analyze_instruction_mark_err_ret_trace_ptr(ira, (IrInstructionMarkErrRetTracePtr *)instruction); |
| 18205 | 18229 | } |
| 18206 | 18230 | zig_unreachable(); |
| 18207 | 18231 | } |
| ... | ... | @@ -18330,6 +18354,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 18330 | 18354 | case IrInstructionIdSaveErrRetAddr: |
| 18331 | 18355 | case IrInstructionIdAddImplicitReturnType: |
| 18332 | 18356 | case IrInstructionIdMergeErrRetTraces: |
| 18357 | case IrInstructionIdMarkErrRetTracePtr: |
| 18333 | 18358 | return true; |
| 18334 | 18359 | |
| 18335 | 18360 | case IrInstructionIdPhi: |