1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
use llvm_sys::core::*; use llvm_sys::LLVMAttributeFunctionIndex; use crate::codegen::const_gen::annotate_private_global; use crate::codegen::fun_gen::FunCtx; use crate::codegen::mod_gen::ModCtx; use crate::codegen::target_gen::TargetCtx; use crate::libcstr; pub(crate) fn gen_panic( tcx: &mut TargetCtx, mcx: &mut ModCtx<'_, '_, '_>, fcx: &mut FunCtx, message: &str, ) { unsafe { let llvm_i8 = LLVMInt8TypeInContext(tcx.llx); let llvm_i32 = LLVMInt32TypeInContext(tcx.llx); let llvm_param_types = &mut [ tcx.task_llvm_ptr_type(), LLVMPointerType(llvm_i8, 0), llvm_i32, ]; let panic_with_string_llvm_type = LLVMFunctionType( LLVMVoidTypeInContext(tcx.llx), llvm_param_types.as_mut_ptr(), llvm_param_types.len() as u32, 0, ); let panic_with_string_fun = mcx.get_function_or_insert( panic_with_string_llvm_type, b"arret_runtime_panic_with_string\0", |panic_with_string_fun| { LLVMAddAttributeAtIndex( panic_with_string_fun, LLVMAttributeFunctionIndex, tcx.llvm_enum_attr_for_name("cold", 0), ); LLVMAddAttributeAtIndex( panic_with_string_fun, LLVMAttributeFunctionIndex, tcx.llvm_enum_attr_for_name("noreturn", 0), ); }, ); let llvm_message_string = LLVMConstStringInContext(tcx.llx, message.as_ptr() as *mut _, message.len() as u32, 1); let llvm_message_global = LLVMAddGlobal( mcx.module, LLVMTypeOf(llvm_message_string), libcstr!("panic_message"), ); LLVMSetInitializer(llvm_message_global, llvm_message_string); annotate_private_global(llvm_message_global); let llvm_first_byte_gep_indices = &mut [LLVMConstInt(llvm_i32, 0, 0), LLVMConstInt(llvm_i32, 0, 0)]; let message_pointer = LLVMConstInBoundsGEP( llvm_message_global, llvm_first_byte_gep_indices.as_mut_ptr(), llvm_first_byte_gep_indices.len() as u32, ); let panic_with_string_args = &mut [ fcx.current_task, message_pointer, LLVMConstInt(llvm_i32, message.len() as u64, 0), ]; LLVMBuildCall( fcx.builder, panic_with_string_fun, panic_with_string_args.as_mut_ptr(), panic_with_string_args.len() as u32, libcstr!(""), ); LLVMBuildUnreachable(fcx.builder); } }