about summary refs log tree commit diff
path: root/src/libstd/rt
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2015-05-12 15:52:33 -0700
committerAlex Crichton <alex@alexcrichton.com>2015-05-19 10:53:07 -0700
commit74f4f395aefd1054b8d8974a128007d0671e9d78 (patch)
tree04cb70af0c63aa522ba89227e975944c656234ce /src/libstd/rt
parent3d32cf5d9afdd8c375935ac875b2a20f24159e52 (diff)
downloadrust-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.rs33
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>;