@@ -367,9 +367,29 @@ pub enum TrapReason {
367367
368368 /// A trap raised from a wasm libcall
369369 Wasm ( wasmtime_environ:: Trap ) ,
370+ }
370371
371- /// A pending exception (stored in and rooted by the `Store`).
372- Exception ,
372+ /// Special tombstone Error object that we use to indicate a thrown
373+ /// exception. We use this tombstone directly in the libcall
374+ /// implementing `throw_ref` (throws from Wasm), and we create the
375+ /// tombstone when intercepting a `Rooted<ExnRef>` when wrapping a
376+ /// host function into a `Func`.
377+ ///
378+ /// This will be captured in a `TrapReason::User` as a boxed
379+ /// error. When provided as a `TrapReason`, the rooted
380+ /// pending-exception slot on the `Store` must have already been
381+ /// set. Both of the above creation sites ensure this invariant.
382+ pub ( crate ) struct ExceptionTombstone ;
383+ impl core:: error:: Error for ExceptionTombstone { }
384+ impl core:: fmt:: Debug for ExceptionTombstone {
385+ fn fmt ( & self , f : & mut core:: fmt:: Formatter ) -> core:: fmt:: Result {
386+ write ! ( f, "Wasm exception" )
387+ }
388+ }
389+ impl core:: fmt:: Display for ExceptionTombstone {
390+ fn fmt ( & self , f : & mut core:: fmt:: Formatter ) -> core:: fmt:: Result {
391+ write ! ( f, "Wasm exception" )
392+ }
373393}
374394
375395impl From < Error > for TrapReason {
@@ -758,7 +778,10 @@ impl CallThreadState {
758778 // An unwind due to an already-set pending exception sets
759779 // a special UnwindState that triggers the handler-search
760780 // stack-walk on unwind().
761- UnwindReason :: Trap ( TrapReason :: Exception ) => {
781+ UnwindReason :: Trap ( TrapReason :: User ( err) )
782+ if err. downcast_ref :: < ExceptionTombstone > ( ) . is_some ( ) =>
783+ {
784+ println ! ( "record_unwind: ExceptionTombstone" ) ;
762785 self . unwind . set ( UnwindState :: ThrowException ) ;
763786 }
764787 // And if we are just propagating an existing trap that already has
@@ -799,7 +822,9 @@ impl CallThreadState {
799822 use wasmtime_unwinder:: ThrowAction ;
800823
801824 let mut unwind = self . unwind . replace ( UnwindState :: None ) ;
825+ println ! ( "unwind!" ) ;
802826 if let UnwindState :: ThrowException = & unwind {
827+ println ! ( "throw exception" ) ;
803828 // Take the pending exception from the store and resolve its throw action.
804829 let exnref = nogc. take_pending_exception ( ) ;
805830 let action = unsafe { compute_throw ( nogc, & exnref) } ;
@@ -816,10 +841,11 @@ impl CallThreadState {
816841 ) ;
817842 } ,
818843 ThrowAction :: None => {
844+ println ! ( "no handler" ) ;
819845 // Throw all the way to entry from host, and put the exnref back on the store.
820846 nogc. set_pending_exception ( exnref) ;
821847 unwind = UnwindState :: UnwindToHost {
822- reason : UnwindReason :: Trap ( TrapReason :: Exception ) ,
848+ reason : UnwindReason :: Trap ( TrapReason :: User ( ExceptionTombstone . into ( ) ) ) ,
823849 backtrace : None ,
824850 coredump_stack : None ,
825851 }
0 commit comments