From ef25b7d5389a68d50904a8b4f4785287fc7c6ac3 Mon Sep 17 00:00:00 2001 From: Ryan Prichard Date: Sat, 11 Apr 2015 02:46:57 -0700 Subject: [PATCH] Change the rt::unwind line argument type from usize to u32. --- src/libcore/lib.rs | 2 +- src/libcore/panicking.rs | 6 ++--- src/libstd/macros.rs | 49 +++++++++++++++++++++++++++++++++++++- src/libstd/panicking.rs | 2 +- src/libstd/rt/unwind.rs | 25 +++++++++++++++---- src/libsyntax/ext/build.rs | 2 +- 6 files changed, 75 insertions(+), 11 deletions(-) diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 1b7311028f5ed..164d3e49385e7 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -38,7 +38,7 @@ //! provided by the [rlibc crate](https://crates.io/crates/rlibc). //! //! * `rust_begin_unwind` - This function takes three arguments, a -//! `fmt::Arguments`, a `&str`, and a `usize`. These three arguments dictate +//! `fmt::Arguments`, a `&str`, and a `u32`. These three arguments dictate //! the panic message, the file at which panic was invoked, and the line. //! It is up to consumers of this core library to define this panic //! function; it is only required to never return. diff --git a/src/libcore/panicking.rs b/src/libcore/panicking.rs index d6e00df1fd795..0b8a52329dce6 100644 --- a/src/libcore/panicking.rs +++ b/src/libcore/panicking.rs @@ -16,7 +16,7 @@ //! interface for panicking is: //! //! ```ignore -//! fn panic_impl(fmt: fmt::Arguments, &(&'static str, usize)) -> !; +//! fn panic_impl(fmt: fmt::Arguments, &(&'static str, u32)) -> !; //! ``` //! //! This definition allows for panicking with any general message, but it does not @@ -58,8 +58,8 @@ pub fn panic_fmt(fmt: fmt::Arguments, file_line: &(&'static str, u32)) -> ! { #[allow(improper_ctypes)] extern { #[lang = "panic_fmt"] - fn panic_impl(fmt: fmt::Arguments, file: &'static str, line: usize) -> !; + fn panic_impl(fmt: fmt::Arguments, file: &'static str, line: u32) -> !; } let (file, line) = *file_line; - unsafe { panic_impl(fmt, file, line as usize) } + unsafe { panic_impl(fmt, file, line) } } diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index 3d10c151f80d6..f3e99a8541aaa 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -38,6 +38,7 @@ #[macro_export] #[stable(feature = "rust1", since = "1.0.0")] #[allow_internal_unstable] +#[cfg(stage0)] macro_rules! panic { () => ({ panic!("explicit panic") @@ -55,7 +56,53 @@ macro_rules! panic { // used inside a dead function. Just `#[allow(dead_code)]` is // insufficient, since the user may have // `#[forbid(dead_code)]` and which cannot be overridden. - static _FILE_LINE: (&'static str, usize) = (file!(), line!() as usize); + static _FILE_LINE: (&'static str, u32) = (file!(), line!()); + &_FILE_LINE + }) + }); +} + +/// The entry point for panic of Rust tasks. +/// +/// This macro is used to inject panic into a Rust task, causing the task to +/// unwind and panic entirely. Each task's panic can be reaped as the +/// `Box` type, and the single-argument form of the `panic!` macro will be +/// the value which is transmitted. +/// +/// The multi-argument form of this macro panics with a string and has the +/// `format!` syntax for building a string. +/// +/// # Examples +/// +/// ```should_panic +/// # #![allow(unreachable_code)] +/// panic!(); +/// panic!("this is a terrible mistake!"); +/// panic!(4); // panic with the value of 4 to be collected elsewhere +/// panic!("this is a {} {message}", "fancy", message = "message"); +/// ``` +#[macro_export] +#[stable(feature = "rust1", since = "1.0.0")] +#[allow_internal_unstable] +#[cfg(not(stage0))] +macro_rules! panic { + () => ({ + panic!("explicit panic") + }); + ($msg:expr) => ({ + $crate::rt::begin_unwind($msg, { + // static requires less code at runtime, more constant data + static _FILE_LINE: (&'static str, u32) = (file!(), line!()); + &_FILE_LINE + }) + }); + ($fmt:expr, $($arg:tt)+) => ({ + $crate::rt::begin_unwind_fmt(format_args!($fmt, $($arg)+), { + // The leading _'s are to avoid dead code warnings if this is + // used inside a dead function. Just `#[allow(dead_code)]` is + // insufficient, since the user may have + // `#[forbid(dead_code)]` and which cannot be overridden. + static _FILE_LINE: (&'static str, u32) = (file!(), line!()); &_FILE_LINE }) }); diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs index 3e0584d9ab4f5..a498e634185f2 100644 --- a/src/libstd/panicking.rs +++ b/src/libstd/panicking.rs @@ -26,7 +26,7 @@ thread_local! { } } -pub fn on_panic(obj: &(Any+Send), file: &'static str, line: usize) { +pub fn on_panic(obj: &(Any+Send), file: &'static str, line: u32) { let msg = match obj.downcast_ref::<&'static str>() { Some(s) => *s, None => match obj.downcast_ref::() { diff --git a/src/libstd/rt/unwind.rs b/src/libstd/rt/unwind.rs index 2f58a437eb472..b118010a0cc15 100644 --- a/src/libstd/rt/unwind.rs +++ b/src/libstd/rt/unwind.rs @@ -78,7 +78,7 @@ struct Exception { cause: Option>, } -pub type Callback = fn(msg: &(Any + Send), file: &'static str, line: usize); +pub type Callback = fn(msg: &(Any + Send), file: &'static str, line: u32); // Variables used for invoking callbacks when a thread starts to unwind. // @@ -484,7 +484,7 @@ pub mod eabi { /// Entry point of panic from the libcore crate. #[lang = "panic_fmt"] pub extern fn rust_begin_unwind(msg: fmt::Arguments, - file: &'static str, line: usize) -> ! { + file: &'static str, line: u32) -> ! { begin_unwind_fmt(msg, &(file, line)) } @@ -495,7 +495,7 @@ pub extern fn rust_begin_unwind(msg: fmt::Arguments, /// on (e.g.) the inlining of other functions as possible), by moving /// the actual formatting into this shared place. #[inline(never)] #[cold] -pub fn begin_unwind_fmt(msg: fmt::Arguments, file_line: &(&'static str, usize)) -> ! { +pub fn begin_unwind_fmt(msg: fmt::Arguments, file_line: &(&'static str, u32)) -> ! { use fmt::Write; // We do two allocations here, unfortunately. But (a) they're @@ -510,6 +510,7 @@ pub fn begin_unwind_fmt(msg: fmt::Arguments, file_line: &(&'static str, usize)) /// This is the entry point of unwinding for panic!() and assert!(). #[inline(never)] #[cold] // avoid code bloat at the call sites as much as possible +#[cfg(stage0)] pub fn begin_unwind(msg: M, file_line: &(&'static str, usize)) -> ! { // Note that this should be the only allocation performed in this code path. // Currently this means that panic!() on OOM will invoke this code path, @@ -518,6 +519,22 @@ pub fn begin_unwind(msg: M, file_line: &(&'static str, usize)) -> // be performed in the parent of this thread instead of the thread that's // panicking. + // see below for why we do the `Any` coercion here. + let (file, line) = *file_line; + begin_unwind_inner(Box::new(msg), &(file, line as u32)) +} + +/// This is the entry point of unwinding for panic!() and assert!(). +#[inline(never)] #[cold] // avoid code bloat at the call sites as much as possible +#[cfg(not(stage0))] +pub fn begin_unwind(msg: M, file_line: &(&'static str, u32)) -> ! { + // Note that this should be the only allocation performed in this code path. + // Currently this means that panic!() on OOM will invoke this code path, + // but then again we're not really ready for panic on OOM anyway. If + // we do start doing this, then we should propagate this allocation to + // be performed in the parent of this thread instead of the thread that's + // panicking. + // see below for why we do the `Any` coercion here. begin_unwind_inner(Box::new(msg), file_line) } @@ -533,7 +550,7 @@ pub fn begin_unwind(msg: M, file_line: &(&'static str, usize)) -> /// }` from ~1900/3700 (-O/no opts) to 180/590. #[inline(never)] #[cold] // this is the slow path, please never inline this fn begin_unwind_inner(msg: Box, - file_line: &(&'static str, usize)) -> ! { + file_line: &(&'static str, u32)) -> ! { // Make sure the default failure handler is registered before we look at the // callbacks. We also use a raw sys-based mutex here instead of a // `std::sync` one as accessing TLS can cause weird recursive problems (and diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 5d0853761eec8..cde16d25412e5 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -767,7 +767,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { let loc = self.codemap().lookup_char_pos(span.lo); let expr_file = self.expr_str(span, token::intern_and_get_ident(&loc.file.name)); - let expr_line = self.expr_usize(span, loc.line); + let expr_line = self.expr_u32(span, loc.line as u32); let expr_file_line_tuple = self.expr_tuple(span, vec!(expr_file, expr_line)); let expr_file_line_ptr = self.expr_addr_of(span, expr_file_line_tuple); self.expr_call_global(