authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-04-08 16:04:21-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-04-08 16:04:48-04:00
logada441157f4a388950946e7f4db65c273f23c063
tree88883742e7a7a96ca60eea7cbed7541071e7507d
parente4083b7391fd829e3060d24e10d13c8d52d889b0

put the error return addresses in the coro frame


5 files changed, 105 insertions(+), 61 deletions(-)

src/all_types.hpp+10-2
...@@ -2057,6 +2057,7 @@ enum IrInstructionId {...@@ -2057,6 +2057,7 @@ enum IrInstructionId {
2057 IrInstructionIdSaveErrRetAddr,2057 IrInstructionIdSaveErrRetAddr,
2058 IrInstructionIdAddImplicitReturnType,2058 IrInstructionIdAddImplicitReturnType,
2059 IrInstructionIdMergeErrRetTraces,2059 IrInstructionIdMergeErrRetTraces,
2060 IrInstructionIdMarkErrRetTracePtr,
2060};2061};
20612062
2062struct IrInstruction {2063struct IrInstruction {
...@@ -3036,7 +3037,13 @@ struct IrInstructionMergeErrRetTraces {...@@ -3036,7 +3037,13 @@ struct IrInstructionMergeErrRetTraces {
3036 IrInstruction base;3037 IrInstruction base;
30373038
3038 IrInstruction *coro_promise_ptr;3039 IrInstruction *coro_promise_ptr;
3039 TypeStructField *resolved_field;3040 IrInstruction *err_ret_trace_ptr;
3041};
3042
3043struct IrInstructionMarkErrRetTracePtr {
3044 IrInstruction base;
3045
3046 IrInstruction *err_ret_trace_ptr;
3040};3047};
30413048
3042static const size_t slice_ptr_index = 0;3049static const size_t slice_ptr_index = 0;
...@@ -3056,7 +3063,8 @@ static const size_t stack_trace_ptr_count = 30;...@@ -3056,7 +3063,8 @@ static const size_t stack_trace_ptr_count = 30;
3056#define AWAITER_HANDLE_FIELD_NAME "awaiter_handle"3063#define AWAITER_HANDLE_FIELD_NAME "awaiter_handle"
3057#define RESULT_FIELD_NAME "result"3064#define RESULT_FIELD_NAME "result"
3058#define RESULT_PTR_FIELD_NAME "result_ptr"3065#define RESULT_PTR_FIELD_NAME "result_ptr"
3059#define ERR_RET_TRACE_PTR_FIELD_NAME "err_ret_trace_ptr"3066#define RETURN_ADDRESSES_FIELD_NAME "return_addresses"
3067#define ERR_RET_TRACE_FIELD_NAME "err_ret_trace"
30603068
30613069
3062enum FloatMode {3070enum FloatMode {
src/analyze.cpp+5-2
...@@ -474,7 +474,8 @@ TypeTableEntry *get_promise_frame_type(CodeGen *g, TypeTableEntry *return_type)...@@ -474,7 +474,8 @@ TypeTableEntry *get_promise_frame_type(CodeGen *g, TypeTableEntry *return_type)
474 field_names.append(RESULT_FIELD_NAME);474 field_names.append(RESULT_FIELD_NAME);
475 field_names.append(RESULT_PTR_FIELD_NAME);475 field_names.append(RESULT_PTR_FIELD_NAME);
476 if (g->have_err_ret_tracing) {476 if (g->have_err_ret_tracing) {
477 field_names.append(ERR_RET_TRACE_PTR_FIELD_NAME);477 field_names.append(ERR_RET_TRACE_FIELD_NAME);
478 field_names.append(RETURN_ADDRESSES_FIELD_NAME);
478 }479 }
479480
480 ZigList<TypeTableEntry *> field_types = {};481 ZigList<TypeTableEntry *> field_types = {};
...@@ -482,7 +483,9 @@ TypeTableEntry *get_promise_frame_type(CodeGen *g, TypeTableEntry *return_type)...@@ -482,7 +483,9 @@ TypeTableEntry *get_promise_frame_type(CodeGen *g, TypeTableEntry *return_type)
482 field_types.append(return_type);483 field_types.append(return_type);
483 field_types.append(result_ptr_type);484 field_types.append(result_ptr_type);
484 if (g->have_err_ret_tracing) {485 if (g->have_err_ret_tracing) {
485 field_types.append(get_ptr_to_stack_trace_type(g));486 get_ptr_to_stack_trace_type(g);
487 field_types.append(g->stack_trace_type);
488 field_types.append(get_array_type(g, g->builtin_types.entry_usize, stack_trace_ptr_count));
486 }489 }
487490
488 assert(field_names.length == field_types.length);491 assert(field_names.length == field_types.length);
src/codegen.cpp+17-16
...@@ -4383,10 +4383,7 @@ static LLVMValueRef ir_render_merge_err_ret_traces(CodeGen *g, IrExecutable *exe...@@ -4383,10 +4383,7 @@ static LLVMValueRef ir_render_merge_err_ret_traces(CodeGen *g, IrExecutable *exe
4383{4383{
4384 assert(g->have_err_ret_tracing);4384 assert(g->have_err_ret_tracing);
43854385
4386 LLVMValueRef coro_promise_ptr = ir_llvm_value(g, instruction->coro_promise_ptr);4386 LLVMValueRef src_trace_ptr = ir_llvm_value(g, instruction->err_ret_trace_ptr);
4387 TypeStructField *field = instruction->resolved_field;
4388 LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, coro_promise_ptr, field->gen_index, "");
4389 LLVMValueRef src_trace_ptr = LLVMBuildLoad(g->builder, ptr_field_ptr, "");
4390 LLVMValueRef dest_trace_ptr = get_cur_err_ret_trace_val(g, instruction->base.scope);4387 LLVMValueRef dest_trace_ptr = get_cur_err_ret_trace_val(g, instruction->base.scope);
43914388
4392 LLVMValueRef args[] = { dest_trace_ptr, src_trace_ptr };4389 LLVMValueRef args[] = { dest_trace_ptr, src_trace_ptr };
...@@ -4394,6 +4391,14 @@ static LLVMValueRef ir_render_merge_err_ret_traces(CodeGen *g, IrExecutable *exe...@@ -4394,6 +4391,14 @@ static LLVMValueRef ir_render_merge_err_ret_traces(CodeGen *g, IrExecutable *exe
4394 return nullptr;4391 return nullptr;
4395}4392}
43964393
4394static LLVMValueRef ir_render_mark_err_ret_trace_ptr(CodeGen *g, IrExecutable *executable,
4395 IrInstructionMarkErrRetTracePtr *instruction)
4396{
4397 assert(g->have_err_ret_tracing);
4398 g->cur_err_ret_trace_val_stack = ir_llvm_value(g, instruction->err_ret_trace_ptr);
4399 return nullptr;
4400}
4401
4397static void set_debug_location(CodeGen *g, IrInstruction *instruction) {4402static void set_debug_location(CodeGen *g, IrInstruction *instruction) {
4398 AstNode *source_node = instruction->source_node;4403 AstNode *source_node = instruction->source_node;
4399 Scope *scope = instruction->scope;4404 Scope *scope = instruction->scope;
...@@ -4613,6 +4618,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,...@@ -4613,6 +4618,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
4613 return ir_render_save_err_ret_addr(g, executable, (IrInstructionSaveErrRetAddr *)instruction);4618 return ir_render_save_err_ret_addr(g, executable, (IrInstructionSaveErrRetAddr *)instruction);
4614 case IrInstructionIdMergeErrRetTraces:4619 case IrInstructionIdMergeErrRetTraces:
4615 return ir_render_merge_err_ret_traces(g, executable, (IrInstructionMergeErrRetTraces *)instruction);4620 return ir_render_merge_err_ret_traces(g, executable, (IrInstructionMergeErrRetTraces *)instruction);
4621 case IrInstructionIdMarkErrRetTracePtr:
4622 return ir_render_mark_err_ret_trace_ptr(g, executable, (IrInstructionMarkErrRetTracePtr *)instruction);
4616 }4623 }
4617 zig_unreachable();4624 zig_unreachable();
4618}4625}
...@@ -5504,16 +5511,11 @@ static void do_code_gen(CodeGen *g) {...@@ -5504,16 +5511,11 @@ static void do_code_gen(CodeGen *g) {
55045511
5505 // error return tracing setup5512 // error return tracing setup
5506 bool is_async = fn_table_entry->type_entry->data.fn.fn_type_id.cc == CallingConventionAsync;5513 bool is_async = fn_table_entry->type_entry->data.fn.fn_type_id.cc == CallingConventionAsync;
5507 bool have_err_ret_trace_stack = g->have_err_ret_tracing && fn_table_entry->calls_or_awaits_errorable_fn &&5514 bool have_err_ret_trace_stack = g->have_err_ret_tracing && fn_table_entry->calls_or_awaits_errorable_fn && !is_async && !have_err_ret_trace_arg;
5508 (is_async || !have_err_ret_trace_arg);
5509 bool have_exactly_one_err_ret_value = !have_err_ret_trace_stack && g->have_err_ret_tracing && is_async &&
5510 type_can_fail(fn_table_entry->type_entry->data.fn.fn_type_id.return_type);
5511 LLVMValueRef err_ret_array_val = nullptr;5515 LLVMValueRef err_ret_array_val = nullptr;
5512 if (have_err_ret_trace_stack || have_exactly_one_err_ret_value) {5516 if (have_err_ret_trace_stack) {
5513 uint32_t ret_addr_count = have_exactly_one_err_ret_value ? 1 : stack_trace_ptr_count;5517 TypeTableEntry *array_type = get_array_type(g, g->builtin_types.entry_usize, stack_trace_ptr_count);
5514 TypeTableEntry *array_type = get_array_type(g, g->builtin_types.entry_usize, ret_addr_count);5518 err_ret_array_val = build_alloca(g, array_type, "error_return_trace_addresses", get_abi_alignment(g, array_type));
5515 err_ret_array_val = build_alloca(g, array_type, "error_return_trace_addresses",
5516 get_abi_alignment(g, array_type));
5517 g->cur_err_ret_trace_val_stack = build_alloca(g, g->stack_trace_type, "error_return_trace", get_abi_alignment(g, g->stack_trace_type));5519 g->cur_err_ret_trace_val_stack = build_alloca(g, g->stack_trace_type, "error_return_trace", get_abi_alignment(g, g->stack_trace_type));
5518 } else {5520 } else {
5519 g->cur_err_ret_trace_val_stack = nullptr;5521 g->cur_err_ret_trace_val_stack = nullptr;
...@@ -5610,8 +5612,7 @@ static void do_code_gen(CodeGen *g) {...@@ -5610,8 +5612,7 @@ static void do_code_gen(CodeGen *g) {
5610 }5612 }
56115613
5612 // finishing error return trace setup. we have to do this after all the allocas.5614 // finishing error return trace setup. we have to do this after all the allocas.
5613 if (have_err_ret_trace_stack || have_exactly_one_err_ret_value) {5615 if (have_err_ret_trace_stack) {
5614 uint32_t ret_addr_count = have_exactly_one_err_ret_value ? 1 : stack_trace_ptr_count;
5615 TypeTableEntry *usize = g->builtin_types.entry_usize;5616 TypeTableEntry *usize = g->builtin_types.entry_usize;
5616 size_t index_field_index = g->stack_trace_type->data.structure.fields[0].gen_index;5617 size_t index_field_index = g->stack_trace_type->data.structure.fields[0].gen_index;
5617 LLVMValueRef index_field_ptr = LLVMBuildStructGEP(g->builder, g->cur_err_ret_trace_val_stack, (unsigned)index_field_index, "");5618 LLVMValueRef index_field_ptr = LLVMBuildStructGEP(g->builder, g->cur_err_ret_trace_val_stack, (unsigned)index_field_index, "");
...@@ -5632,7 +5633,7 @@ static void do_code_gen(CodeGen *g) {...@@ -5632,7 +5633,7 @@ static void do_code_gen(CodeGen *g) {
56325633
5633 size_t len_field_index = slice_type->data.structure.fields[slice_len_index].gen_index;5634 size_t len_field_index = slice_type->data.structure.fields[slice_len_index].gen_index;
5634 LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, addresses_field_ptr, (unsigned)len_field_index, "");5635 LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, addresses_field_ptr, (unsigned)len_field_index, "");
5635 gen_store(g, LLVMConstInt(usize->type_ref, ret_addr_count, false), len_field_ptr, get_pointer_to_type(g, usize, false));5636 gen_store(g, LLVMConstInt(usize->type_ref, stack_trace_ptr_count, false), len_field_ptr, get_pointer_to_type(g, usize, false));
5636 }5637 }
56375638
5638 FnTypeId *fn_type_id = &fn_table_entry->type_entry->data.fn.fn_type_id;5639 FnTypeId *fn_type_id = &fn_table_entry->type_entry->data.fn.fn_type_id;
src/ir.cpp+63-38
...@@ -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}
731731
732static constexpr IrInstructionId ir_instruction_id(IrInstructionMarkErrRetTracePtr *) {
733 return IrInstructionIdMarkErrRetTracePtr;
734}
735
732template<typename T>736template<typename T>
733static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) {737static 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}
962966
963static 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
988static IrInstruction *ir_build_bin_op(IrBuilder *irb, Scope *scope, AstNode *source_node, IrBinOp op_id,967static 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}
27302709
2731static IrInstruction *ir_build_merge_err_ret_traces(IrBuilder *irb, Scope *scope, AstNode *source_node,2710static 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;
27372716
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
2723static 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);
27392728
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
61546143
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);
64226413
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);
64276421
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 field6451 // 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);
64616454
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 }
64806489
64816490
...@@ -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 }
1794117950
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;
1794417954
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}
1795917969
17970static 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
17960static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) {17982static 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;
1833418359
18335 case IrInstructionIdPhi:18360 case IrInstructionIdPhi:
src/ir_print.cpp+10-3
...@@ -1192,9 +1192,13 @@ static void ir_print_merge_err_ret_traces(IrPrint *irp, IrInstructionMergeErrRet...@@ -1192,9 +1192,13 @@ static void ir_print_merge_err_ret_traces(IrPrint *irp, IrInstructionMergeErrRet
1192 fprintf(irp->f, "@mergeErrRetTraces(");1192 fprintf(irp->f, "@mergeErrRetTraces(");
1193 ir_print_other_instruction(irp, instruction->coro_promise_ptr);1193 ir_print_other_instruction(irp, instruction->coro_promise_ptr);
1194 fprintf(irp->f, ",");1194 fprintf(irp->f, ",");
1195 if (instruction->resolved_field != nullptr) {1195 ir_print_other_instruction(irp, instruction->err_ret_trace_ptr);
1196 fprintf(irp->f, "field '%s'", buf_ptr(instruction->resolved_field->name));1196 fprintf(irp->f, ")");
1197 }1197}
1198
1199static void ir_print_mark_err_ret_trace_ptr(IrPrint *irp, IrInstructionMarkErrRetTracePtr *instruction) {
1200 fprintf(irp->f, "@markErrRetTracePtr(");
1201 ir_print_other_instruction(irp, instruction->err_ret_trace_ptr);
1198 fprintf(irp->f, ")");1202 fprintf(irp->f, ")");
1199}1203}
12001204
...@@ -1581,6 +1585,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {...@@ -1581,6 +1585,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
1581 case IrInstructionIdMergeErrRetTraces:1585 case IrInstructionIdMergeErrRetTraces:
1582 ir_print_merge_err_ret_traces(irp, (IrInstructionMergeErrRetTraces *)instruction);1586 ir_print_merge_err_ret_traces(irp, (IrInstructionMergeErrRetTraces *)instruction);
1583 break;1587 break;
1588 case IrInstructionIdMarkErrRetTracePtr:
1589 ir_print_mark_err_ret_trace_ptr(irp, (IrInstructionMarkErrRetTracePtr *)instruction);
1590 break;
1584 }1591 }
1585 fprintf(irp->f, "\n");1592 fprintf(irp->f, "\n");
1586}1593}