diff options
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/rt/stack.rs | 38 | ||||
| -rw-r--r-- | src/libstd/rt/unwind.rs | 42 |
2 files changed, 72 insertions, 8 deletions
diff --git a/src/libstd/rt/stack.rs b/src/libstd/rt/stack.rs index b9bcd1de8fc..b3be742e1ed 100644 --- a/src/libstd/rt/stack.rs +++ b/src/libstd/rt/stack.rs @@ -30,12 +30,9 @@ pub static RED_ZONE: uint = 20 * 1024; /// stacks are currently not enabled as segmented stacks, but rather one giant /// stack segment. This means that whenever we run out of stack, we want to /// truly consider it to be stack overflow rather than allocating a new stack. -#[no_mangle] // - this is called from C code -#[no_split_stack] // - it would be sad for this function to trigger __morestack -#[doc(hidden)] // - Function must be `pub` to get exported, but it's - // irrelevant for documentation purposes. -#[cfg(not(test))] // in testing, use the original libstd's version -pub extern "C" fn rust_stack_exhausted() { +#[cfg(not(test), not(stage0))] // in testing, use the original libstd's version +#[lang = "stack_exhausted"] +extern fn stack_exhausted() { use option::{Option, None, Some}; use owned::Box; use rt::local::Local; @@ -106,6 +103,35 @@ pub extern "C" fn rust_stack_exhausted() { } } +#[no_mangle] // - this is called from C code +#[no_split_stack] // - it would be sad for this function to trigger __morestack +#[doc(hidden)] // - Function must be `pub` to get exported, but it's + // irrelevant for documentation purposes. +#[cfg(stage0, not(test))] // in testing, use the original libstd's version +pub extern "C" fn rust_stack_exhausted() { + use option::{Option, None, Some}; + use owned::Box; + use rt::local::Local; + use rt::task::Task; + use str::Str; + use intrinsics; + + unsafe { + let limit = get_sp_limit(); + record_sp_limit(limit - RED_ZONE / 2); + let task: Option<Box<Task>> = Local::try_take(); + let name = match task { + Some(ref task) => { + task.name.as_ref().map(|n| n.as_slice()) + } + None => None + }; + let name = name.unwrap_or("<unknown>"); + rterrln!("task '{}' has overflowed its stack", name); + intrinsics::abort(); + } +} + #[inline(always)] pub unsafe fn record_stack_bounds(stack_lo: uint, stack_hi: uint) { // When the old runtime had segmented stacks, it used a calculation that was diff --git a/src/libstd/rt/unwind.rs b/src/libstd/rt/unwind.rs index 1cc513825a7..af87a31b7bd 100644 --- a/src/libstd/rt/unwind.rs +++ b/src/libstd/rt/unwind.rs @@ -212,7 +212,23 @@ pub mod eabi { } #[lang="eh_personality"] + #[cfg(not(stage0))] + extern fn eh_personality( + version: c_int, + actions: uw::_Unwind_Action, + exception_class: uw::_Unwind_Exception_Class, + ue_header: *uw::_Unwind_Exception, + context: *uw::_Unwind_Context + ) -> uw::_Unwind_Reason_Code + { + unsafe { + __gcc_personality_v0(version, actions, exception_class, ue_header, + context) + } + } + #[lang="eh_personality"] #[no_mangle] // so we can reference it by name from middle/trans/base.rs + #[cfg(stage0)] pub extern "C" fn rust_eh_personality( version: c_int, actions: uw::_Unwind_Action, @@ -264,7 +280,21 @@ pub mod eabi { } #[lang="eh_personality"] + #[cfg(not(stage0))] + extern "C" fn eh_personality( + state: uw::_Unwind_State, + ue_header: *uw::_Unwind_Exception, + context: *uw::_Unwind_Context + ) -> uw::_Unwind_Reason_Code + { + unsafe { + __gcc_personality_v0(state, ue_header, context) + } + } + + #[lang="eh_personality"] #[no_mangle] // so we can reference it by name from middle/trans/base.rs + #[cfg(stage0)] pub extern "C" fn rust_eh_personality( state: uw::_Unwind_State, ue_header: *uw::_Unwind_Exception, @@ -296,8 +326,15 @@ pub mod eabi { } // Entry point of failure from the libcore crate +#[cfg(not(test), not(stage0))] +#[lang = "begin_unwind"] +pub extern fn rust_begin_unwind(msg: &fmt::Arguments, + file: &'static str, line: uint) -> ! { + begin_unwind_fmt(msg, file, line) +} + #[no_mangle] -#[cfg(not(test))] +#[cfg(not(test), stage0)] pub extern fn rust_begin_unwind(msg: &fmt::Arguments, file: &'static str, line: uint) -> ! { begin_unwind_fmt(msg, file, line) @@ -310,7 +347,8 @@ 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: &'static str, line: uint) -> ! { +pub fn begin_unwind_fmt(msg: &fmt::Arguments, file: &'static str, + line: uint) -> ! { // We do two allocations here, unfortunately. But (a) they're // required with the current scheme, and (b) we don't handle // failure + OOM properly anyway (see comment in begin_unwind |
