diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2015-05-12 15:52:33 -0700 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2015-05-19 10:53:07 -0700 |
| commit | 74f4f395aefd1054b8d8974a128007d0671e9d78 (patch) | |
| tree | 04cb70af0c63aa522ba89227e975944c656234ce /src/libstd/rt | |
| parent | 3d32cf5d9afdd8c375935ac875b2a20f24159e52 (diff) | |
| download | rust-74f4f395aefd1054b8d8974a128007d0671e9d78.tar.gz rust-74f4f395aefd1054b8d8974a128007d0671e9d78.zip | |
std: Don't require rust_try as an exported symbol
This commit adds a small non-generic non-inlineable shim function to `rt::unwind::try` which the compiler can take care of for managing the exported symbol instead of having to edit `src/rt/rust_try.ll`
Diffstat (limited to 'src/libstd/rt')
| -rw-r--r-- | src/libstd/rt/unwind/mod.rs | 33 |
1 files changed, 24 insertions, 9 deletions
diff --git a/src/libstd/rt/unwind/mod.rs b/src/libstd/rt/unwind/mod.rs index 9cbe6c40483..576035ffe9a 100644 --- a/src/libstd/rt/unwind/mod.rs +++ b/src/libstd/rt/unwind/mod.rs @@ -127,16 +127,31 @@ extern {} /// run. pub unsafe fn try<F: FnOnce()>(f: F) -> Result<(), Box<Any + Send>> { let mut f = Some(f); + return inner_try(try_fn::<F>, &mut f as *mut _ as *mut c_void); - let prev = PANICKING.with(|s| s.get()); - PANICKING.with(|s| s.set(false)); - let ep = rust_try(try_fn::<F>, &mut f as *mut _ as *mut c_void); - PANICKING.with(|s| s.set(prev)); - return if ep.is_null() { - Ok(()) - } else { - Err(imp::cleanup(ep)) - }; + // If an inner function were not used here, then this generic function `try` + // uses the native symbol `rust_try`, for which the code is statically + // linked into the standard library. This means that the DLL for the + // standard library must have `rust_try` as an exposed symbol that + // downstream crates can link against (because monomorphizations of `try` in + // downstream crates will have a reference to the `rust_try` symbol). + // + // On MSVC this requires the symbol `rust_try` to be tagged with + // `dllexport`, but it's easier to not have conditional `src/rt/rust_try.ll` + // files and instead just have this non-generic shim the compiler can take + // care of exposing correctly. + unsafe fn inner_try(f: extern fn(*mut c_void), data: *mut c_void) + -> Result<(), Box<Any + Send>> { + let prev = PANICKING.with(|s| s.get()); + PANICKING.with(|s| s.set(false)); + let ep = rust_try(f, data); + PANICKING.with(|s| s.set(prev)); + if ep.is_null() { + Ok(()) + } else { + Err(imp::cleanup(ep)) + } + } extern fn try_fn<F: FnOnce()>(opt_closure: *mut c_void) { let opt_closure = opt_closure as *mut Option<F>; |
