| ... | @@ -647,8 +647,28 @@ static void gen_panic_raw(CodeGen *g, LLVMValueRef msg_ptr, LLVMValueRef msg_len | ... | @@ -647,8 +647,28 @@ static void gen_panic_raw(CodeGen *g, LLVMValueRef msg_ptr, LLVMValueRef msg_len |
| 647 | LLVMBuildUnreachable(g->builder); | 647 | LLVMBuildUnreachable(g->builder); |
| 648 | } | 648 | } |
| 649 | | 649 | |
| 650 | static void gen_panic(CodeGen *g, LLVMValueRef msg_arg) { | 650 | static LLVMValueRef get_panic_slice_fn(CodeGen *g) { |
| | 651 | if (g->panic_slice_fn != nullptr) |
| | 652 | return g->panic_slice_fn; |
| | 653 | |
| 651 | TypeTableEntry *str_type = get_slice_type(g, g->builtin_types.entry_u8, true); | 654 | TypeTableEntry *str_type = get_slice_type(g, g->builtin_types.entry_u8, true); |
| | 655 | TypeTableEntry *ptr_to_str_type = get_pointer_to_type(g, str_type, true); |
| | 656 | |
| | 657 | Buf *fn_name = get_mangled_name(g, buf_create_from_str("__zig_panic_slice"), false); |
| | 658 | LLVMTypeRef fn_type_ref = LLVMFunctionType(LLVMVoidType(), &ptr_to_str_type->type_ref, 1, false); |
| | 659 | LLVMValueRef fn_val = LLVMAddFunction(g->module, buf_ptr(fn_name), fn_type_ref); |
| | 660 | addLLVMFnAttr(fn_val, "noreturn"); |
| | 661 | addLLVMFnAttr(fn_val, "cold"); |
| | 662 | LLVMSetLinkage(fn_val, LLVMInternalLinkage); |
| | 663 | LLVMSetFunctionCallConv(fn_val, LLVMFastCallConv); |
| | 664 | |
| | 665 | LLVMBasicBlockRef entry_block = LLVMAppendBasicBlock(fn_val, "Entry"); |
| | 666 | LLVMBasicBlockRef prev_block = LLVMGetInsertBlock(g->builder); |
| | 667 | LLVMValueRef prev_debug_location = LLVMGetCurrentDebugLocation(g->builder); |
| | 668 | LLVMPositionBuilderAtEnd(g->builder, entry_block); |
| | 669 | |
| | 670 | LLVMValueRef msg_arg = LLVMGetParam(fn_val, 0); |
| | 671 | |
| 652 | size_t ptr_index = str_type->data.structure.fields[slice_ptr_index].gen_index; | 672 | size_t ptr_index = str_type->data.structure.fields[slice_ptr_index].gen_index; |
| 653 | size_t len_index = str_type->data.structure.fields[slice_len_index].gen_index; | 673 | size_t len_index = str_type->data.structure.fields[slice_len_index].gen_index; |
| 654 | LLVMValueRef ptr_ptr = LLVMBuildStructGEP(g->builder, msg_arg, (unsigned)ptr_index, ""); | 674 | LLVMValueRef ptr_ptr = LLVMBuildStructGEP(g->builder, msg_arg, (unsigned)ptr_index, ""); |
| ... | @@ -657,6 +677,17 @@ static void gen_panic(CodeGen *g, LLVMValueRef msg_arg) { | ... | @@ -657,6 +677,17 @@ static void gen_panic(CodeGen *g, LLVMValueRef msg_arg) { |
| 657 | LLVMValueRef msg_ptr = LLVMBuildLoad(g->builder, ptr_ptr, ""); | 677 | LLVMValueRef msg_ptr = LLVMBuildLoad(g->builder, ptr_ptr, ""); |
| 658 | LLVMValueRef msg_len = LLVMBuildLoad(g->builder, len_ptr, ""); | 678 | LLVMValueRef msg_len = LLVMBuildLoad(g->builder, len_ptr, ""); |
| 659 | gen_panic_raw(g, msg_ptr, msg_len); | 679 | gen_panic_raw(g, msg_ptr, msg_len); |
| | 680 | |
| | 681 | LLVMPositionBuilderAtEnd(g->builder, prev_block); |
| | 682 | LLVMSetCurrentDebugLocation(g->builder, prev_debug_location); |
| | 683 | g->panic_slice_fn = fn_val; |
| | 684 | return g->panic_slice_fn; |
| | 685 | } |
| | 686 | |
| | 687 | static void gen_panic(CodeGen *g, LLVMValueRef msg_arg) { |
| | 688 | LLVMValueRef fn_val = get_panic_slice_fn(g); |
| | 689 | LLVMBuildCall(g->builder, fn_val, &msg_arg, 1, ""); |
| | 690 | LLVMBuildUnreachable(g->builder); |
| 660 | } | 691 | } |
| 661 | | 692 | |
| 662 | static void gen_debug_safety_crash(CodeGen *g, PanicMsgId msg_id) { | 693 | static void gen_debug_safety_crash(CodeGen *g, PanicMsgId msg_id) { |