use fmt;
use intrinsics;
+#[cfg(stage0)]
#[cold] #[inline(never)] // this is the slow path, always
#[lang="fail_"]
fn fail_(expr: &'static str, file: &'static str, line: uint) -> ! {
unsafe { intrinsics::abort() }
}
+#[cfg(stage0)]
#[cold]
#[lang="fail_bounds_check"]
fn fail_bounds_check(file: &'static str, line: uint,
unsafe { intrinsics::abort() }
}
+#[cfg(not(stage0))]
+#[cold] #[inline(never)] // this is the slow path, always
+#[lang="fail_"]
+fn fail_(expr_file_line: &(&'static str, &'static str, uint)) -> ! {
+ let (expr, file, line) = *expr_file_line;
+ let ref file_line = (file, line);
+ format_args!(|args| -> () {
+ begin_unwind(args, file_line);
+ }, "{}", expr);
+
+ unsafe { intrinsics::abort() }
+}
+
+#[cfg(not(stage0))]
+#[cold]
+#[lang="fail_bounds_check"]
+fn fail_bounds_check(file_line: &(&'static str, uint),
+ index: uint, len: uint) -> ! {
+ format_args!(|args| -> () {
+ begin_unwind(args, file_line);
+ }, "index out of bounds: the len is {} but the index is {}", len, index);
+ unsafe { intrinsics::abort() }
+}
+
#[cold]
pub fn begin_unwind(fmt: &fmt::Arguments, file_line: &(&'static str, uint)) -> ! {
#[allow(ctypes)]
use middle::trans::cleanup::CleanupMethods;
use middle::trans::cleanup;
use middle::trans::common::*;
+use middle::trans::consts;
use middle::trans::datum;
use middle::trans::debuginfo;
use middle::trans::expr;
return bcx;
}
-fn str_slice_arg<'a>(bcx: &'a Block<'a>, s: InternedString) -> ValueRef {
- let ccx = bcx.ccx();
- let s = C_str_slice(ccx, s);
- let slot = alloca(bcx, val_ty(s), "__temp");
- Store(bcx, s, slot);
- slot
-}
-
pub fn trans_fail<'a>(
bcx: &'a Block<'a>,
sp: Span,
let ccx = bcx.ccx();
let _icx = push_ctxt("trans_fail_value");
- let v_str = str_slice_arg(bcx, fail_str);
+ let v_str = C_str_slice(ccx, fail_str);
let loc = bcx.sess().codemap().lookup_char_pos(sp.lo);
let filename = token::intern_and_get_ident(loc.file.name.as_slice());
- let v_filename = str_slice_arg(bcx, filename);
- let v_line = loc.line as int;
- let args = vec!(v_str, v_filename, C_int(ccx, v_line));
+ let filename = C_str_slice(ccx, filename);
+ let line = C_int(ccx, loc.line as int);
+ let expr_file_line_const = C_struct(ccx, &[v_str, filename, line], false);
+ let expr_file_line = consts::const_addr_of(ccx, expr_file_line_const);
+ let args = vec!(expr_file_line);
let did = langcall(bcx, Some(sp), "", FailFnLangItem);
let bcx = callee::trans_lang_call(bcx,
did,
index: ValueRef,
len: ValueRef)
-> &'a Block<'a> {
+ let ccx = bcx.ccx();
let _icx = push_ctxt("trans_fail_bounds_check");
// Extract the file/line from the span
let filename = token::intern_and_get_ident(loc.file.name.as_slice());
// Invoke the lang item
- let filename = str_slice_arg(bcx, filename);
- let line = C_int(bcx.ccx(), loc.line as int);
- let args = vec!(filename, line, index, len);
+ let filename = C_str_slice(ccx, filename);
+ let line = C_int(ccx, loc.line as int);
+ let file_line_const = C_struct(ccx, &[filename, line], false);
+ let file_line = consts::const_addr_of(ccx, file_line_const);
+ let args = vec!(file_line, index, len);
let did = langcall(bcx, Some(sp), "", FailBoundsCheckFnLangItem);
let bcx = callee::trans_lang_call(bcx,
did,