| ... | @@ -296,6 +296,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c | ... | @@ -296,6 +296,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c |
| 296 | static void generate_error_name_table(CodeGen *g); | 296 | static void generate_error_name_table(CodeGen *g); |
| 297 | static bool value_is_all_undef(ConstExprValue *const_val); | 297 | static bool value_is_all_undef(ConstExprValue *const_val); |
| 298 | static void gen_undef_init(CodeGen *g, uint32_t ptr_align_bytes, ZigType *value_type, LLVMValueRef ptr); | 298 | static void gen_undef_init(CodeGen *g, uint32_t ptr_align_bytes, ZigType *value_type, LLVMValueRef ptr); |
| | 299 | static LLVMValueRef build_alloca(CodeGen *g, ZigType *type_entry, const char *name, uint32_t alignment); |
| 299 | | 300 | |
| 300 | static void addLLVMAttr(LLVMValueRef val, LLVMAttributeIndex attr_index, const char *attr_name) { | 301 | static void addLLVMAttr(LLVMValueRef val, LLVMAttributeIndex attr_index, const char *attr_name) { |
| 301 | unsigned kind_id = LLVMGetEnumAttributeKindForName(attr_name, strlen(attr_name)); | 302 | unsigned kind_id = LLVMGetEnumAttributeKindForName(attr_name, strlen(attr_name)); |
| ... | @@ -1518,53 +1519,12 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) { | ... | @@ -1518,53 +1519,12 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) { |
| 1518 | generate_error_name_table(g); | 1519 | generate_error_name_table(g); |
| 1519 | assert(g->err_name_table != nullptr); | 1520 | assert(g->err_name_table != nullptr); |
| 1520 | | 1521 | |
| 1521 | size_t unwrap_err_msg_text_len = strlen(unwrap_err_msg_text); | 1522 | // Generate the constant part of the error message |
| 1522 | size_t err_buf_len = strlen(unwrap_err_msg_text) + g->largest_err_name_len; | 1523 | LLVMValueRef msg_prefix_init = LLVMConstString(unwrap_err_msg_text, strlen(unwrap_err_msg_text), 1); |
| 1523 | LLVMValueRef *err_buf_vals = allocate<LLVMValueRef>(err_buf_len); | 1524 | LLVMValueRef msg_prefix = LLVMAddGlobal(g->module, LLVMTypeOf(msg_prefix_init), ""); |
| 1524 | size_t i = 0; | 1525 | LLVMSetInitializer(msg_prefix, msg_prefix_init); |
| 1525 | for (; i < unwrap_err_msg_text_len; i += 1) { | 1526 | LLVMSetLinkage(msg_prefix, LLVMInternalLinkage); |
| 1526 | err_buf_vals[i] = LLVMConstInt(LLVMInt8Type(), unwrap_err_msg_text[i], false); | 1527 | LLVMSetGlobalConstant(msg_prefix, true); |
| 1527 | } | | |
| 1528 | for (; i < err_buf_len; i += 1) { | | |
| 1529 | err_buf_vals[i] = LLVMGetUndef(LLVMInt8Type()); | | |
| 1530 | } | | |
| 1531 | uint32_t u8_align_bytes = get_abi_alignment(g, g->builtin_types.entry_u8); | | |
| 1532 | LLVMValueRef init_value = LLVMConstArray(LLVMInt8Type(), err_buf_vals, err_buf_len); | | |
| 1533 | LLVMValueRef global_array = LLVMAddGlobal(g->module, LLVMTypeOf(init_value), ""); | | |
| 1534 | LLVMSetInitializer(global_array, init_value); | | |
| 1535 | LLVMSetLinkage(global_array, LLVMInternalLinkage); | | |
| 1536 | LLVMSetGlobalConstant(global_array, false); | | |
| 1537 | LLVMSetUnnamedAddr(global_array, true); | | |
| 1538 | LLVMSetAlignment(global_array, u8_align_bytes); | | |
| 1539 | | | |
| 1540 | ZigType *usize = g->builtin_types.entry_usize; | | |
| 1541 | LLVMValueRef full_buf_ptr_indices[] = { | | |
| 1542 | LLVMConstNull(usize->llvm_type), | | |
| 1543 | LLVMConstNull(usize->llvm_type), | | |
| 1544 | }; | | |
| 1545 | LLVMValueRef full_buf_ptr = LLVMConstInBoundsGEP(global_array, full_buf_ptr_indices, 2); | | |
| 1546 | | | |
| 1547 | | | |
| 1548 | ZigType *u8_ptr_type = get_pointer_to_type_extra(g, g->builtin_types.entry_u8, true, false, | | |
| 1549 | PtrLenUnknown, get_abi_alignment(g, g->builtin_types.entry_u8), 0, 0, false); | | |
| 1550 | ZigType *str_type = get_slice_type(g, u8_ptr_type); | | |
| 1551 | LLVMValueRef global_slice_fields[] = { | | |
| 1552 | full_buf_ptr, | | |
| 1553 | LLVMConstNull(usize->llvm_type), | | |
| 1554 | }; | | |
| 1555 | LLVMValueRef slice_init_value = LLVMConstNamedStruct(get_llvm_type(g, str_type), global_slice_fields, 2); | | |
| 1556 | LLVMValueRef global_slice = LLVMAddGlobal(g->module, LLVMTypeOf(slice_init_value), ""); | | |
| 1557 | LLVMSetInitializer(global_slice, slice_init_value); | | |
| 1558 | LLVMSetLinkage(global_slice, LLVMInternalLinkage); | | |
| 1559 | LLVMSetGlobalConstant(global_slice, false); | | |
| 1560 | LLVMSetUnnamedAddr(global_slice, true); | | |
| 1561 | LLVMSetAlignment(global_slice, get_abi_alignment(g, str_type)); | | |
| 1562 | | | |
| 1563 | LLVMValueRef offset_ptr_indices[] = { | | |
| 1564 | LLVMConstNull(usize->llvm_type), | | |
| 1565 | LLVMConstInt(usize->llvm_type, unwrap_err_msg_text_len, false), | | |
| 1566 | }; | | |
| 1567 | LLVMValueRef offset_buf_ptr = LLVMConstInBoundsGEP(global_array, offset_ptr_indices, 2); | | |
| 1568 | | 1528 | |
| 1569 | Buf *fn_name = get_mangled_name(g, buf_create_from_str("__zig_fail_unwrap"), false); | 1529 | Buf *fn_name = get_mangled_name(g, buf_create_from_str("__zig_fail_unwrap"), false); |
| 1570 | LLVMTypeRef fn_type_ref; | 1530 | LLVMTypeRef fn_type_ref; |
| ... | @@ -1601,6 +1561,19 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) { | ... | @@ -1601,6 +1561,19 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) { |
| 1601 | LLVMPositionBuilderAtEnd(g->builder, entry_block); | 1561 | LLVMPositionBuilderAtEnd(g->builder, entry_block); |
| 1602 | ZigLLVMClearCurrentDebugLocation(g->builder); | 1562 | ZigLLVMClearCurrentDebugLocation(g->builder); |
| 1603 | | 1563 | |
| | 1564 | ZigType *usize_ty = g->builtin_types.entry_usize; |
| | 1565 | ZigType *u8_ptr_type = get_pointer_to_type_extra(g, g->builtin_types.entry_u8, true, false, |
| | 1566 | PtrLenUnknown, get_abi_alignment(g, g->builtin_types.entry_u8), 0, 0, false); |
| | 1567 | ZigType *str_type = get_slice_type(g, u8_ptr_type); |
| | 1568 | |
| | 1569 | // Allocate a buffer to hold the fully-formatted error message |
| | 1570 | const size_t err_buf_len = strlen(unwrap_err_msg_text) + g->largest_err_name_len; |
| | 1571 | LLVMValueRef max_msg_len = LLVMConstInt(usize_ty->llvm_type, err_buf_len, 0); |
| | 1572 | LLVMValueRef msg_buffer = LLVMBuildArrayAlloca(g->builder, LLVMInt8Type(), max_msg_len, "msg_buffer"); |
| | 1573 | |
| | 1574 | // Allocate a []u8 slice for the message |
| | 1575 | LLVMValueRef msg_slice = build_alloca(g, str_type, "msg_slice", 0); |
| | 1576 | |
| 1604 | LLVMValueRef err_ret_trace_arg; | 1577 | LLVMValueRef err_ret_trace_arg; |
| 1605 | LLVMValueRef err_val; | 1578 | LLVMValueRef err_val; |
| 1606 | if (g->have_err_ret_tracing) { | 1579 | if (g->have_err_ret_tracing) { |
| ... | @@ -1611,8 +1584,9 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) { | ... | @@ -1611,8 +1584,9 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) { |
| 1611 | err_val = LLVMGetParam(fn_val, 0); | 1584 | err_val = LLVMGetParam(fn_val, 0); |
| 1612 | } | 1585 | } |
| 1613 | | 1586 | |
| | 1587 | // Fetch the error name from the global table |
| 1614 | LLVMValueRef err_table_indices[] = { | 1588 | LLVMValueRef err_table_indices[] = { |
| 1615 | LLVMConstNull(g->builtin_types.entry_usize->llvm_type), | 1589 | LLVMConstNull(usize_ty->llvm_type), |
| 1616 | err_val, | 1590 | err_val, |
| 1617 | }; | 1591 | }; |
| 1618 | LLVMValueRef err_name_val = LLVMBuildInBoundsGEP(g->builder, g->err_name_table, err_table_indices, 2, ""); | 1592 | 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) { | ... | @@ -1623,15 +1597,38 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) { |
| 1623 | LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, err_name_val, slice_len_index, ""); | 1597 | LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, err_name_val, slice_len_index, ""); |
| 1624 | LLVMValueRef err_name_len = gen_load_untyped(g, len_field_ptr, 0, false, ""); | 1598 | LLVMValueRef err_name_len = gen_load_untyped(g, len_field_ptr, 0, false, ""); |
| 1625 | | 1599 | |
| 1626 | ZigLLVMBuildMemCpy(g->builder, offset_buf_ptr, u8_align_bytes, err_name_ptr, u8_align_bytes, err_name_len, false); | 1600 | LLVMValueRef msg_prefix_len = LLVMConstInt(usize_ty->llvm_type, strlen(unwrap_err_msg_text), false); |
| | 1601 | // Points to the beginning of msg_buffer |
| | 1602 | LLVMValueRef msg_buffer_ptr_indices[] = { |
| | 1603 | LLVMConstNull(usize_ty->llvm_type), |
| | 1604 | }; |
| | 1605 | LLVMValueRef msg_buffer_ptr = LLVMBuildInBoundsGEP(g->builder, msg_buffer, msg_buffer_ptr_indices, 1, ""); |
| | 1606 | // Points to the beginning of the constant prefix message |
| | 1607 | LLVMValueRef msg_prefix_ptr_indices[] = { |
| | 1608 | LLVMConstNull(usize_ty->llvm_type), |
| | 1609 | }; |
| | 1610 | LLVMValueRef msg_prefix_ptr = LLVMConstInBoundsGEP(msg_prefix, msg_prefix_ptr_indices, 1); |
| | 1611 | |
| | 1612 | // Build the message using the prefix... |
| | 1613 | ZigLLVMBuildMemCpy(g->builder, msg_buffer_ptr, 1, msg_prefix_ptr, 1, msg_prefix_len, false); |
| | 1614 | // ..and append the error name |
| | 1615 | LLVMValueRef msg_buffer_ptr_after_indices[] = { |
| | 1616 | msg_prefix_len, |
| | 1617 | }; |
| | 1618 | LLVMValueRef msg_buffer_ptr_after = LLVMBuildInBoundsGEP(g->builder, msg_buffer, msg_buffer_ptr_after_indices, 1, ""); |
| | 1619 | ZigLLVMBuildMemCpy(g->builder, msg_buffer_ptr_after, 1, err_name_ptr, 1, err_name_len, false); |
| 1627 | | 1620 | |
| 1628 | LLVMValueRef const_prefix_len = LLVMConstInt(LLVMTypeOf(err_name_len), strlen(unwrap_err_msg_text), false); | 1621 | // Set the slice pointer |
| 1629 | LLVMValueRef full_buf_len = LLVMBuildNUWAdd(g->builder, const_prefix_len, err_name_len, ""); | 1622 | LLVMValueRef msg_slice_ptr_field_ptr = LLVMBuildStructGEP(g->builder, msg_slice, slice_ptr_index, ""); |
| | 1623 | gen_store_untyped(g, msg_buffer_ptr, msg_slice_ptr_field_ptr, 0, false); |
| 1630 | | 1624 | |
| 1631 | LLVMValueRef global_slice_len_field_ptr = LLVMBuildStructGEP(g->builder, global_slice, slice_len_index, ""); | 1625 | // Set the slice length |
| 1632 | gen_store(g, full_buf_len, global_slice_len_field_ptr, u8_ptr_type); | 1626 | LLVMValueRef slice_len = LLVMBuildNUWAdd(g->builder, msg_prefix_len, err_name_len, ""); |
| | 1627 | LLVMValueRef msg_slice_len_field_ptr = LLVMBuildStructGEP(g->builder, msg_slice, slice_len_index, ""); |
| | 1628 | gen_store_untyped(g, slice_len, msg_slice_len_field_ptr, 0, false); |
| 1633 | | 1629 | |
| 1634 | gen_panic(g, global_slice, err_ret_trace_arg); | 1630 | // Call panic() |
| | 1631 | gen_panic(g, msg_slice, err_ret_trace_arg); |
| 1635 | | 1632 | |
| 1636 | LLVMPositionBuilderAtEnd(g->builder, prev_block); | 1633 | LLVMPositionBuilderAtEnd(g->builder, prev_block); |
| 1637 | LLVMSetCurrentDebugLocation(g->builder, prev_debug_location); | 1634 | LLVMSetCurrentDebugLocation(g->builder, prev_debug_location); |