| ... | ... | @@ -647,8 +647,28 @@ static void gen_panic_raw(CodeGen *g, LLVMValueRef msg_ptr, LLVMValueRef msg_len |
| 647 | 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 | 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 | 672 | size_t ptr_index = str_type->data.structure.fields[slice_ptr_index].gen_index; |
| 653 | 673 | size_t len_index = str_type->data.structure.fields[slice_len_index].gen_index; |
| 654 | 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 | 677 | LLVMValueRef msg_ptr = LLVMBuildLoad(g->builder, ptr_ptr, ""); |
| 658 | 678 | LLVMValueRef msg_len = LLVMBuildLoad(g->builder, len_ptr, ""); |
| 659 | 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 | 693 | static void gen_debug_safety_crash(CodeGen *g, PanicMsgId msg_id) { |