Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support panicking and make unsupported platforms a nop #5

Closed
wants to merge 12 commits into from
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "stacker"
version = "0.1.3"
version = "0.2.0"
alexcrichton marked this conversation as resolved.
Show resolved Hide resolved
authors = ["Alex Crichton <alex@alexcrichton.com>"]
build = "build.rs"
license = "MIT/Apache-2.0"
Expand Down
6 changes: 1 addition & 5 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@ fn main() {
cfg.define("APPLE", None);
} else if target.contains("windows") {
cfg.define("WINDOWS", None);
} else {
panic!("\n\nusing currently unsupported target triple with \
stacker: {}\n\n", target);
oli-obk marked this conversation as resolved.
Show resolved Hide resolved
}

if target.starts_with("x86_64") {
Expand All @@ -26,8 +23,7 @@ fn main() {
cfg.file(if msvc {"src/arch/i686.asm"} else {"src/arch/i686.S"});
cfg.define("X86", None);
} else {
panic!("\n\nusing currently unsupported target triple with \
stacker: {}\n\n", target);
cfg.file("fallback.rs");
oli-obk marked this conversation as resolved.
Show resolved Hide resolved
}

cfg.include("src/arch").compile("libstacker.a");
Expand Down
13 changes: 13 additions & 0 deletions src/arch/fallback.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#[no_mangle]
extern fn __stacker_stack_pointer() -> usize {
0
}

#[no_mangle]
unsafe extern fn __stacker_switch_stacks(
_new_stack: usize,
fnptr: unsafe fn(&mut &mut FnMut()),
dataptr: &mut &mut FnMut(),
) {
fnptr(dataptr)
}
19 changes: 13 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@
//! // guaranteed to have at least 32K of stack
//! });
//! ```
//!
//! # Platform support
//!
//! Only Windows, MacOS and Linux are supported. Other platforms don't do anything
//! and will overflow your stack.

#![allow(improper_ctypes)]

Expand Down Expand Up @@ -60,9 +65,7 @@ fn set_stack_limit(l: usize) {
///
/// The closure `f` is guaranteed to run on a stack with at least `red_zone`
/// bytes, and it will be run on the current stack if there's space available.
pub fn maybe_grow<R, F: FnOnce() -> R>(red_zone: usize,
stack_size: usize,
f: F) -> R {
pub fn maybe_grow<R, F: FnOnce() -> R>(red_zone: usize, stack_size: usize, f: F) -> R {
if remaining_stack() >= red_zone {
f()
} else {
Expand All @@ -86,10 +89,14 @@ fn grow_the_stack<R, F: FnOnce() -> R>(stack_size: usize, f: F) -> R {
let mut ret = None;
unsafe {
_grow_the_stack(stack_size, &mut || {
ret = Some(f.take().unwrap()());
let f: F = f.take().unwrap();
ret = Some(std::panic::catch_unwind(std::panic::AssertUnwindSafe(f)));
});
}
ret.unwrap()
match ret.unwrap() {
Ok(ret) => ret,
Err(payload) => std::panic::resume_unwind(payload),
}
}

unsafe fn _grow_the_stack(stack_size: usize, mut f: &mut FnMut()) {
Expand Down Expand Up @@ -177,7 +184,7 @@ cfg_if! {
}
} else {
unsafe fn guess_os_stack_limit() -> usize {
panic!("cannot guess the stack limit on this platform");
0
alexcrichton marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
27 changes: 27 additions & 0 deletions tests/panic_handling.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
extern crate stacker;

const RED_ZONE: usize = 100*1024; // 100k
const STACK_PER_RECURSION: usize = 1 * 1024 * 1024; // 1MB

pub fn ensure_sufficient_stack<R, F: FnOnce() -> R + std::panic::UnwindSafe>(
f: F
) -> R {
stacker::maybe_grow(RED_ZONE, STACK_PER_RECURSION, f)
}

#[inline(never)]
fn recurse(n: usize) {
let x = [42u8; 50000];
if n == 0 {
panic!("an inconvenient time");
} else {
ensure_sufficient_stack(|| recurse(n - 1));
}
drop(x);
}

#[test]
#[should_panic]
fn foo() {
recurse(10000);
}