@@ -77,8 +77,11 @@ use libc::{c_int, c_uint, c_void};
77
77
// #include <stdint.h>
78
78
//
79
79
// struct rust_panic {
80
+ // rust_panic(const rust_panic&);
81
+ // ~rust_panic();
82
+ //
80
83
// uint64_t x[2];
81
- // }
84
+ // };
82
85
//
83
86
// void foo() {
84
87
// rust_panic a = {0, 1};
@@ -128,7 +131,7 @@ mod imp {
128
131
#[ repr( C ) ]
129
132
pub struct _ThrowInfo {
130
133
pub attributes : c_uint ,
131
- pub pnfnUnwind : imp:: ptr_t ,
134
+ pub pmfnUnwind : imp:: ptr_t ,
132
135
pub pForwardCompat : imp:: ptr_t ,
133
136
pub pCatchableTypeArray : imp:: ptr_t ,
134
137
}
@@ -145,7 +148,7 @@ pub struct _CatchableType {
145
148
pub pType : imp:: ptr_t ,
146
149
pub thisDisplacement : _PMD ,
147
150
pub sizeOrOffset : c_int ,
148
- pub copy_function : imp:: ptr_t ,
151
+ pub copyFunction : imp:: ptr_t ,
149
152
}
150
153
151
154
#[ repr( C ) ]
@@ -168,7 +171,7 @@ const TYPE_NAME: [u8; 11] = *b"rust_panic\0";
168
171
169
172
static mut THROW_INFO : _ThrowInfo = _ThrowInfo {
170
173
attributes : 0 ,
171
- pnfnUnwind : ptr ! ( 0 ) ,
174
+ pmfnUnwind : ptr ! ( 0 ) ,
172
175
pForwardCompat : ptr ! ( 0 ) ,
173
176
pCatchableTypeArray : ptr ! ( 0 ) ,
174
177
} ;
@@ -181,7 +184,7 @@ static mut CATCHABLE_TYPE: _CatchableType = _CatchableType {
181
184
pType : ptr ! ( 0 ) ,
182
185
thisDisplacement : _PMD { mdisp : 0 , pdisp : -1 , vdisp : 0 } ,
183
186
sizeOrOffset : mem:: size_of :: < [ u64 ; 2 ] > ( ) as c_int ,
184
- copy_function : ptr ! ( 0 ) ,
187
+ copyFunction : ptr ! ( 0 ) ,
185
188
} ;
186
189
187
190
extern "C" {
@@ -208,6 +211,39 @@ static mut TYPE_DESCRIPTOR: _TypeDescriptor = _TypeDescriptor {
208
211
name : TYPE_NAME ,
209
212
} ;
210
213
214
+ // Destructor used if the C++ code decides to capture the exception and drop it
215
+ // without propagating it. The catch part of the try intrinsic will set the
216
+ // first word of the exception object to 0 so that it is skipped by the
217
+ // destructor.
218
+ //
219
+ // Note that x86 Windows uses the "thiscall" calling convention for C++ member
220
+ // functions instead of the default "C" calling convention.
221
+ cfg_if:: cfg_if! {
222
+ if #[ cfg( target_arch = "x86" ) ] {
223
+ unsafe extern "thiscall" fn exception_cleanup( e: * mut [ u64 ; 2 ] ) {
224
+ if ( * e) [ 0 ] != 0 {
225
+ cleanup( * e) ;
226
+ }
227
+ }
228
+ unsafe extern "thiscall" fn exception_copy( _dest: * mut [ u64 ; 2 ] ,
229
+ _src: * mut [ u64 ; 2 ] )
230
+ -> * mut [ u64 ; 2 ] {
231
+ panic!( "Rust panics cannot be copied" ) ;
232
+ }
233
+ } else {
234
+ unsafe extern "C" fn exception_cleanup( e: * mut [ u64 ; 2 ] ) {
235
+ if ( * e) [ 0 ] != 0 {
236
+ cleanup( * e) ;
237
+ }
238
+ }
239
+ unsafe extern "C" fn exception_copy( _dest: * mut [ u64 ; 2 ] ,
240
+ _src: * mut [ u64 ; 2 ] )
241
+ -> * mut [ u64 ; 2 ] {
242
+ panic!( "Rust panics cannot be copied" ) ;
243
+ }
244
+ }
245
+ }
246
+
211
247
pub unsafe fn panic ( data : Box < dyn Any + Send > ) -> u32 {
212
248
use core:: intrinsics:: atomic_store;
213
249
@@ -220,8 +256,7 @@ pub unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
220
256
// exception (constructed above).
221
257
let ptrs = mem:: transmute :: < _ , raw:: TraitObject > ( data) ;
222
258
let mut ptrs = [ ptrs. data as u64 , ptrs. vtable as u64 ] ;
223
- let ptrs_ptr = ptrs. as_mut_ptr ( ) ;
224
- let throw_ptr = ptrs_ptr as * mut _ ;
259
+ let throw_ptr = ptrs. as_mut_ptr ( ) as * mut _ ;
225
260
226
261
// This... may seems surprising, and justifiably so. On 32-bit MSVC the
227
262
// pointers between these structure are just that, pointers. On 64-bit MSVC,
@@ -243,6 +278,12 @@ pub unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
243
278
//
244
279
// In any case, we basically need to do something like this until we can
245
280
// express more operations in statics (and we may never be able to).
281
+ if !cfg ! ( bootstrap) {
282
+ atomic_store (
283
+ & mut THROW_INFO . pmfnUnwind as * mut _ as * mut u32 ,
284
+ ptr ! ( exception_cleanup) as u32 ,
285
+ ) ;
286
+ }
246
287
atomic_store (
247
288
& mut THROW_INFO . pCatchableTypeArray as * mut _ as * mut u32 ,
248
289
ptr ! ( & CATCHABLE_TYPE_ARRAY as * const _) as u32 ,
@@ -255,6 +296,12 @@ pub unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
255
296
& mut CATCHABLE_TYPE . pType as * mut _ as * mut u32 ,
256
297
ptr ! ( & TYPE_DESCRIPTOR as * const _) as u32 ,
257
298
) ;
299
+ if !cfg ! ( bootstrap) {
300
+ atomic_store (
301
+ & mut CATCHABLE_TYPE . copyFunction as * mut _ as * mut u32 ,
302
+ ptr ! ( exception_copy) as u32 ,
303
+ ) ;
304
+ }
258
305
259
306
extern "system" {
260
307
#[ unwind( allowed) ]
0 commit comments