diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2016-04-08 16:18:40 -0700 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2016-05-09 08:22:36 -0700 |
| commit | 0ec321f7b541fcbfbf20286beb497e6d9d3352b2 (patch) | |
| tree | 30abd6498f7e3ae65fa94057e2bd46f6c769fcf2 /src/librustc/session | |
| parent | 32683ce1930ef1390f20e4ab72650e6804fd1c1b (diff) | |
| download | rust-0ec321f7b541fcbfbf20286beb497e6d9d3352b2.tar.gz rust-0ec321f7b541fcbfbf20286beb497e6d9d3352b2.zip | |
rustc: Implement custom panic runtimes
This commit is an implementation of [RFC 1513] which allows applications to alter the behavior of panics at compile time. A new compiler flag, `-C panic`, is added and accepts the values `unwind` or `panic`, with the default being `unwind`. This model affects how code is generated for the local crate, skipping generation of landing pads with `-C panic=abort`. [RFC 1513]: https://github.com/rust-lang/rfcs/blob/master/text/1513-less-unwinding.md Panic implementations are then provided by crates tagged with `#![panic_runtime]` and lazily required by crates with `#![needs_panic_runtime]`. The panic strategy (`-C panic` value) of the panic runtime must match the final product, and if the panic strategy is not `abort` then the entire DAG must have the same panic strategy. With the `-C panic=abort` strategy, users can expect a stable method to disable generation of landing pads, improving optimization in niche scenarios, decreasing compile time, and decreasing output binary size. With the `-C panic=unwind` strategy users can expect the existing ability to isolate failure in Rust code from the outside world. Organizationally, this commit dismantles the `sys_common::unwind` module in favor of some bits moving part of it to `libpanic_unwind` and the rest into the `panicking` module in libstd. The custom panic runtime support is pretty similar to the custom allocator support with the only major difference being how the panic runtime is injected (takes the `-C panic` flag into account).
Diffstat (limited to 'src/librustc/session')
| -rw-r--r-- | src/librustc/session/config.rs | 30 | ||||
| -rw-r--r-- | src/librustc/session/mod.rs | 11 |
2 files changed, 37 insertions, 4 deletions
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 1a2c1b9a095..82e5ce07b13 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -317,6 +317,21 @@ impl Passes { } } +#[derive(Clone, PartialEq)] +pub enum PanicStrategy { + Unwind, + Abort, +} + +impl PanicStrategy { + pub fn desc(&self) -> &str { + match *self { + PanicStrategy::Unwind => "unwind", + PanicStrategy::Abort => "abort", + } + } +} + /// Declare a macro that will define all CodegenOptions/DebuggingOptions fields and parsers all /// at once. The goal of this macro is to define an interface that can be /// programmatically used by the option parser in order to initialize the struct @@ -402,11 +417,13 @@ macro_rules! options { Some("a space-separated list of passes, or `all`"); pub const parse_opt_uint: Option<&'static str> = Some("a number"); + pub const parse_panic_strategy: Option<&'static str> = + Some("either `panic` or `abort`"); } #[allow(dead_code)] mod $mod_set { - use super::{$struct_name, Passes, SomePasses, AllPasses}; + use super::{$struct_name, Passes, SomePasses, AllPasses, PanicStrategy}; $( pub fn $opt(cg: &mut $struct_name, v: Option<&str>) -> bool { @@ -510,6 +527,15 @@ macro_rules! options { } } } + + fn parse_panic_strategy(slot: &mut PanicStrategy, v: Option<&str>) -> bool { + match v { + Some("unwind") => *slot = PanicStrategy::Unwind, + Some("abort") => *slot = PanicStrategy::Abort, + _ => return false + } + true + } } ) } @@ -575,6 +601,8 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options, "explicitly enable the cfg(debug_assertions) directive"), inline_threshold: Option<usize> = (None, parse_opt_uint, "set the inlining threshold for"), + panic: PanicStrategy = (PanicStrategy::Unwind, parse_panic_strategy, + "panic strategy to compile crate with"), } diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index edb1c4530c2..1bea01c4849 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -12,6 +12,7 @@ use lint; use middle::cstore::CrateStore; use middle::dependency_format; use session::search_paths::PathKind; +use session::config::PanicStrategy; use ty::tls; use util::nodemap::{NodeMap, FnvHashMap}; use mir::transform as mir_pass; @@ -82,9 +83,11 @@ pub struct Session { /// operations such as auto-dereference and monomorphization. pub recursion_limit: Cell<usize>, - /// The metadata::creader module may inject an allocator dependency if it - /// didn't already find one, and this tracks what was injected. + /// The metadata::creader module may inject an allocator/panic_runtime + /// dependency if it didn't already find one, and this tracks what was + /// injected. pub injected_allocator: Cell<Option<ast::CrateNum>>, + pub injected_panic_runtime: Cell<Option<ast::CrateNum>>, /// Names of all bang-style macros and syntax extensions /// available in this crate @@ -295,7 +298,8 @@ impl Session { self.opts.cg.lto } pub fn no_landing_pads(&self) -> bool { - self.opts.debugging_opts.no_landing_pads + self.opts.debugging_opts.no_landing_pads || + self.opts.cg.panic == PanicStrategy::Abort } pub fn unstable_options(&self) -> bool { self.opts.debugging_opts.unstable_options @@ -502,6 +506,7 @@ pub fn build_session_(sopts: config::Options, recursion_limit: Cell::new(64), next_node_id: Cell::new(1), injected_allocator: Cell::new(None), + injected_panic_runtime: Cell::new(None), available_macros: RefCell::new(HashSet::new()), imported_macro_spans: RefCell::new(HashMap::new()), }; |
