@@ -77,8 +77,11 @@ use libc::{c_int, c_uint, c_void};
7777// #include <stdint.h>
7878//
7979// struct rust_panic {
80+ // rust_panic(const rust_panic&);
81+ // ~rust_panic();
82+ //
8083// uint64_t x[2];
81- // }
84+ // };
8285//
8386// void foo() {
8487// rust_panic a = {0, 1};
@@ -128,7 +131,7 @@ mod imp {
128131#[ repr( C ) ]
129132pub struct _ThrowInfo {
130133 pub attributes : c_uint ,
131- pub pnfnUnwind : imp:: ptr_t ,
134+ pub pmfnUnwind : imp:: ptr_t ,
132135 pub pForwardCompat : imp:: ptr_t ,
133136 pub pCatchableTypeArray : imp:: ptr_t ,
134137}
@@ -145,7 +148,7 @@ pub struct _CatchableType {
145148 pub pType : imp:: ptr_t ,
146149 pub thisDisplacement : _PMD ,
147150 pub sizeOrOffset : c_int ,
148- pub copy_function : imp:: ptr_t ,
151+ pub copyFunction : imp:: ptr_t ,
149152}
150153
151154#[ repr( C ) ]
@@ -168,7 +171,7 @@ const TYPE_NAME: [u8; 11] = *b"rust_panic\0";
168171
169172static mut THROW_INFO : _ThrowInfo = _ThrowInfo {
170173 attributes : 0 ,
171- pnfnUnwind : ptr ! ( 0 ) ,
174+ pmfnUnwind : ptr ! ( 0 ) ,
172175 pForwardCompat : ptr ! ( 0 ) ,
173176 pCatchableTypeArray : ptr ! ( 0 ) ,
174177} ;
@@ -181,7 +184,7 @@ static mut CATCHABLE_TYPE: _CatchableType = _CatchableType {
181184 pType : ptr ! ( 0 ) ,
182185 thisDisplacement : _PMD { mdisp : 0 , pdisp : -1 , vdisp : 0 } ,
183186 sizeOrOffset : mem:: size_of :: < [ u64 ; 2 ] > ( ) as c_int ,
184- copy_function : ptr ! ( 0 ) ,
187+ copyFunction : ptr ! ( 0 ) ,
185188} ;
186189
187190extern "C" {
@@ -208,6 +211,39 @@ static mut TYPE_DESCRIPTOR: _TypeDescriptor = _TypeDescriptor {
208211 name : TYPE_NAME ,
209212} ;
210213
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+
211247pub unsafe fn panic ( data : Box < dyn Any + Send > ) -> u32 {
212248 use core:: intrinsics:: atomic_store;
213249
@@ -220,8 +256,7 @@ pub unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
220256 // exception (constructed above).
221257 let ptrs = mem:: transmute :: < _ , raw:: TraitObject > ( data) ;
222258 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 _ ;
225260
226261 // This... may seems surprising, and justifiably so. On 32-bit MSVC the
227262 // 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 {
243278 //
244279 // In any case, we basically need to do something like this until we can
245280 // 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+ }
246287 atomic_store (
247288 & mut THROW_INFO . pCatchableTypeArray as * mut _ as * mut u32 ,
248289 ptr ! ( & CATCHABLE_TYPE_ARRAY as * const _) as u32 ,
@@ -255,6 +296,12 @@ pub unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
255296 & mut CATCHABLE_TYPE . pType as * mut _ as * mut u32 ,
256297 ptr ! ( & TYPE_DESCRIPTOR as * const _) as u32 ,
257298 ) ;
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+ }
258305
259306 extern "system" {
260307 #[ unwind( allowed) ]
0 commit comments