]> git.lizzy.rs Git - rust.git/commitdiff
Apply review feedback
authorAmanieu d'Antras <amanieu@gmail.com>
Tue, 7 Jan 2020 10:36:57 +0000 (11:36 +0100)
committerAmanieu d'Antras <amanieu@gmail.com>
Sat, 11 Jan 2020 10:18:44 +0000 (10:18 +0000)
src/libpanic_unwind/emcc.rs
src/libpanic_unwind/seh.rs
src/librustc_codegen_llvm/intrinsic.rs

index 61f33fd4d5d664dc02d3af55c6c7662d06daee69..fbadf4ac6a058dd50e1d4a01789c917f3132b600 100644 (file)
@@ -53,6 +53,10 @@ pub fn payload() -> *mut u8 {
 }
 
 struct Exception {
+    // This needs to be an Option because the object's lifetime follows C++
+    // semantics: when catch_unwind moves the Box out of the exception it must
+    // still leave the exception object in a valid state because its destructor
+    // is still going to be called by __cxa_end_catch..
     data: Option<Box<dyn Any + Send>>,
 }
 
index ef27e38c2d1d604d0c80f47c0f51cebade827389..f1d0080472a01a6dbadb8849ca5a90ad440e1bc7 100644 (file)
@@ -224,33 +224,28 @@ pub struct _TypeDescriptor {
 // used as the result of the exception copy. This is used by the C++ runtime to
 // support capturing exceptions with std::exception_ptr, which we can't support
 // because Box<dyn Any> isn't clonable.
-cfg_if::cfg_if! {
-    if #[cfg(target_arch = "x86")] {
-        unsafe extern "thiscall" fn exception_cleanup(e: *mut [u64; 2]) {
-            if (*e)[0] != 0 {
-                cleanup(*e);
-            }
-        }
-        #[unwind(allowed)]
-        unsafe extern "thiscall" fn exception_copy(_dest: *mut [u64; 2],
-                                                   _src: *mut [u64; 2])
-                                                   -> *mut [u64; 2] {
-            panic!("Rust panics cannot be copied");
-        }
-    } else {
-        unsafe extern "C" fn exception_cleanup(e: *mut [u64; 2]) {
+macro_rules! define_cleanup {
+    ($abi:tt) => {
+        unsafe extern $abi fn exception_cleanup(e: *mut [u64; 2]) {
             if (*e)[0] != 0 {
                 cleanup(*e);
             }
         }
         #[unwind(allowed)]
-        unsafe extern "C" fn exception_copy(_dest: *mut [u64; 2],
-                                            _src: *mut [u64; 2])
-                                            -> *mut [u64; 2] {
+        unsafe extern $abi fn exception_copy(_dest: *mut [u64; 2],
+                                             _src: *mut [u64; 2])
+                                             -> *mut [u64; 2] {
             panic!("Rust panics cannot be copied");
         }
     }
 }
+cfg_if::cfg_if! {
+   if #[cfg(target_arch = "x86")] {
+       define_cleanup!("thiscall");
+   } else {
+       define_cleanup!("C");
+   }
+}
 
 pub unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
     use core::intrinsics::atomic_store;
index 27308cabd45e600d6205cf2f3fbc2aa6acc62ed9..031837c1efbe814da24c7843022d3bb3cb710c0f 100644 (file)
@@ -953,7 +953,9 @@ fn codegen_msvc_try(
         catchswitch.add_handler(cs, catchpad.llbb());
 
         // The flag value of 8 indicates that we are catching the exception by
-        // reference instead of by value.
+        // reference instead of by value. We can't use catch by value because
+        // that requires copying the exception object, which we don't support
+        // since our exception object effectively contains a Box.
         //
         // Source: MicrosoftCXXABI::getAddrOfCXXCatchHandlerType in clang
         let flags = bx.const_i32(8);
@@ -970,6 +972,8 @@ fn codegen_msvc_try(
         catchpad.store(payload, local_ptr, i64_align);
 
         // Clear the first word of the exception so avoid double-dropping it.
+        // This will be read by the destructor which is implicitly called at the
+        // end of the catch block by the runtime.
         let payload_0_ptr = catchpad.inbounds_gep(payload_ptr, &[bx.const_i32(0), bx.const_i32(0)]);
         catchpad.store(bx.const_u64(0), payload_0_ptr, i64_align);