@@ -20,7 +20,7 @@ use crate::runtime::store::{ExecutorRef, StoreOpaque};
2020use crate :: runtime:: vm:: sys:: traphandlers;
2121use crate :: runtime:: vm:: { InterpreterRef , VMContext , VMStoreContext , f32x4, f64x2, i8x16} ;
2222use crate :: store:: AutoAssertNoGc ;
23- use crate :: { EntryStoreContext , prelude:: * } ;
23+ use crate :: { EntryStoreContext , ExnRef , prelude:: * } ;
2424use crate :: { StoreContextMut , WasmBacktrace } ;
2525use core:: cell:: Cell ;
2626use core:: num:: NonZeroU32 ;
@@ -415,7 +415,7 @@ pub unsafe fn catch_traps<T, F>(
415415 store : & mut StoreContextMut < ' _ , T > ,
416416 old_state : & mut EntryStoreContext ,
417417 mut closure : F ,
418- ) -> Result < ( ) , Box < Trap > >
418+ ) -> Result < ( ) >
419419where
420420 F : FnMut ( NonNull < VMContext > , Option < InterpreterRef < ' _ > > ) -> bool ,
421421{
@@ -461,16 +461,40 @@ where
461461 } ,
462462 } ) ;
463463
464- return match result {
464+ match result {
465465 Ok ( x) => Ok ( x) ,
466- Err ( ( UnwindReason :: Trap ( reason ) , backtrace , coredumpstack ) ) => Err ( Box :: new ( Trap {
467- reason,
466+ Err ( UnwindState :: UnwindToHost {
467+ reason : UnwindReason :: Trap ( reason ) ,
468468 backtrace,
469- coredumpstack,
470- } ) ) ,
469+ coredump_stack,
470+ } ) => Err ( crate :: trap:: from_runtime_box (
471+ store. 0 ,
472+ Box :: new ( Trap {
473+ reason,
474+ backtrace,
475+ coredumpstack : coredump_stack,
476+ } ) ,
477+ ) ) ,
471478 #[ cfg( all( feature = "std" , panic = "unwind" ) ) ]
472- Err ( ( UnwindReason :: Panic ( panic) , _, _) ) => std:: panic:: resume_unwind ( panic) ,
473- } ;
479+ Err ( UnwindState :: UnwindToHost {
480+ reason : UnwindReason :: Panic ( panic) ,
481+ ..
482+ } ) => std:: panic:: resume_unwind ( panic) ,
483+ #[ cfg( feature = "gc" ) ]
484+ Err ( UnwindState :: ThrowException ) => {
485+ // We may have gotten here if a host function (created via
486+ // `Func::new`) was called directly with `Func::call` and
487+ // returned an exception: in that case, no trampoline to
488+ // call `unwind()` exists, so we have to fetch the pending
489+ // exception explicitly here.
490+ let exnref = store. 0 . take_pending_exception ( ) ;
491+ let exnref = ExnRef :: from_raw ( store, exnref. as_gc_ref ( ) . as_raw_u32 ( ) ) . unwrap ( ) ;
492+ Err ( exnref. into ( ) )
493+ }
494+ Err ( UnwindState :: None ) => {
495+ unreachable ! ( "We should not have gotten an error with no unwind state" ) ;
496+ }
497+ }
474498}
475499
476500// Module to hide visibility of the `CallThreadState::prev` field and force
@@ -719,32 +743,18 @@ where
719743
720744impl CallThreadState {
721745 #[ inline]
722- fn with (
723- mut self ,
724- closure : impl FnOnce ( & CallThreadState ) -> bool ,
725- ) -> Result < ( ) , ( UnwindReason , Option < Backtrace > , Option < CoreDumpStack > ) > {
746+ fn with ( mut self , closure : impl FnOnce ( & CallThreadState ) -> bool ) -> Result < ( ) , UnwindState > {
726747 let succeeded = tls:: set ( & mut self , |me| closure ( me) ) ;
727748 if succeeded {
728749 Ok ( ( ) )
729750 } else {
730- Err ( self . read_unwind_to_host ( ) )
751+ Err ( self . read_unwind ( ) )
731752 }
732753 }
733754
734755 #[ cold]
735- fn read_unwind_to_host ( & self ) -> ( UnwindReason , Option < Backtrace > , Option < CoreDumpStack > ) {
736- match self . unwind . replace ( UnwindState :: None ) {
737- UnwindState :: UnwindToHost {
738- reason,
739- backtrace,
740- coredump_stack,
741- } => ( reason, backtrace, coredump_stack) ,
742- #[ cfg( feature = "gc" ) ]
743- UnwindState :: ThrowException => {
744- panic ! ( "Exception should have been resolved by unwind() before reaching caller" )
745- }
746- UnwindState :: None => panic ! ( "No unwind state with erroneous return code" ) ,
747- }
756+ fn read_unwind ( & self ) -> UnwindState {
757+ self . unwind . replace ( UnwindState :: None )
748758 }
749759
750760 /// Records the unwind information provided within this `CallThreadState`,
0 commit comments