Move __zig_fail_unwrap locals on stack
This commit is contained in:
parent
568dc56232
commit
e2c2263434
105
src/codegen.cpp
105
src/codegen.cpp
|
@ -296,6 +296,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c
|
||||||
static void generate_error_name_table(CodeGen *g);
|
static void generate_error_name_table(CodeGen *g);
|
||||||
static bool value_is_all_undef(ConstExprValue *const_val);
|
static bool value_is_all_undef(ConstExprValue *const_val);
|
||||||
static void gen_undef_init(CodeGen *g, uint32_t ptr_align_bytes, ZigType *value_type, LLVMValueRef ptr);
|
static void gen_undef_init(CodeGen *g, uint32_t ptr_align_bytes, ZigType *value_type, LLVMValueRef ptr);
|
||||||
|
static LLVMValueRef build_alloca(CodeGen *g, ZigType *type_entry, const char *name, uint32_t alignment);
|
||||||
|
|
||||||
static void addLLVMAttr(LLVMValueRef val, LLVMAttributeIndex attr_index, const char *attr_name) {
|
static void addLLVMAttr(LLVMValueRef val, LLVMAttributeIndex attr_index, const char *attr_name) {
|
||||||
unsigned kind_id = LLVMGetEnumAttributeKindForName(attr_name, strlen(attr_name));
|
unsigned kind_id = LLVMGetEnumAttributeKindForName(attr_name, strlen(attr_name));
|
||||||
|
@ -1518,53 +1519,12 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {
|
||||||
generate_error_name_table(g);
|
generate_error_name_table(g);
|
||||||
assert(g->err_name_table != nullptr);
|
assert(g->err_name_table != nullptr);
|
||||||
|
|
||||||
size_t unwrap_err_msg_text_len = strlen(unwrap_err_msg_text);
|
// Generate the constant part of the error message
|
||||||
size_t err_buf_len = strlen(unwrap_err_msg_text) + g->largest_err_name_len;
|
LLVMValueRef msg_prefix_init = LLVMConstString(unwrap_err_msg_text, strlen(unwrap_err_msg_text), 1);
|
||||||
LLVMValueRef *err_buf_vals = allocate<LLVMValueRef>(err_buf_len);
|
LLVMValueRef msg_prefix = LLVMAddGlobal(g->module, LLVMTypeOf(msg_prefix_init), "");
|
||||||
size_t i = 0;
|
LLVMSetInitializer(msg_prefix, msg_prefix_init);
|
||||||
for (; i < unwrap_err_msg_text_len; i += 1) {
|
LLVMSetLinkage(msg_prefix, LLVMInternalLinkage);
|
||||||
err_buf_vals[i] = LLVMConstInt(LLVMInt8Type(), unwrap_err_msg_text[i], false);
|
LLVMSetGlobalConstant(msg_prefix, true);
|
||||||
}
|
|
||||||
for (; i < err_buf_len; i += 1) {
|
|
||||||
err_buf_vals[i] = LLVMGetUndef(LLVMInt8Type());
|
|
||||||
}
|
|
||||||
uint32_t u8_align_bytes = get_abi_alignment(g, g->builtin_types.entry_u8);
|
|
||||||
LLVMValueRef init_value = LLVMConstArray(LLVMInt8Type(), err_buf_vals, err_buf_len);
|
|
||||||
LLVMValueRef global_array = LLVMAddGlobal(g->module, LLVMTypeOf(init_value), "");
|
|
||||||
LLVMSetInitializer(global_array, init_value);
|
|
||||||
LLVMSetLinkage(global_array, LLVMInternalLinkage);
|
|
||||||
LLVMSetGlobalConstant(global_array, false);
|
|
||||||
LLVMSetUnnamedAddr(global_array, true);
|
|
||||||
LLVMSetAlignment(global_array, u8_align_bytes);
|
|
||||||
|
|
||||||
ZigType *usize = g->builtin_types.entry_usize;
|
|
||||||
LLVMValueRef full_buf_ptr_indices[] = {
|
|
||||||
LLVMConstNull(usize->llvm_type),
|
|
||||||
LLVMConstNull(usize->llvm_type),
|
|
||||||
};
|
|
||||||
LLVMValueRef full_buf_ptr = LLVMConstInBoundsGEP(global_array, full_buf_ptr_indices, 2);
|
|
||||||
|
|
||||||
|
|
||||||
ZigType *u8_ptr_type = get_pointer_to_type_extra(g, g->builtin_types.entry_u8, true, false,
|
|
||||||
PtrLenUnknown, get_abi_alignment(g, g->builtin_types.entry_u8), 0, 0, false);
|
|
||||||
ZigType *str_type = get_slice_type(g, u8_ptr_type);
|
|
||||||
LLVMValueRef global_slice_fields[] = {
|
|
||||||
full_buf_ptr,
|
|
||||||
LLVMConstNull(usize->llvm_type),
|
|
||||||
};
|
|
||||||
LLVMValueRef slice_init_value = LLVMConstNamedStruct(get_llvm_type(g, str_type), global_slice_fields, 2);
|
|
||||||
LLVMValueRef global_slice = LLVMAddGlobal(g->module, LLVMTypeOf(slice_init_value), "");
|
|
||||||
LLVMSetInitializer(global_slice, slice_init_value);
|
|
||||||
LLVMSetLinkage(global_slice, LLVMInternalLinkage);
|
|
||||||
LLVMSetGlobalConstant(global_slice, false);
|
|
||||||
LLVMSetUnnamedAddr(global_slice, true);
|
|
||||||
LLVMSetAlignment(global_slice, get_abi_alignment(g, str_type));
|
|
||||||
|
|
||||||
LLVMValueRef offset_ptr_indices[] = {
|
|
||||||
LLVMConstNull(usize->llvm_type),
|
|
||||||
LLVMConstInt(usize->llvm_type, unwrap_err_msg_text_len, false),
|
|
||||||
};
|
|
||||||
LLVMValueRef offset_buf_ptr = LLVMConstInBoundsGEP(global_array, offset_ptr_indices, 2);
|
|
||||||
|
|
||||||
Buf *fn_name = get_mangled_name(g, buf_create_from_str("__zig_fail_unwrap"), false);
|
Buf *fn_name = get_mangled_name(g, buf_create_from_str("__zig_fail_unwrap"), false);
|
||||||
LLVMTypeRef fn_type_ref;
|
LLVMTypeRef fn_type_ref;
|
||||||
|
@ -1601,6 +1561,19 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {
|
||||||
LLVMPositionBuilderAtEnd(g->builder, entry_block);
|
LLVMPositionBuilderAtEnd(g->builder, entry_block);
|
||||||
ZigLLVMClearCurrentDebugLocation(g->builder);
|
ZigLLVMClearCurrentDebugLocation(g->builder);
|
||||||
|
|
||||||
|
ZigType *usize_ty = g->builtin_types.entry_usize;
|
||||||
|
ZigType *u8_ptr_type = get_pointer_to_type_extra(g, g->builtin_types.entry_u8, true, false,
|
||||||
|
PtrLenUnknown, get_abi_alignment(g, g->builtin_types.entry_u8), 0, 0, false);
|
||||||
|
ZigType *str_type = get_slice_type(g, u8_ptr_type);
|
||||||
|
|
||||||
|
// Allocate a buffer to hold the fully-formatted error message
|
||||||
|
const size_t err_buf_len = strlen(unwrap_err_msg_text) + g->largest_err_name_len;
|
||||||
|
LLVMValueRef max_msg_len = LLVMConstInt(usize_ty->llvm_type, err_buf_len, 0);
|
||||||
|
LLVMValueRef msg_buffer = LLVMBuildArrayAlloca(g->builder, LLVMInt8Type(), max_msg_len, "msg_buffer");
|
||||||
|
|
||||||
|
// Allocate a []u8 slice for the message
|
||||||
|
LLVMValueRef msg_slice = build_alloca(g, str_type, "msg_slice", 0);
|
||||||
|
|
||||||
LLVMValueRef err_ret_trace_arg;
|
LLVMValueRef err_ret_trace_arg;
|
||||||
LLVMValueRef err_val;
|
LLVMValueRef err_val;
|
||||||
if (g->have_err_ret_tracing) {
|
if (g->have_err_ret_tracing) {
|
||||||
|
@ -1611,8 +1584,9 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {
|
||||||
err_val = LLVMGetParam(fn_val, 0);
|
err_val = LLVMGetParam(fn_val, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fetch the error name from the global table
|
||||||
LLVMValueRef err_table_indices[] = {
|
LLVMValueRef err_table_indices[] = {
|
||||||
LLVMConstNull(g->builtin_types.entry_usize->llvm_type),
|
LLVMConstNull(usize_ty->llvm_type),
|
||||||
err_val,
|
err_val,
|
||||||
};
|
};
|
||||||
LLVMValueRef err_name_val = LLVMBuildInBoundsGEP(g->builder, g->err_name_table, err_table_indices, 2, "");
|
LLVMValueRef err_name_val = LLVMBuildInBoundsGEP(g->builder, g->err_name_table, err_table_indices, 2, "");
|
||||||
|
@ -1623,15 +1597,38 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {
|
||||||
LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, err_name_val, slice_len_index, "");
|
LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, err_name_val, slice_len_index, "");
|
||||||
LLVMValueRef err_name_len = gen_load_untyped(g, len_field_ptr, 0, false, "");
|
LLVMValueRef err_name_len = gen_load_untyped(g, len_field_ptr, 0, false, "");
|
||||||
|
|
||||||
ZigLLVMBuildMemCpy(g->builder, offset_buf_ptr, u8_align_bytes, err_name_ptr, u8_align_bytes, err_name_len, false);
|
LLVMValueRef msg_prefix_len = LLVMConstInt(usize_ty->llvm_type, strlen(unwrap_err_msg_text), false);
|
||||||
|
// Points to the beginning of msg_buffer
|
||||||
|
LLVMValueRef msg_buffer_ptr_indices[] = {
|
||||||
|
LLVMConstNull(usize_ty->llvm_type),
|
||||||
|
};
|
||||||
|
LLVMValueRef msg_buffer_ptr = LLVMBuildInBoundsGEP(g->builder, msg_buffer, msg_buffer_ptr_indices, 1, "");
|
||||||
|
// Points to the beginning of the constant prefix message
|
||||||
|
LLVMValueRef msg_prefix_ptr_indices[] = {
|
||||||
|
LLVMConstNull(usize_ty->llvm_type),
|
||||||
|
};
|
||||||
|
LLVMValueRef msg_prefix_ptr = LLVMConstInBoundsGEP(msg_prefix, msg_prefix_ptr_indices, 1);
|
||||||
|
|
||||||
LLVMValueRef const_prefix_len = LLVMConstInt(LLVMTypeOf(err_name_len), strlen(unwrap_err_msg_text), false);
|
// Build the message using the prefix...
|
||||||
LLVMValueRef full_buf_len = LLVMBuildNUWAdd(g->builder, const_prefix_len, err_name_len, "");
|
ZigLLVMBuildMemCpy(g->builder, msg_buffer_ptr, 1, msg_prefix_ptr, 1, msg_prefix_len, false);
|
||||||
|
// ..and append the error name
|
||||||
|
LLVMValueRef msg_buffer_ptr_after_indices[] = {
|
||||||
|
msg_prefix_len,
|
||||||
|
};
|
||||||
|
LLVMValueRef msg_buffer_ptr_after = LLVMBuildInBoundsGEP(g->builder, msg_buffer, msg_buffer_ptr_after_indices, 1, "");
|
||||||
|
ZigLLVMBuildMemCpy(g->builder, msg_buffer_ptr_after, 1, err_name_ptr, 1, err_name_len, false);
|
||||||
|
|
||||||
LLVMValueRef global_slice_len_field_ptr = LLVMBuildStructGEP(g->builder, global_slice, slice_len_index, "");
|
// Set the slice pointer
|
||||||
gen_store(g, full_buf_len, global_slice_len_field_ptr, u8_ptr_type);
|
LLVMValueRef msg_slice_ptr_field_ptr = LLVMBuildStructGEP(g->builder, msg_slice, slice_ptr_index, "");
|
||||||
|
gen_store_untyped(g, msg_buffer_ptr, msg_slice_ptr_field_ptr, 0, false);
|
||||||
|
|
||||||
gen_panic(g, global_slice, err_ret_trace_arg);
|
// Set the slice length
|
||||||
|
LLVMValueRef slice_len = LLVMBuildNUWAdd(g->builder, msg_prefix_len, err_name_len, "");
|
||||||
|
LLVMValueRef msg_slice_len_field_ptr = LLVMBuildStructGEP(g->builder, msg_slice, slice_len_index, "");
|
||||||
|
gen_store_untyped(g, slice_len, msg_slice_len_field_ptr, 0, false);
|
||||||
|
|
||||||
|
// Call panic()
|
||||||
|
gen_panic(g, msg_slice, err_ret_trace_arg);
|
||||||
|
|
||||||
LLVMPositionBuilderAtEnd(g->builder, prev_block);
|
LLVMPositionBuilderAtEnd(g->builder, prev_block);
|
||||||
LLVMSetCurrentDebugLocation(g->builder, prev_debug_location);
|
LLVMSetCurrentDebugLocation(g->builder, prev_debug_location);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user