parent
7dbbfe668f
commit
7031c96fb3
7 changed files with 79 additions and 43 deletions
|
|
@ -13,7 +13,7 @@ use mini_core::*;
|
|||
macro_rules! assert_eq {
|
||||
($l:expr, $r: expr) => {
|
||||
if $l != $r {
|
||||
panic(&(stringify!($l != $r), file!(), line!(), 0));
|
||||
panic(stringify!($l != $r));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#![feature(
|
||||
no_core, lang_items, intrinsics, unboxed_closures, type_ascription, extern_types,
|
||||
untagged_unions, decl_macro, rustc_attrs, transparent_unions, optin_builtin_traits,
|
||||
thread_local,
|
||||
thread_local, track_caller
|
||||
)]
|
||||
#![no_core]
|
||||
#![allow(dead_code)]
|
||||
|
|
@ -394,9 +394,19 @@ pub trait FnMut<Args>: FnOnce<Args> {
|
|||
}
|
||||
|
||||
#[lang = "panic"]
|
||||
pub fn panic(&(_msg, _file, _line, _col): &(&'static str, &'static str, u32, u32)) -> ! {
|
||||
#[track_caller]
|
||||
pub fn panic(msg: &str) -> ! {
|
||||
unsafe {
|
||||
libc::puts("Panicking\0" as *const str as *const u8);
|
||||
libc::puts("Panicking\n\0" as *const str as *const u8);
|
||||
intrinsics::abort();
|
||||
}
|
||||
}
|
||||
|
||||
#[lang = "panic_bounds_check"]
|
||||
#[track_caller]
|
||||
fn panic_bounds_check(index: usize, len: usize) -> ! {
|
||||
unsafe {
|
||||
libc::printf("index out of bounds: the len is %d but the index is %d\n\0" as *const str as *const i8, len, index);
|
||||
intrinsics::abort();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ static NUM_REF: &'static u8 = unsafe { &NUM };
|
|||
macro_rules! assert {
|
||||
($e:expr) => {
|
||||
if !$e {
|
||||
panic(&(stringify!(! $e), file!(), line!(), 0));
|
||||
panic(stringify!(! $e));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
@ -105,7 +105,7 @@ macro_rules! assert {
|
|||
macro_rules! assert_eq {
|
||||
($l:expr, $r: expr) => {
|
||||
if $l != $r {
|
||||
panic(&(stringify!($l != $r), file!(), line!(), 0));
|
||||
panic(stringify!($l != $r));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -206,7 +206,7 @@ impl<'tcx, B: Backend + 'static> FunctionCx<'_, 'tcx, B> {
|
|||
func_ref
|
||||
}
|
||||
|
||||
fn lib_call(
|
||||
pub(crate) fn lib_call(
|
||||
&mut self,
|
||||
name: &str,
|
||||
input_tys: Vec<types::Type>,
|
||||
|
|
|
|||
38
src/base.rs
38
src/base.rs
|
|
@ -241,14 +241,36 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, impl Backend>) {
|
|||
fx.bcx.ins().jump(target, &[]);
|
||||
|
||||
fx.bcx.switch_to_block(failure);
|
||||
trap_panic(
|
||||
fx,
|
||||
format!(
|
||||
"[panic] Assert {:?} at {:?} failed.",
|
||||
msg,
|
||||
bb_data.terminator().source_info.span
|
||||
),
|
||||
);
|
||||
|
||||
let location = fx.get_caller_location(bb_data.terminator().source_info.span).load_scalar(fx);
|
||||
|
||||
let args;
|
||||
let lang_item = match msg {
|
||||
AssertKind::BoundsCheck { ref len, ref index } => {
|
||||
let len = trans_operand(fx, len).load_scalar(fx);
|
||||
let index = trans_operand(fx, index).load_scalar(fx);
|
||||
args = [index, len, location];
|
||||
rustc_hir::lang_items::PanicBoundsCheckFnLangItem
|
||||
}
|
||||
_ => {
|
||||
let msg_str = msg.description();
|
||||
let msg_ptr = fx.anonymous_str("assert", msg_str);
|
||||
let msg_len = fx.bcx.ins().iconst(fx.pointer_type, i64::try_from(msg_str.len()).unwrap());
|
||||
args = [msg_ptr, msg_len, location];
|
||||
rustc_hir::lang_items::PanicFnLangItem
|
||||
}
|
||||
};
|
||||
|
||||
let def_id = fx.tcx.lang_items().require(lang_item).unwrap_or_else(|s| {
|
||||
fx.tcx.sess.span_fatal(bb_data.terminator().source_info.span, &s)
|
||||
});
|
||||
|
||||
let instance = Instance::mono(fx.tcx, def_id);
|
||||
let symbol_name = fx.tcx.symbol_name(instance).name.as_str();
|
||||
|
||||
fx.lib_call(&*symbol_name, vec![fx.pointer_type, fx.pointer_type, fx.pointer_type], vec![], &args);
|
||||
|
||||
crate::trap::trap_unreachable(fx, "panic lang item returned");
|
||||
}
|
||||
|
||||
TerminatorKind::SwitchInt {
|
||||
|
|
|
|||
|
|
@ -410,4 +410,35 @@ impl<'tcx, B: Backend + 'static> FunctionCx<'_, 'tcx, B> {
|
|||
pub(crate) fn triple(&self) -> &target_lexicon::Triple {
|
||||
self.module.isa().triple()
|
||||
}
|
||||
|
||||
pub(crate) fn anonymous_str(&mut self, prefix: &str, msg: &str) -> Value {
|
||||
use std::collections::hash_map::DefaultHasher;
|
||||
use std::hash::{Hash, Hasher};
|
||||
|
||||
let mut hasher = DefaultHasher::new();
|
||||
msg.hash(&mut hasher);
|
||||
let msg_hash = hasher.finish();
|
||||
let mut data_ctx = DataContext::new();
|
||||
data_ctx.define(msg.as_bytes().to_vec().into_boxed_slice());
|
||||
let msg_id = self
|
||||
.module
|
||||
.declare_data(
|
||||
&format!("__{}_{:08x}", prefix, msg_hash),
|
||||
Linkage::Local,
|
||||
false,
|
||||
false,
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// Ignore DuplicateDefinition error, as the data will be the same
|
||||
let _ = self.module.define_data(msg_id, &data_ctx);
|
||||
|
||||
let local_msg_id = self.module.declare_data_in_func(msg_id, self.bcx.func);
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
self.add_comment(local_msg_id, msg);
|
||||
}
|
||||
self.bcx.ins().global_value(self.pointer_type, local_msg_id)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
29
src/trap.rs
29
src/trap.rs
|
|
@ -1,6 +1,3 @@
|
|||
use std::collections::hash_map::DefaultHasher;
|
||||
use std::hash::{Hash, Hasher};
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
fn codegen_print(fx: &mut FunctionCx<'_, '_, impl cranelift_module::Backend>, msg: &str) {
|
||||
|
|
@ -24,31 +21,7 @@ fn codegen_print(fx: &mut FunctionCx<'_, '_, impl cranelift_module::Backend>, ms
|
|||
|
||||
let symbol_name = fx.tcx.symbol_name(fx.instance);
|
||||
let real_msg = format!("trap at {:?} ({}): {}\0", fx.instance, symbol_name, msg);
|
||||
let mut hasher = DefaultHasher::new();
|
||||
real_msg.hash(&mut hasher);
|
||||
let msg_hash = hasher.finish();
|
||||
let mut data_ctx = DataContext::new();
|
||||
data_ctx.define(real_msg.as_bytes().to_vec().into_boxed_slice());
|
||||
let msg_id = fx
|
||||
.module
|
||||
.declare_data(
|
||||
&format!("__trap_{:08x}", msg_hash),
|
||||
Linkage::Local,
|
||||
false,
|
||||
false,
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// Ignore DuplicateDefinition error, as the data will be the same
|
||||
let _ = fx.module.define_data(msg_id, &data_ctx);
|
||||
|
||||
let local_msg_id = fx.module.declare_data_in_func(msg_id, fx.bcx.func);
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
fx.add_comment(local_msg_id, msg);
|
||||
}
|
||||
let msg_ptr = fx.bcx.ins().global_value(pointer_ty(fx.tcx), local_msg_id);
|
||||
let msg_ptr = fx.anonymous_str("trap", &real_msg);
|
||||
fx.bcx.ins().call(puts, &[msg_ptr]);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue