]> git.lizzy.rs Git - rust.git/commitdiff
rustc: Use rust strings for failure arguments
authorAlex Crichton <alex@alexcrichton.com>
Mon, 26 May 2014 17:33:18 +0000 (10:33 -0700)
committerAlex Crichton <alex@alexcrichton.com>
Tue, 27 May 2014 07:33:05 +0000 (00:33 -0700)
This avoids having to perform conversions from `*u8` to `&'static str` which can
suck in a good deal of code.

Closes #14442

src/libcore/failure.rs
src/librustc/middle/trans/common.rs
src/librustc/middle/trans/controlflow.rs
src/test/auxiliary/lang-item-public.rs

index 003ebed63644f67ced884a71d745412c28cae8fb..a53a380d7379831c1bd0017b96eccf732f46aedb 100644 (file)
 
 #![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), 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))]
+#[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]
index 55638b9f80a6ea75d7918b69f41e3fc7404be8ce..154a5eaa7801bfde6c0c440f304157ffd0c21e9f 100644 (file)
@@ -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))
index 419b4f1e110a2944f750e7f36718824f5ba40286..2174fe3df9a078481bd78147884cc2fef39784b9 100644 (file)
 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,
index 2c9a5bc433fb4b0fcd940d2d61c17a710116c4bd..4b19d291b85ddfc40c4deeefa945c5544f715932 100644 (file)
@@ -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() {}