| ... | @@ -22,8 +22,6 @@ | ... | @@ -22,8 +22,6 @@ |
| 22 | #include <stdio.h> | 22 | #include <stdio.h> |
| 23 | #include <errno.h> | 23 | #include <errno.h> |
| 24 | | 24 | |
| 25 | static const size_t stack_trace_ptr_count = 31; | | |
| 26 | | | |
| 27 | static void init_darwin_native(CodeGen *g) { | 25 | static void init_darwin_native(CodeGen *g) { |
| 28 | char *osx_target = getenv("MACOSX_DEPLOYMENT_TARGET"); | 26 | char *osx_target = getenv("MACOSX_DEPLOYMENT_TARGET"); |
| 29 | char *ios_target = getenv("IPHONEOS_DEPLOYMENT_TARGET"); | 27 | char *ios_target = getenv("IPHONEOS_DEPLOYMENT_TARGET"); |
| ... | @@ -958,7 +956,7 @@ static LLVMValueRef get_return_err_fn(CodeGen *g) { | ... | @@ -958,7 +956,7 @@ static LLVMValueRef get_return_err_fn(CodeGen *g) { |
| 958 | | 956 | |
| 959 | LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->type_ref; | 957 | LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->type_ref; |
| 960 | | 958 | |
| 961 | // stack_trace.instruction_addresses[stack_trace.index % stack_trace_ptr_count] = return_address; | 959 | // stack_trace.instruction_addresses[stack_trace.index % stack_trace.instruction_addresses.len] = return_address; |
| 962 | | 960 | |
| 963 | LLVMValueRef err_ret_trace_ptr = LLVMGetParam(fn_val, 0); | 961 | LLVMValueRef err_ret_trace_ptr = LLVMGetParam(fn_val, 0); |
| 964 | size_t index_field_index = g->stack_trace_type->data.structure.fields[0].gen_index; | 962 | size_t index_field_index = g->stack_trace_type->data.structure.fields[0].gen_index; |
| ... | @@ -966,13 +964,21 @@ static LLVMValueRef get_return_err_fn(CodeGen *g) { | ... | @@ -966,13 +964,21 @@ static LLVMValueRef get_return_err_fn(CodeGen *g) { |
| 966 | size_t addresses_field_index = g->stack_trace_type->data.structure.fields[1].gen_index; | 964 | size_t addresses_field_index = g->stack_trace_type->data.structure.fields[1].gen_index; |
| 967 | LLVMValueRef addresses_field_ptr = LLVMBuildStructGEP(g->builder, err_ret_trace_ptr, (unsigned)addresses_field_index, ""); | 965 | LLVMValueRef addresses_field_ptr = LLVMBuildStructGEP(g->builder, err_ret_trace_ptr, (unsigned)addresses_field_index, ""); |
| 968 | | 966 | |
| | 967 | TypeTableEntry *slice_type = g->stack_trace_type->data.structure.fields[1].type_entry; |
| | 968 | size_t ptr_field_index = slice_type->data.structure.fields[slice_ptr_index].gen_index; |
| | 969 | LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, addresses_field_ptr, (unsigned)ptr_field_index, ""); |
| | 970 | size_t len_field_index = slice_type->data.structure.fields[slice_len_index].gen_index; |
| | 971 | LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, addresses_field_ptr, (unsigned)len_field_index, ""); |
| | 972 | |
| | 973 | LLVMValueRef len_value = gen_load_untyped(g, len_field_ptr, 0, false, ""); |
| 969 | LLVMValueRef index_val = gen_load_untyped(g, index_field_ptr, 0, false, ""); | 974 | LLVMValueRef index_val = gen_load_untyped(g, index_field_ptr, 0, false, ""); |
| 970 | LLVMValueRef modded_val = LLVMBuildURem(g->builder, index_val, LLVMConstInt(usize_type_ref, stack_trace_ptr_count, false), ""); | 975 | LLVMValueRef modded_val = LLVMBuildURem(g->builder, index_val, len_value, ""); |
| 971 | LLVMValueRef address_indices[] = { | 976 | LLVMValueRef address_indices[] = { |
| 972 | LLVMConstNull(usize_type_ref), | | |
| 973 | modded_val, | 977 | modded_val, |
| 974 | }; | 978 | }; |
| 975 | LLVMValueRef address_slot = LLVMBuildInBoundsGEP(g->builder, addresses_field_ptr, address_indices, 2, ""); | 979 | |
| | 980 | LLVMValueRef ptr_value = gen_load_untyped(g, ptr_field_ptr, 0, false, ""); |
| | 981 | LLVMValueRef address_slot = LLVMBuildInBoundsGEP(g->builder, ptr_value, address_indices, 1, ""); |
| 976 | | 982 | |
| 977 | LLVMValueRef return_address = LLVMBuildPtrToInt(g->builder, LLVMGetParam(fn_val, 1), usize_type_ref, ""); | 983 | LLVMValueRef return_address = LLVMBuildPtrToInt(g->builder, LLVMGetParam(fn_val, 1), usize_type_ref, ""); |
| 978 | | 984 | |
| ... | @@ -1052,8 +1058,8 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) { | ... | @@ -1052,8 +1058,8 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) { |
| 1052 | | 1058 | |
| 1053 | Buf *fn_name = get_mangled_name(g, buf_create_from_str("__zig_fail_unwrap"), false); | 1059 | Buf *fn_name = get_mangled_name(g, buf_create_from_str("__zig_fail_unwrap"), false); |
| 1054 | LLVMTypeRef arg_types[] = { | 1060 | LLVMTypeRef arg_types[] = { |
| 1055 | g->err_tag_type->type_ref, | | |
| 1056 | g->ptr_to_stack_trace_type->type_ref, | 1061 | g->ptr_to_stack_trace_type->type_ref, |
| | 1062 | g->err_tag_type->type_ref, |
| 1057 | }; | 1063 | }; |
| 1058 | LLVMTypeRef fn_type_ref = LLVMFunctionType(LLVMVoidType(), arg_types, 2, false); | 1064 | LLVMTypeRef fn_type_ref = LLVMFunctionType(LLVMVoidType(), arg_types, 2, false); |
| 1059 | LLVMValueRef fn_val = LLVMAddFunction(g->module, buf_ptr(fn_name), fn_type_ref); | 1065 | LLVMValueRef fn_val = LLVMAddFunction(g->module, buf_ptr(fn_name), fn_type_ref); |
| ... | @@ -1077,7 +1083,7 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) { | ... | @@ -1077,7 +1083,7 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) { |
| 1077 | LLVMPositionBuilderAtEnd(g->builder, entry_block); | 1083 | LLVMPositionBuilderAtEnd(g->builder, entry_block); |
| 1078 | ZigLLVMClearCurrentDebugLocation(g->builder); | 1084 | ZigLLVMClearCurrentDebugLocation(g->builder); |
| 1079 | | 1085 | |
| 1080 | LLVMValueRef err_val = LLVMGetParam(fn_val, 0); | 1086 | LLVMValueRef err_val = LLVMGetParam(fn_val, 1); |
| 1081 | | 1087 | |
| 1082 | LLVMValueRef err_table_indices[] = { | 1088 | LLVMValueRef err_table_indices[] = { |
| 1083 | LLVMConstNull(g->builtin_types.entry_usize->type_ref), | 1089 | LLVMConstNull(g->builtin_types.entry_usize->type_ref), |
| ... | @@ -1107,7 +1113,7 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) { | ... | @@ -1107,7 +1113,7 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) { |
| 1107 | LLVMValueRef global_slice_len_field_ptr = LLVMBuildStructGEP(g->builder, global_slice, slice_len_index, ""); | 1113 | LLVMValueRef global_slice_len_field_ptr = LLVMBuildStructGEP(g->builder, global_slice, slice_len_index, ""); |
| 1108 | gen_store(g, full_buf_len, global_slice_len_field_ptr, u8_ptr_type); | 1114 | gen_store(g, full_buf_len, global_slice_len_field_ptr, u8_ptr_type); |
| 1109 | | 1115 | |
| 1110 | gen_panic(g, global_slice, LLVMGetParam(fn_val, 1)); | 1116 | gen_panic(g, global_slice, LLVMGetParam(fn_val, 0)); |
| 1111 | | 1117 | |
| 1112 | LLVMPositionBuilderAtEnd(g->builder, prev_block); | 1118 | LLVMPositionBuilderAtEnd(g->builder, prev_block); |
| 1113 | LLVMSetCurrentDebugLocation(g->builder, prev_debug_location); | 1119 | LLVMSetCurrentDebugLocation(g->builder, prev_debug_location); |
| ... | @@ -1124,8 +1130,8 @@ static void gen_debug_safety_crash_for_err(CodeGen *g, LLVMValueRef err_val) { | ... | @@ -1124,8 +1130,8 @@ static void gen_debug_safety_crash_for_err(CodeGen *g, LLVMValueRef err_val) { |
| 1124 | err_ret_trace_val = LLVMConstNull(ptr_to_stack_trace_type->type_ref); | 1130 | err_ret_trace_val = LLVMConstNull(ptr_to_stack_trace_type->type_ref); |
| 1125 | } | 1131 | } |
| 1126 | LLVMValueRef args[] = { | 1132 | LLVMValueRef args[] = { |
| 1127 | err_val, | | |
| 1128 | err_ret_trace_val, | 1133 | err_ret_trace_val, |
| | 1134 | err_val, |
| 1129 | }; | 1135 | }; |
| 1130 | LLVMValueRef call_instruction = ZigLLVMBuildCall(g->builder, safety_crash_err_fn, args, 2, get_llvm_cc(g, CallingConventionUnspecified), | 1136 | LLVMValueRef call_instruction = ZigLLVMBuildCall(g->builder, safety_crash_err_fn, args, 2, get_llvm_cc(g, CallingConventionUnspecified), |
| 1131 | ZigLLVM_FnInlineAuto, ""); | 1137 | ZigLLVM_FnInlineAuto, ""); |
| ... | @@ -4651,11 +4657,34 @@ static void do_code_gen(CodeGen *g) { | ... | @@ -4651,11 +4657,34 @@ static void do_code_gen(CodeGen *g) { |
| 4651 | if (err_ret_trace_arg_index != UINT32_MAX) { | 4657 | if (err_ret_trace_arg_index != UINT32_MAX) { |
| 4652 | g->cur_err_ret_trace_val = LLVMGetParam(fn, err_ret_trace_arg_index); | 4658 | g->cur_err_ret_trace_val = LLVMGetParam(fn, err_ret_trace_arg_index); |
| 4653 | } else if (fn_table_entry->calls_errorable_function) { | 4659 | } else if (fn_table_entry->calls_errorable_function) { |
| | 4660 | // TODO call graph analysis to find out what this number needs to be for every function |
| | 4661 | static const size_t stack_trace_ptr_count = 30; |
| | 4662 | |
| | 4663 | TypeTableEntry *usize = g->builtin_types.entry_usize; |
| | 4664 | TypeTableEntry *array_type = get_array_type(g, usize, stack_trace_ptr_count); |
| | 4665 | LLVMValueRef err_ret_array_val = build_alloca(g, array_type, "error_return_trace_addresses", |
| | 4666 | get_abi_alignment(g, array_type)); |
| 4654 | g->cur_err_ret_trace_val = build_alloca(g, g->stack_trace_type, "error_return_trace", get_abi_alignment(g, g->stack_trace_type)); | 4667 | g->cur_err_ret_trace_val = build_alloca(g, g->stack_trace_type, "error_return_trace", get_abi_alignment(g, g->stack_trace_type)); |
| 4655 | size_t index_field_index = g->stack_trace_type->data.structure.fields[0].gen_index; | 4668 | size_t index_field_index = g->stack_trace_type->data.structure.fields[0].gen_index; |
| 4656 | LLVMValueRef index_field_ptr = LLVMBuildStructGEP(g->builder, g->cur_err_ret_trace_val, (unsigned)index_field_index, ""); | 4669 | LLVMValueRef index_field_ptr = LLVMBuildStructGEP(g->builder, g->cur_err_ret_trace_val, (unsigned)index_field_index, ""); |
| 4657 | TypeTableEntry *usize = g->builtin_types.entry_usize; | | |
| 4658 | gen_store_untyped(g, LLVMConstNull(usize->type_ref), index_field_ptr, 0, false); | 4670 | gen_store_untyped(g, LLVMConstNull(usize->type_ref), index_field_ptr, 0, false); |
| | 4671 | |
| | 4672 | size_t addresses_field_index = g->stack_trace_type->data.structure.fields[1].gen_index; |
| | 4673 | LLVMValueRef addresses_field_ptr = LLVMBuildStructGEP(g->builder, g->cur_err_ret_trace_val, (unsigned)addresses_field_index, ""); |
| | 4674 | |
| | 4675 | TypeTableEntry *slice_type = g->stack_trace_type->data.structure.fields[1].type_entry; |
| | 4676 | size_t ptr_field_index = slice_type->data.structure.fields[slice_ptr_index].gen_index; |
| | 4677 | LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, addresses_field_ptr, (unsigned)ptr_field_index, ""); |
| | 4678 | LLVMValueRef zero = LLVMConstNull(usize->type_ref); |
| | 4679 | LLVMValueRef indices[] = {zero, zero}; |
| | 4680 | LLVMValueRef err_ret_array_val_elem0_ptr = LLVMBuildInBoundsGEP(g->builder, err_ret_array_val, |
| | 4681 | indices, 2, ""); |
| | 4682 | gen_store(g, err_ret_array_val_elem0_ptr, ptr_field_ptr, |
| | 4683 | get_pointer_to_type(g, get_pointer_to_type(g, usize, false), false)); |
| | 4684 | |
| | 4685 | size_t len_field_index = slice_type->data.structure.fields[slice_len_index].gen_index; |
| | 4686 | LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, addresses_field_ptr, (unsigned)len_field_index, ""); |
| | 4687 | gen_store(g, LLVMConstInt(usize->type_ref, stack_trace_ptr_count, false), len_field_ptr, get_pointer_to_type(g, usize, false)); |
| 4659 | } else { | 4688 | } else { |
| 4660 | g->cur_err_ret_trace_val = nullptr; | 4689 | g->cur_err_ret_trace_val = nullptr; |
| 4661 | } | 4690 | } |
| ... | @@ -5246,11 +5275,11 @@ static void define_builtin_compile_vars(CodeGen *g) { | ... | @@ -5246,11 +5275,11 @@ static void define_builtin_compile_vars(CodeGen *g) { |
| 5246 | os_path_join(g->cache_dir, buf_create_from_str(builtin_zig_basename), builtin_zig_path); | 5275 | os_path_join(g->cache_dir, buf_create_from_str(builtin_zig_basename), builtin_zig_path); |
| 5247 | Buf *contents = buf_alloc(); | 5276 | Buf *contents = buf_alloc(); |
| 5248 | | 5277 | |
| 5249 | buf_appendf(contents, | 5278 | buf_append_str(contents, |
| 5250 | "pub const StackTrace = struct {\n" | 5279 | "pub const StackTrace = struct {\n" |
| 5251 | " index: usize,\n" | 5280 | " index: usize,\n" |
| 5252 | " instruction_addresses: [%" ZIG_PRI_usize "]usize,\n" | 5281 | " instruction_addresses: []usize,\n" |
| 5253 | "};\n\n", stack_trace_ptr_count); | 5282 | "};\n\n"); |
| 5254 | | 5283 | |
| 5255 | const char *cur_os = nullptr; | 5284 | const char *cur_os = nullptr; |
| 5256 | { | 5285 | { |