Skip to content

Commit 5b41d99

Browse files
committed
Apply review feedback
1 parent 25364c6 commit 5b41d99

File tree

3 files changed

+22
-19
lines changed

3 files changed

+22
-19
lines changed

src/libpanic_unwind/emcc.rs

+4
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ pub fn payload() -> *mut u8 {
5353
}
5454

5555
struct Exception {
56+
// This needs to be an Option because the object's lifetime follows C++
57+
// semantics: when catch_unwind moves the Box out of the exception it must
58+
// still leave the exception object in a valid state because its destructor
59+
// is still going to be called by __cxa_end_catch..
5660
data: Option<Box<dyn Any + Send>>,
5761
}
5862

src/libpanic_unwind/seh.rs

+13-18
Original file line numberDiff line numberDiff line change
@@ -224,33 +224,28 @@ static mut TYPE_DESCRIPTOR: _TypeDescriptor = _TypeDescriptor {
224224
// used as the result of the exception copy. This is used by the C++ runtime to
225225
// support capturing exceptions with std::exception_ptr, which we can't support
226226
// because Box<dyn Any> isn't clonable.
227-
cfg_if::cfg_if! {
228-
if #[cfg(target_arch = "x86")] {
229-
unsafe extern "thiscall" fn exception_cleanup(e: *mut [u64; 2]) {
230-
if (*e)[0] != 0 {
231-
cleanup(*e);
232-
}
233-
}
234-
#[unwind(allowed)]
235-
unsafe extern "thiscall" fn exception_copy(_dest: *mut [u64; 2],
236-
_src: *mut [u64; 2])
237-
-> *mut [u64; 2] {
238-
panic!("Rust panics cannot be copied");
239-
}
240-
} else {
241-
unsafe extern "C" fn exception_cleanup(e: *mut [u64; 2]) {
227+
macro_rules! define_cleanup {
228+
($abi:tt) => {
229+
unsafe extern $abi fn exception_cleanup(e: *mut [u64; 2]) {
242230
if (*e)[0] != 0 {
243231
cleanup(*e);
244232
}
245233
}
246234
#[unwind(allowed)]
247-
unsafe extern "C" fn exception_copy(_dest: *mut [u64; 2],
248-
_src: *mut [u64; 2])
249-
-> *mut [u64; 2] {
235+
unsafe extern $abi fn exception_copy(_dest: *mut [u64; 2],
236+
_src: *mut [u64; 2])
237+
-> *mut [u64; 2] {
250238
panic!("Rust panics cannot be copied");
251239
}
252240
}
253241
}
242+
cfg_if::cfg_if! {
243+
if #[cfg(target_arch = "x86")] {
244+
define_cleanup!("thiscall");
245+
} else {
246+
define_cleanup!("C");
247+
}
248+
}
254249

255250
pub unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
256251
use core::intrinsics::atomic_store;

src/librustc_codegen_llvm/intrinsic.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -953,7 +953,9 @@ fn codegen_msvc_try(
953953
catchswitch.add_handler(cs, catchpad.llbb());
954954

955955
// The flag value of 8 indicates that we are catching the exception by
956-
// reference instead of by value.
956+
// reference instead of by value. We can't use catch by value because
957+
// that requires copying the exception object, which we don't support
958+
// since our exception object effectively contains a Box.
957959
//
958960
// Source: MicrosoftCXXABI::getAddrOfCXXCatchHandlerType in clang
959961
let flags = bx.const_i32(8);
@@ -970,6 +972,8 @@ fn codegen_msvc_try(
970972
catchpad.store(payload, local_ptr, i64_align);
971973

972974
// Clear the first word of the exception so avoid double-dropping it.
975+
// This will be read by the destructor which is implicitly called at the
976+
// end of the catch block by the runtime.
973977
let payload_0_ptr = catchpad.inbounds_gep(payload_ptr, &[bx.const_i32(0), bx.const_i32(0)]);
974978
catchpad.store(bx.const_u64(0), payload_0_ptr, i64_align);
975979

0 commit comments

Comments
 (0)