wasmer/entities/
trap.rs

1use std::{any::Any, error::Error, fmt::Debug};
2
3#[cfg(feature = "sys")]
4use crate::BackendException;
5use crate::{Exception, RuntimeError, macros::backend::match_rt};
6
7/// An enumeration of all the trap kinds supported by the runtimes.
8#[derive(Debug, derive_more::From)]
9pub enum BackendTrap {
10    #[cfg(feature = "sys")]
11    /// The trap from the `sys` runtime.
12    Sys(crate::backend::sys::vm::Trap),
13
14    #[cfg(feature = "wamr")]
15    /// The trap from the `wamr` runtime.
16    Wamr(crate::backend::wamr::vm::Trap),
17
18    #[cfg(feature = "wasmi")]
19    /// The trap from the `wasmi` runtime.
20    Wasmi(crate::backend::wasmi::vm::Trap),
21
22    #[cfg(feature = "v8")]
23    /// The trap from the `v8` runtime.
24    V8(crate::backend::v8::vm::Trap),
25
26    #[cfg(feature = "js")]
27    /// The trap from the `js` runtime.
28    Js(crate::backend::js::vm::Trap),
29
30    #[cfg(feature = "jsc")]
31    /// The trap from the `jsc` runtime.
32    Jsc(crate::backend::jsc::vm::Trap),
33}
34
35impl BackendTrap {
36    /// Construct a new Error with the given a user error.
37    ///
38    /// Internally saves a backtrace when constructed.
39    pub fn user(err: Box<dyn Error + Send + Sync>) -> RuntimeError {
40        #[cfg(feature = "sys")]
41        {
42            return crate::backend::sys::vm::Trap::user(err).into();
43        }
44        #[cfg(feature = "wamr")]
45        {
46            return crate::backend::wamr::vm::Trap::user(err).into();
47        }
48
49        #[cfg(feature = "wasmi")]
50        {
51            return crate::backend::wasmi::vm::Trap::user(err).into();
52        }
53
54        #[cfg(feature = "v8")]
55        {
56            return crate::backend::v8::vm::Trap::user(err).into();
57        }
58        #[cfg(feature = "js")]
59        {
60            return crate::backend::js::vm::Trap::user(err).into();
61        }
62        #[cfg(feature = "jsc")]
63        {
64            return crate::backend::jsc::vm::Trap::user(err).into();
65        }
66
67        panic!("No runtime enabled!")
68    }
69    /// Attempts to downcast the `Trap` to a concrete type.
70    #[inline]
71    pub fn downcast<T: Error + 'static>(self) -> Result<T, Self> {
72        match_rt!(on self => s {
73            s.downcast::<T>().map_err(Into::into)
74        })
75    }
76
77    /// Attempts to downcast the `Trap` to a concrete type.
78    #[inline]
79    pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
80        match_rt!(on self => s {
81            s.downcast_ref::<T>()
82        })
83    }
84
85    /// Returns true if the `Trap` is the same as T
86    #[inline]
87    pub fn is<T: Error + 'static>(&self) -> bool {
88        match_rt!(on self => s {
89            s.is::<T>()
90        })
91    }
92
93    /// Returns true if the trap is an exception
94    #[inline]
95    pub fn is_exception(&self) -> bool {
96        match_rt!(on self => s {
97            s.is_exception()
98        })
99    }
100
101    /// If the `Trap` is an uncaught exception, returns it.
102    #[inline]
103    pub fn to_exception(&self) -> Option<Exception> {
104        match self {
105            #[cfg(feature = "sys")]
106            Self::Sys(s) => s
107                .to_exception_ref()
108                .map(|e| Exception::from_vm_exceptionref(crate::vm::VMExceptionRef::Sys(e))),
109            #[cfg(feature = "wamr")]
110            Self::Wamr(s) => s
111                .to_exception_ref()
112                .map(|e| Exception::from_vm_exceptionref(crate::vm::VMExceptionRef::Wamr(e))),
113            #[cfg(feature = "wasmi")]
114            Self::Wasmi(s) => s
115                .to_exception_ref()
116                .map(|e| Exception::from_vm_exceptionref(crate::vm::VMExceptionRef::Wasmi(e))),
117            #[cfg(feature = "v8")]
118            Self::V8(s) => s
119                .to_exception_ref()
120                .map(|e| Exception::from_vm_exceptionref(crate::vm::VMExceptionRef::V8(e))),
121            #[cfg(feature = "js")]
122            Self::Js(s) => s
123                .to_exception_ref()
124                .map(|e| Exception::from_vm_exceptionref(crate::vm::VMExceptionRef::Js(e))),
125            #[cfg(feature = "jsc")]
126            Self::Jsc(s) => s
127                .to_exception_ref()
128                .map(|e| Exception::from_vm_exceptionref(crate::vm::VMExceptionRef::Jsc(e))),
129        }
130    }
131}
132
133impl std::fmt::Display for BackendTrap {
134    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
135        match_rt!(on self => s {
136            (s as &dyn std::fmt::Display).fmt(f)
137        })
138    }
139}
140
141impl std::error::Error for BackendTrap {
142    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
143        match_rt!(on self => s {
144            s.source()
145        })
146    }
147}