rustc: Use rust strings for failure arguments
This avoids having to perform conversions from `*u8` to `&'static str` which can suck in a good deal of code. Closes #14442
This commit is contained in:
parent
746d086f93
commit
5c1a70d498
@ -28,13 +28,25 @@
|
||||
|
||||
#![allow(dead_code, missing_doc)]
|
||||
|
||||
#[cfg(not(test))]
|
||||
use str::raw::c_str_to_static_slice;
|
||||
use fmt;
|
||||
use intrinsics;
|
||||
#[cfg(not(test), stage0)]
|
||||
use str::raw::c_str_to_static_slice;
|
||||
|
||||
#[cold] #[inline(never)] // this is the slow path, always
|
||||
#[lang="fail_"]
|
||||
#[cfg(not(test))]
|
||||
#[cfg(not(test), not(stage0))]
|
||||
fn fail_(expr: &'static str, file: &'static str, line: uint) -> ! {
|
||||
format_args!(|args| -> () {
|
||||
begin_unwind(args, file, line);
|
||||
}, "{}", expr);
|
||||
|
||||
unsafe { intrinsics::abort() }
|
||||
}
|
||||
|
||||
#[cold] #[inline(never)] // this is the slow path, always
|
||||
#[lang="fail_"]
|
||||
#[cfg(not(test), stage0)]
|
||||
fn fail_(expr: *u8, file: *u8, line: uint) -> ! {
|
||||
unsafe {
|
||||
let expr = c_str_to_static_slice(expr as *i8);
|
||||
@ -43,19 +55,30 @@ fn fail_(expr: *u8, file: *u8, line: uint) -> ! {
|
||||
begin_unwind(args, file, line);
|
||||
}, "{}", expr);
|
||||
|
||||
loop {}
|
||||
intrinsics::abort()
|
||||
}
|
||||
}
|
||||
|
||||
#[cold]
|
||||
#[lang="fail_bounds_check"]
|
||||
#[cfg(not(test))]
|
||||
#[cfg(not(test), not(stage0))]
|
||||
fn fail_bounds_check(file: &'static str, line: 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]
|
||||
#[lang="fail_bounds_check"]
|
||||
#[cfg(not(test), stage0)]
|
||||
fn fail_bounds_check(file: *u8, line: uint, index: uint, len: uint) -> ! {
|
||||
let file = unsafe { c_str_to_static_slice(file as *i8) };
|
||||
format_args!(|args| -> () {
|
||||
begin_unwind(args, file, line);
|
||||
}, "index out of bounds: the len is {} but the index is {}", len, index);
|
||||
loop {}
|
||||
unsafe { intrinsics::abort() }
|
||||
}
|
||||
|
||||
#[cold]
|
||||
|
@ -596,7 +596,8 @@ pub fn C_cstr(cx: &CrateContext, s: InternedString, null_terminated: bool) -> Va
|
||||
pub fn C_str_slice(cx: &CrateContext, s: InternedString) -> ValueRef {
|
||||
unsafe {
|
||||
let len = s.get().len();
|
||||
let cs = llvm::LLVMConstPointerCast(C_cstr(cx, s, false), Type::i8p(cx).to_ref());
|
||||
let cs = llvm::LLVMConstPointerCast(C_cstr(cx, s, false),
|
||||
Type::i8p(cx).to_ref());
|
||||
C_struct(cx, [cs, C_uint(cx, len)], false)
|
||||
}
|
||||
}
|
||||
@ -843,19 +844,6 @@ pub fn find_vtable(tcx: &ty::ctxt,
|
||||
param_bounds.get(n_bound).clone()
|
||||
}
|
||||
|
||||
pub fn filename_and_line_num_from_span(bcx: &Block, span: Span)
|
||||
-> (ValueRef, ValueRef) {
|
||||
let loc = bcx.sess().codemap().lookup_char_pos(span.lo);
|
||||
let filename_cstr = C_cstr(bcx.ccx(),
|
||||
token::intern_and_get_ident(loc.file
|
||||
.name
|
||||
.as_slice()),
|
||||
true);
|
||||
let filename = build::PointerCast(bcx, filename_cstr, Type::i8p(bcx.ccx()));
|
||||
let line = C_int(bcx.ccx(), loc.line as int);
|
||||
(filename, line)
|
||||
}
|
||||
|
||||
// Casts a Rust bool value to an i1.
|
||||
pub fn bool_to_i1(bcx: &Block, llval: ValueRef) -> ValueRef {
|
||||
build::ICmp(bcx, lib::llvm::IntNE, llval, C_bool(bcx.ccx(), false))
|
||||
|
@ -14,16 +14,15 @@ use middle::lang_items::{FailFnLangItem, FailBoundsCheckFnLangItem};
|
||||
use middle::trans::base::*;
|
||||
use middle::trans::build::*;
|
||||
use middle::trans::callee;
|
||||
use middle::trans::cleanup::CleanupMethods;
|
||||
use middle::trans::cleanup;
|
||||
use middle::trans::common::*;
|
||||
use middle::trans::debuginfo;
|
||||
use middle::trans::cleanup;
|
||||
use middle::trans::cleanup::CleanupMethods;
|
||||
use middle::trans::expr;
|
||||
use middle::trans::type_of;
|
||||
use middle::ty;
|
||||
use util::ppaux::Repr;
|
||||
|
||||
use middle::trans::type_::Type;
|
||||
|
||||
use syntax::ast;
|
||||
use syntax::ast::Ident;
|
||||
use syntax::ast_util;
|
||||
@ -337,23 +336,31 @@ pub fn trans_ret<'a>(bcx: &'a Block<'a>,
|
||||
return bcx;
|
||||
}
|
||||
|
||||
fn str_slice_arg<'a>(bcx: &'a Block<'a>, s: InternedString) -> ValueRef {
|
||||
let ccx = bcx.ccx();
|
||||
let t = ty::mk_str_slice(bcx.tcx(), ty::ReStatic, ast::MutImmutable);
|
||||
let s = C_str_slice(ccx, s);
|
||||
let slot = alloca(bcx, val_ty(s), "__temp");
|
||||
Store(bcx, s, slot);
|
||||
|
||||
// The type of C_str_slice is { i8*, i64 }, but the type of the &str is
|
||||
// %str_slice, so we do a bitcast here to the right type.
|
||||
BitCast(bcx, slot, type_of::type_of(ccx, t).ptr_to())
|
||||
}
|
||||
|
||||
pub fn trans_fail<'a>(
|
||||
bcx: &'a Block<'a>,
|
||||
sp: Span,
|
||||
fail_str: InternedString)
|
||||
-> &'a Block<'a> {
|
||||
let ccx = bcx.ccx();
|
||||
let v_fail_str = C_cstr(ccx, fail_str, true);
|
||||
let _icx = push_ctxt("trans_fail_value");
|
||||
|
||||
let v_str = str_slice_arg(bcx, fail_str);
|
||||
let loc = bcx.sess().codemap().lookup_char_pos(sp.lo);
|
||||
let v_filename = C_cstr(ccx,
|
||||
token::intern_and_get_ident(loc.file
|
||||
.name
|
||||
.as_slice()),
|
||||
true);
|
||||
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 v_str = PointerCast(bcx, v_fail_str, Type::i8p(ccx));
|
||||
let v_filename = PointerCast(bcx, v_filename, Type::i8p(ccx));
|
||||
let args = vec!(v_str, v_filename, C_int(ccx, v_line));
|
||||
let did = langcall(bcx, Some(sp), "", FailFnLangItem);
|
||||
let bcx = callee::trans_lang_call(bcx,
|
||||
@ -371,7 +378,14 @@ pub fn trans_fail_bounds_check<'a>(
|
||||
len: ValueRef)
|
||||
-> &'a Block<'a> {
|
||||
let _icx = push_ctxt("trans_fail_bounds_check");
|
||||
let (filename, line) = filename_and_line_num_from_span(bcx, sp);
|
||||
|
||||
// Extract the file/line from the span
|
||||
let loc = bcx.sess().codemap().lookup_char_pos(sp.lo);
|
||||
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 did = langcall(bcx, Some(sp), "", FailBoundsCheckFnLangItem);
|
||||
let bcx = callee::trans_lang_call(bcx,
|
||||
|
@ -11,7 +11,7 @@
|
||||
#![no_std]
|
||||
|
||||
#[lang="fail_"]
|
||||
fn fail(_: *i8, _: *i8, _: uint) -> ! { loop {} }
|
||||
fn fail(_: &'static str, _: &'static str, _: uint) -> ! { loop {} }
|
||||
|
||||
#[lang = "stack_exhausted"]
|
||||
extern fn stack_exhausted() {}
|
||||
|
Loading…
Reference in New Issue
Block a user