|
1 | 1 | use crate::prelude::*; |
2 | 2 |
|
| 3 | +fn codegen_print(fx: &mut FunctionCx<'_, '_, impl cranelift_module::Backend>, msg: &str) { |
| 4 | + let puts = fx.module.declare_function("puts", Linkage::Import, &Signature { |
| 5 | + call_conv: CallConv::SystemV, |
| 6 | + params: vec![AbiParam::new(pointer_ty(fx.tcx))], |
| 7 | + returns: vec![], |
| 8 | + }).unwrap(); |
| 9 | + let puts = fx.module.declare_func_in_func(puts, &mut fx.bcx.func); |
| 10 | + |
| 11 | + let symbol_name = fx.tcx.symbol_name(fx.instance); |
| 12 | + let msg_bytes = format!("trap at {:?} ({}): {}\0", fx.instance, symbol_name, msg).into_bytes().into_boxed_slice(); |
| 13 | + let mut data_ctx = DataContext::new(); |
| 14 | + data_ctx.define(msg_bytes); |
| 15 | + let msg_id = fx.module.declare_data(&(symbol_name.as_str().to_string() + msg), Linkage::Local, false).unwrap(); |
| 16 | + |
| 17 | + // Ignore DuplicateDefinition error, as the data will be the same |
| 18 | + let _ = fx.module.define_data(msg_id, &data_ctx); |
| 19 | + |
| 20 | + let local_msg_id = fx.module.declare_data_in_func(msg_id, fx.bcx.func); |
| 21 | + let msg_ptr = fx.bcx.ins().global_value(pointer_ty(fx.tcx), local_msg_id); |
| 22 | + fx.bcx.ins().call(puts, &[msg_ptr]); |
| 23 | +} |
| 24 | + |
3 | 25 | /// Trap code: user0 |
4 | | -pub fn trap_panic(bcx: &mut FunctionBuilder) { |
5 | | - bcx.ins().trap(TrapCode::User(0)); |
| 26 | +pub fn trap_panic(fx: &mut FunctionCx<'_, '_, impl cranelift_module::Backend>, msg: impl AsRef<str>) { |
| 27 | + codegen_print(fx, msg.as_ref()); |
| 28 | + fx.bcx.ins().trap(TrapCode::User(0)); |
6 | 29 | } |
7 | 30 |
|
8 | 31 | /// Trap code: user65535 |
9 | | -pub fn trap_unreachable(bcx: &mut FunctionBuilder) { |
10 | | - bcx.ins().trap(TrapCode::User(!0)); |
| 32 | +pub fn trap_unreachable(fx: &mut FunctionCx<'_, '_, impl cranelift_module::Backend>, msg: impl AsRef<str>) { |
| 33 | + codegen_print(fx, msg.as_ref()); |
| 34 | + fx.bcx.ins().trap(TrapCode::User(!0)); |
11 | 35 | } |
12 | 36 |
|
13 | | -pub fn trap_unreachable_ret_value<'tcx>(fx: &mut FunctionCx<'_, 'tcx, impl cranelift_module::Backend>, dest_layout: TyLayout<'tcx>) -> CValue<'tcx> { |
| 37 | +/// Trap code: user65535 |
| 38 | +pub fn trap_unreachable_ret_value<'tcx>(fx: &mut FunctionCx<'_, 'tcx, impl cranelift_module::Backend>, dest_layout: TyLayout<'tcx>, msg: impl AsRef<str>) -> CValue<'tcx> { |
| 39 | + codegen_print(fx, msg.as_ref()); |
14 | 40 | let true_ = fx.bcx.ins().iconst(types::I32, 1); |
15 | 41 | fx.bcx.ins().trapnz(true_, TrapCode::User(!0)); |
16 | 42 | let zero = fx.bcx.ins().iconst(fx.pointer_type, 0); |
17 | 43 | CValue::ByRef(zero, dest_layout) |
18 | 44 | } |
19 | 45 |
|
20 | | -pub fn trap_unreachable_ret_place<'tcx>(fx: &mut FunctionCx<'_, 'tcx, impl cranelift_module::Backend>, dest_layout: TyLayout<'tcx>) -> CPlace<'tcx> { |
| 46 | +/// Trap code: user65535 |
| 47 | +pub fn trap_unreachable_ret_place<'tcx>(fx: &mut FunctionCx<'_, 'tcx, impl cranelift_module::Backend>, dest_layout: TyLayout<'tcx>, msg: impl AsRef<str>) -> CPlace<'tcx> { |
| 48 | + codegen_print(fx, msg.as_ref()); |
21 | 49 | let true_ = fx.bcx.ins().iconst(types::I32, 1); |
22 | 50 | fx.bcx.ins().trapnz(true_, TrapCode::User(!0)); |
23 | 51 | let zero = fx.bcx.ins().iconst(fx.pointer_type, 0); |
|
0 commit comments