@@ -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,43 @@ 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+ // 
222+ // The exception_copy function is a bit special here: it is invoked by the MSVC 
223+ // runtime under a try/catch block and the panic that we generate here will be 
224+ // used as the result of the exception copy. This is used by the C++ runtime to 
225+ // support capturing exceptions with std::exception_ptr, which we can't support 
226+ // because Box<dyn Any> isn't clonable. 
227+ macro_rules!  define_cleanup { 
228+     ( $abi: tt)  => { 
229+         unsafe  extern $abi fn  exception_cleanup( e:  * mut  [ u64 ;  2 ] )  { 
230+             if  ( * e) [ 0 ]  != 0  { 
231+                 cleanup( * e) ; 
232+                 super :: __rust_drop_panic( ) ; 
233+             } 
234+         } 
235+         #[ unwind( allowed) ] 
236+         unsafe  extern $abi fn  exception_copy( _dest:  * mut  [ u64 ;  2 ] , 
237+                                              _src:  * mut  [ u64 ;  2 ] ) 
238+                                              -> * mut  [ u64 ;  2 ]  { 
239+             panic!( "Rust panics cannot be copied" ) ; 
240+         } 
241+     } 
242+ } 
243+ cfg_if:: cfg_if! { 
244+    if  #[ cfg( target_arch = "x86" ) ]  { 
245+        define_cleanup!( "thiscall" ) ; 
246+    }  else { 
247+        define_cleanup!( "C" ) ; 
248+    } 
249+ } 
250+ 
211251pub  unsafe  fn  panic ( data :  Box < dyn  Any  + Send > )  -> u32  { 
212252    use  core:: intrinsics:: atomic_store; 
213253
@@ -220,8 +260,7 @@ pub unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
220260    // exception (constructed above). 
221261    let  ptrs = mem:: transmute :: < _ ,  raw:: TraitObject > ( data) ; 
222262    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  _ ; 
263+     let  throw_ptr = ptrs. as_mut_ptr ( )  as  * mut  _ ; 
225264
226265    // This... may seems surprising, and justifiably so. On 32-bit MSVC the 
227266    // pointers between these structure are just that, pointers. On 64-bit MSVC, 
@@ -243,6 +282,12 @@ pub unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
243282    // 
244283    // In any case, we basically need to do something like this until we can 
245284    // express more operations in statics (and we may never be able to). 
285+     if  !cfg ! ( bootstrap)  { 
286+         atomic_store ( 
287+             & mut  THROW_INFO . pmfnUnwind  as  * mut  _  as  * mut  u32 , 
288+             ptr ! ( exception_cleanup)  as  u32 , 
289+         ) ; 
290+     } 
246291    atomic_store ( 
247292        & mut  THROW_INFO . pCatchableTypeArray  as  * mut  _  as  * mut  u32 , 
248293        ptr ! ( & CATCHABLE_TYPE_ARRAY  as  * const  _)  as  u32 , 
@@ -255,6 +300,12 @@ pub unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
255300        & mut  CATCHABLE_TYPE . pType  as  * mut  _  as  * mut  u32 , 
256301        ptr ! ( & TYPE_DESCRIPTOR  as  * const  _)  as  u32 , 
257302    ) ; 
303+     if  !cfg ! ( bootstrap)  { 
304+         atomic_store ( 
305+             & mut  CATCHABLE_TYPE . copyFunction  as  * mut  _  as  * mut  u32 , 
306+             ptr ! ( exception_copy)  as  u32 , 
307+         ) ; 
308+     } 
258309
259310    extern  "system"  { 
260311        #[ unwind( allowed) ]  
0 commit comments