@@ -52,22 +52,32 @@ pub fn payload() -> *mut u8 {
52
52
ptr:: null_mut ( )
53
53
}
54
54
55
+ struct Exception {
56
+ data : Option < Box < dyn Any + Send > > ,
57
+ }
58
+
55
59
pub unsafe fn cleanup ( ptr : * mut u8 ) -> Box < dyn Any + Send > {
56
60
assert ! ( !ptr. is_null( ) ) ;
57
- let adjusted_ptr = __cxa_begin_catch ( ptr as * mut libc:: c_void ) ;
58
- let ex = ptr :: read ( adjusted_ptr as * mut _ ) ;
61
+ let adjusted_ptr = __cxa_begin_catch ( ptr as * mut libc:: c_void ) as * mut Exception ;
62
+ let ex = ( * adjusted_ptr ) . data . take ( ) ;
59
63
__cxa_end_catch ( ) ;
60
- ex
64
+ ex. unwrap ( )
61
65
}
62
66
63
67
pub unsafe fn panic ( data : Box < dyn Any + Send > ) -> u32 {
64
68
let sz = mem:: size_of_val ( & data) ;
65
- let exception = __cxa_allocate_exception ( sz) ;
66
- if exception == ptr :: null_mut ( ) {
69
+ let exception = __cxa_allocate_exception ( sz) as * mut Exception ;
70
+ if exception. is_null ( ) {
67
71
return uw:: _URC_FATAL_PHASE1_ERROR as u32 ;
68
72
}
69
- ptr:: write ( exception as * mut _ , data) ;
70
- __cxa_throw ( exception as * mut _ , & EXCEPTION_TYPE_INFO , ptr:: null_mut ( ) ) ;
73
+ ptr:: write ( exception, Exception { data : Some ( data) } ) ;
74
+ __cxa_throw ( exception as * mut _ , & EXCEPTION_TYPE_INFO , exception_cleanup) ;
75
+
76
+ extern "C" fn exception_cleanup ( ptr : * mut libc:: c_void ) {
77
+ unsafe {
78
+ ptr:: drop_in_place ( ptr as * mut Exception ) ;
79
+ }
80
+ }
71
81
}
72
82
73
83
#[ lang = "eh_personality" ]
@@ -89,7 +99,7 @@ extern "C" {
89
99
fn __cxa_throw (
90
100
thrown_exception : * mut libc:: c_void ,
91
101
tinfo : * const TypeInfo ,
92
- dest : * mut libc:: c_void ,
102
+ dest : extern "C" fn ( * mut libc:: c_void ) ,
93
103
) -> !;
94
104
fn __gxx_personality_v0 (
95
105
version : c_int ,
0 commit comments