| ... | ... | @@ -5502,38 +5502,19 @@ static void do_code_gen(CodeGen *g) { |
| 5502 | 5502 | g->cur_err_ret_trace_val_arg = nullptr; |
| 5503 | 5503 | } |
| 5504 | 5504 | |
| 5505 | // error return tracing setup |
| 5505 | 5506 | bool is_async = fn_table_entry->type_entry->data.fn.fn_type_id.cc == CallingConventionAsync; |
| 5506 | 5507 | bool have_err_ret_trace_stack = g->have_err_ret_tracing && fn_table_entry->calls_or_awaits_errorable_fn && |
| 5507 | 5508 | (is_async || !have_err_ret_trace_arg); |
| 5508 | 5509 | bool have_exactly_one_err_ret_value = !have_err_ret_trace_stack && g->have_err_ret_tracing && is_async && |
| 5509 | 5510 | type_can_fail(fn_table_entry->type_entry->data.fn.fn_type_id.return_type); |
| 5511 | LLVMValueRef err_ret_array_val = nullptr; |
| 5510 | 5512 | if (have_err_ret_trace_stack || have_exactly_one_err_ret_value) { |
| 5511 | | TypeTableEntry *usize = g->builtin_types.entry_usize; |
| 5512 | 5513 | uint32_t ret_addr_count = have_exactly_one_err_ret_value ? 1 : stack_trace_ptr_count; |
| 5513 | | TypeTableEntry *array_type = get_array_type(g, usize, ret_addr_count); |
| 5514 | | LLVMValueRef err_ret_array_val = build_alloca(g, array_type, "error_return_trace_addresses", |
| 5514 | TypeTableEntry *array_type = get_array_type(g, g->builtin_types.entry_usize, ret_addr_count); |
| 5515 | err_ret_array_val = build_alloca(g, array_type, "error_return_trace_addresses", |
| 5515 | 5516 | get_abi_alignment(g, array_type)); |
| 5516 | 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)); |
| 5517 | | size_t index_field_index = g->stack_trace_type->data.structure.fields[0].gen_index; |
| 5518 | | LLVMValueRef index_field_ptr = LLVMBuildStructGEP(g->builder, g->cur_err_ret_trace_val_stack, (unsigned)index_field_index, ""); |
| 5519 | | gen_store_untyped(g, LLVMConstNull(usize->type_ref), index_field_ptr, 0, false); |
| 5520 | | |
| 5521 | | size_t addresses_field_index = g->stack_trace_type->data.structure.fields[1].gen_index; |
| 5522 | | LLVMValueRef addresses_field_ptr = LLVMBuildStructGEP(g->builder, g->cur_err_ret_trace_val_stack, (unsigned)addresses_field_index, ""); |
| 5523 | | |
| 5524 | | TypeTableEntry *slice_type = g->stack_trace_type->data.structure.fields[1].type_entry; |
| 5525 | | size_t ptr_field_index = slice_type->data.structure.fields[slice_ptr_index].gen_index; |
| 5526 | | LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, addresses_field_ptr, (unsigned)ptr_field_index, ""); |
| 5527 | | LLVMValueRef zero = LLVMConstNull(usize->type_ref); |
| 5528 | | LLVMValueRef indices[] = {zero, zero}; |
| 5529 | | LLVMValueRef err_ret_array_val_elem0_ptr = LLVMBuildInBoundsGEP(g->builder, err_ret_array_val, |
| 5530 | | indices, 2, ""); |
| 5531 | | gen_store(g, err_ret_array_val_elem0_ptr, ptr_field_ptr, |
| 5532 | | get_pointer_to_type(g, get_pointer_to_type(g, usize, false), false)); |
| 5533 | | |
| 5534 | | size_t len_field_index = slice_type->data.structure.fields[slice_len_index].gen_index; |
| 5535 | | LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, addresses_field_ptr, (unsigned)len_field_index, ""); |
| 5536 | | gen_store(g, LLVMConstInt(usize->type_ref, ret_addr_count, false), len_field_ptr, get_pointer_to_type(g, usize, false)); |
| 5537 | 5518 | } else { |
| 5538 | 5519 | g->cur_err_ret_trace_val_stack = nullptr; |
| 5539 | 5520 | } |
| ... | ... | @@ -5628,6 +5609,32 @@ static void do_code_gen(CodeGen *g) { |
| 5628 | 5609 | } |
| 5629 | 5610 | } |
| 5630 | 5611 | |
| 5612 | // 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) { |
| 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 | 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 | gen_store_untyped(g, LLVMConstNull(usize->type_ref), index_field_ptr, 0, false); |
| 5619 | |
| 5620 | size_t addresses_field_index = g->stack_trace_type->data.structure.fields[1].gen_index; |
| 5621 | LLVMValueRef addresses_field_ptr = LLVMBuildStructGEP(g->builder, g->cur_err_ret_trace_val_stack, (unsigned)addresses_field_index, ""); |
| 5622 | |
| 5623 | TypeTableEntry *slice_type = g->stack_trace_type->data.structure.fields[1].type_entry; |
| 5624 | size_t ptr_field_index = slice_type->data.structure.fields[slice_ptr_index].gen_index; |
| 5625 | LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, addresses_field_ptr, (unsigned)ptr_field_index, ""); |
| 5626 | LLVMValueRef zero = LLVMConstNull(usize->type_ref); |
| 5627 | LLVMValueRef indices[] = {zero, zero}; |
| 5628 | LLVMValueRef err_ret_array_val_elem0_ptr = LLVMBuildInBoundsGEP(g->builder, err_ret_array_val, |
| 5629 | indices, 2, ""); |
| 5630 | TypeTableEntry *ptr_ptr_usize_type = get_pointer_to_type(g, get_pointer_to_type(g, usize, false), false); |
| 5631 | gen_store(g, err_ret_array_val_elem0_ptr, ptr_field_ptr, ptr_ptr_usize_type); |
| 5632 | |
| 5633 | 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 | gen_store(g, LLVMConstInt(usize->type_ref, ret_addr_count, false), len_field_ptr, get_pointer_to_type(g, usize, false)); |
| 5636 | } |
| 5637 | |
| 5631 | 5638 | FnTypeId *fn_type_id = &fn_table_entry->type_entry->data.fn.fn_type_id; |
| 5632 | 5639 | |
| 5633 | 5640 | // create debug variable declarations for parameters |