| ... | @@ -729,6 +729,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionMergeErrRetTrace | ... | @@ -729,6 +729,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionMergeErrRetTrace |
| 729 | return IrInstructionIdMergeErrRetTraces; | 729 | return IrInstructionIdMergeErrRetTraces; |
| 730 | } | 730 | } |
| 731 | | 731 | |
| | 732 | static constexpr IrInstructionId ir_instruction_id(IrInstructionMarkErrRetTracePtr *) { |
| | 733 | return IrInstructionIdMarkErrRetTracePtr; |
| | 734 | } |
| | 735 | |
| 732 | template<typename T> | 736 | template<typename T> |
| 733 | static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) { | 737 | static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) { |
| 734 | T *special_instruction = allocate<T>(1); | 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,31 +964,6 @@ static IrInstruction *ir_build_const_c_str_lit(IrBuilder *irb, Scope *scope, Ast |
| 960 | return &const_instruction->base; | 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 | static IrInstruction *ir_build_bin_op(IrBuilder *irb, Scope *scope, AstNode *source_node, IrBinOp op_id, | 967 | static IrInstruction *ir_build_bin_op(IrBuilder *irb, Scope *scope, AstNode *source_node, IrBinOp op_id, |
| 989 | IrInstruction *op1, IrInstruction *op2, bool safety_check_on) | 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,13 +2708,23 @@ static IrInstruction *ir_build_add_implicit_return_type(IrBuilder *irb, Scope *s |
| 2729 | } | 2708 | } |
| 2730 | | 2709 | |
| 2731 | static IrInstruction *ir_build_merge_err_ret_traces(IrBuilder *irb, Scope *scope, AstNode *source_node, | 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 | IrInstructionMergeErrRetTraces *instruction = ir_build_instruction<IrInstructionMergeErrRetTraces>(irb, scope, source_node); | 2713 | IrInstructionMergeErrRetTraces *instruction = ir_build_instruction<IrInstructionMergeErrRetTraces>(irb, scope, source_node); |
| 2735 | instruction->coro_promise_ptr = coro_promise_ptr; | 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 | ir_ref_instruction(coro_promise_ptr, irb->current_basic_block); | 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 | return &instruction->base; | 2729 | return &instruction->base; |
| 2741 | } | 2730 | } |
| ... | @@ -6154,7 +6143,9 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *parent_scope, Ast | ... | @@ -6154,7 +6143,9 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *parent_scope, Ast |
| 6154 | | 6143 | |
| 6155 | ir_set_cursor_at_end_and_append_block(irb, no_suspend_block); | 6144 | ir_set_cursor_at_end_and_append_block(irb, no_suspend_block); |
| 6156 | if (irb->codegen->have_err_ret_tracing) { | 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 | Buf *result_field_name = buf_create_from_str(RESULT_FIELD_NAME); | 6150 | Buf *result_field_name = buf_create_from_str(RESULT_FIELD_NAME); |
| 6160 | IrInstruction *promise_result_ptr = ir_build_field_ptr(irb, parent_scope, node, coro_promise_ptr, result_field_name); | 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,8 +6412,11 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 6421 | VariableTableEntry *promise_var = ir_create_var(irb, node, coro_scope, nullptr, false, false, true, const_bool_false); | 6412 | VariableTableEntry *promise_var = ir_create_var(irb, node, coro_scope, nullptr, false, false, true, const_bool_false); |
| 6422 | | 6413 | |
| 6423 | return_type = fn_entry->type_entry->data.fn.fn_type_id.return_type; | 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); | 6415 | IrInstruction *undef = ir_build_const_undefined(irb, coro_scope, node); |
| 6425 | ir_build_var_decl(irb, coro_scope, node, promise_var, nullptr, nullptr, promise_init); | 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 | IrInstruction *coro_promise_ptr = ir_build_var_ptr(irb, coro_scope, node, promise_var, false, false); | 6420 | IrInstruction *coro_promise_ptr = ir_build_var_ptr(irb, coro_scope, node, promise_var, false, false); |
| 6427 | | 6421 | |
| 6428 | VariableTableEntry *await_handle_var = ir_create_var(irb, node, coro_scope, nullptr, false, false, true, const_bool_false); | 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,7 +6450,6 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 6456 | ir_set_cursor_at_end_and_append_block(irb, alloc_err_block); | 6450 | ir_set_cursor_at_end_and_append_block(irb, alloc_err_block); |
| 6457 | // we can return undefined here, because the caller passes a pointer to the error struct field | 6451 | // we can return undefined here, because the caller passes a pointer to the error struct field |
| 6458 | // in the error union result, and we populate it in case of allocation failure. | 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 | ir_build_return(irb, coro_scope, node, undef); | 6453 | ir_build_return(irb, coro_scope, node, undef); |
| 6461 | | 6454 | |
| 6462 | ir_set_cursor_at_end_and_append_block(irb, alloc_ok_block); | 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,16 +6459,32 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 6466 | Buf *awaiter_handle_field_name = buf_create_from_str(AWAITER_HANDLE_FIELD_NAME); | 6459 | Buf *awaiter_handle_field_name = buf_create_from_str(AWAITER_HANDLE_FIELD_NAME); |
| 6467 | irb->exec->coro_awaiter_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, | 6460 | irb->exec->coro_awaiter_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, |
| 6468 | awaiter_handle_field_name); | 6461 | awaiter_handle_field_name); |
| | 6462 | ir_build_store_ptr(irb, scope, node, irb->exec->coro_awaiter_field_ptr, null_value); |
| 6469 | Buf *result_field_name = buf_create_from_str(RESULT_FIELD_NAME); | 6463 | Buf *result_field_name = buf_create_from_str(RESULT_FIELD_NAME); |
| 6470 | irb->exec->coro_result_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_field_name); | 6464 | irb->exec->coro_result_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_field_name); |
| 6471 | result_ptr_field_name = buf_create_from_str(RESULT_PTR_FIELD_NAME); | 6465 | result_ptr_field_name = buf_create_from_str(RESULT_PTR_FIELD_NAME); |
| 6472 | irb->exec->coro_result_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_ptr_field_name); | 6466 | irb->exec->coro_result_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_ptr_field_name); |
| 6473 | ir_build_store_ptr(irb, scope, node, irb->exec->coro_result_ptr_field_ptr, irb->exec->coro_result_field_ptr); | 6467 | ir_build_store_ptr(irb, scope, node, irb->exec->coro_result_ptr_field_ptr, irb->exec->coro_result_field_ptr); |
| 6474 | if (irb->codegen->have_err_ret_tracing) { | 6468 | if (irb->codegen->have_err_ret_tracing) { |
| 6475 | IrInstruction *err_ret_trace_ptr = ir_build_error_return_trace(irb, scope, node, IrInstructionErrorReturnTrace::NonNull); | 6469 | // initialize the error return trace |
| 6476 | Buf *err_ret_trace_ptr_field_name = buf_create_from_str(ERR_RET_TRACE_PTR_FIELD_NAME); | 6470 | Buf *return_addresses_field_name = buf_create_from_str(RETURN_ADDRESSES_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); | 6471 | IrInstruction *return_addresses_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, return_addresses_field_name); |
| 6478 | ir_build_store_ptr(irb, scope, node, coro_err_ret_trace_ptr_field_ptr, err_ret_trace_ptr); | 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,11 +17948,12 @@ static TypeTableEntry *ir_analyze_instruction_merge_err_ret_traces(IrAnalyze *ir |
| 17939 | return out_val->type; | 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)); | 17951 | IrInstruction *err_ret_trace_ptr = instruction->err_ret_trace_ptr->other; |
| 17943 | assert(field != nullptr); | 17952 | if (type_is_invalid(err_ret_trace_ptr->value.type)) |
| | 17953 | return ira->codegen->builtin_types.entry_invalid; |
| 17944 | | 17954 | |
| 17945 | IrInstruction *result = ir_build_merge_err_ret_traces(&ira->new_irb, instruction->base.scope, | 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 | ir_link_new_instruction(result, &instruction->base); | 17957 | ir_link_new_instruction(result, &instruction->base); |
| 17948 | result->value.type = ira->codegen->builtin_types.entry_void; | 17958 | result->value.type = ira->codegen->builtin_types.entry_void; |
| 17949 | return result->value.type; | 17959 | return result->value.type; |
| ... | @@ -17957,6 +17967,18 @@ static TypeTableEntry *ir_analyze_instruction_save_err_ret_addr(IrAnalyze *ira, | ... | @@ -17957,6 +17967,18 @@ static TypeTableEntry *ir_analyze_instruction_save_err_ret_addr(IrAnalyze *ira, |
| 17957 | return result->value.type; | 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 | static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) { | 17982 | static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) { |
| 17961 | switch (instruction->id) { | 17983 | switch (instruction->id) { |
| 17962 | case IrInstructionIdInvalid: | 17984 | case IrInstructionIdInvalid: |
| ... | @@ -18202,6 +18224,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi | ... | @@ -18202,6 +18224,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi |
| 18202 | return ir_analyze_instruction_add_implicit_return_type(ira, (IrInstructionAddImplicitReturnType *)instruction); | 18224 | return ir_analyze_instruction_add_implicit_return_type(ira, (IrInstructionAddImplicitReturnType *)instruction); |
| 18203 | case IrInstructionIdMergeErrRetTraces: | 18225 | case IrInstructionIdMergeErrRetTraces: |
| 18204 | return ir_analyze_instruction_merge_err_ret_traces(ira, (IrInstructionMergeErrRetTraces *)instruction); | 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 | zig_unreachable(); | 18230 | zig_unreachable(); |
| 18207 | } | 18231 | } |
| ... | @@ -18330,6 +18354,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -18330,6 +18354,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 18330 | case IrInstructionIdSaveErrRetAddr: | 18354 | case IrInstructionIdSaveErrRetAddr: |
| 18331 | case IrInstructionIdAddImplicitReturnType: | 18355 | case IrInstructionIdAddImplicitReturnType: |
| 18332 | case IrInstructionIdMergeErrRetTraces: | 18356 | case IrInstructionIdMergeErrRetTraces: |
| | 18357 | case IrInstructionIdMarkErrRetTracePtr: |
| 18333 | return true; | 18358 | return true; |
| 18334 | | 18359 | |
| 18335 | case IrInstructionIdPhi: | 18360 | case IrInstructionIdPhi: |