| use core::borrow::Borrow; |
| use core::ops::{Deref, DerefMut}; |
| |
| use crate::describe::*; |
| |
| /// A trait for anything that can be converted into a type that can cross the |
| /// wasm ABI directly, eg `u32` or `f64`. |
| /// |
| /// This is the opposite operation as `FromWasmAbi` and `Ref[Mut]FromWasmAbi`. |
| pub trait IntoWasmAbi: WasmDescribe { |
| /// The wasm ABI type that this converts into when crossing the ABI |
| /// boundary. |
| type Abi: WasmAbi; |
| |
| /// Convert `self` into `Self::Abi` so that it can be sent across the wasm |
| /// ABI boundary. |
| fn into_abi(self) -> Self::Abi; |
| } |
| |
| /// A trait for anything that can be recovered by-value from the wasm ABI |
| /// boundary, eg a Rust `u8` can be recovered from the wasm ABI `u32` type. |
| /// |
| /// This is the by-value variant of the opposite operation as `IntoWasmAbi`. |
| pub trait FromWasmAbi: WasmDescribe { |
| /// The wasm ABI type that this converts from when coming back out from the |
| /// ABI boundary. |
| type Abi: WasmAbi; |
| |
| /// Recover a `Self` from `Self::Abi`. |
| /// |
| /// # Safety |
| /// |
| /// This is only safe to call when -- and implementations may assume that -- |
| /// the supplied `Self::Abi` was previously generated by a call to `<Self as |
| /// IntoWasmAbi>::into_abi()` or the moral equivalent in JS. |
| unsafe fn from_abi(js: Self::Abi) -> Self; |
| } |
| |
| /// A trait for anything that can be recovered as some sort of shared reference |
| /// from the wasm ABI boundary. |
| /// |
| /// This is the shared reference variant of the opposite operation as |
| /// `IntoWasmAbi`. |
| pub trait RefFromWasmAbi: WasmDescribe { |
| /// The wasm ABI type references to `Self` are recovered from. |
| type Abi: WasmAbi; |
| |
| /// The type that holds the reference to `Self` for the duration of the |
| /// invocation of the function that has an `&Self` parameter. This is |
| /// required to ensure that the lifetimes don't persist beyond one function |
| /// call, and so that they remain anonymous. |
| type Anchor: Deref<Target = Self>; |
| |
| /// Recover a `Self::Anchor` from `Self::Abi`. |
| /// |
| /// # Safety |
| /// |
| /// Same as `FromWasmAbi::from_abi`. |
| unsafe fn ref_from_abi(js: Self::Abi) -> Self::Anchor; |
| } |
| |
| /// A version of the `RefFromWasmAbi` trait with the additional requirement |
| /// that the reference must remain valid as long as the anchor isn't dropped. |
| /// |
| /// This isn't the case for `JsValue`'s `RefFromWasmAbi` implementation. To |
| /// avoid having to allocate a spot for the `JsValue` on the `JsValue` heap, |
| /// the `JsValue` is instead pushed onto the `JsValue` stack, and popped off |
| /// again after the function that the reference was passed to returns. So, |
| /// `JsValue` has a different `LongRefFromWasmAbi` implementation that behaves |
| /// the same as `FromWasmAbi`, putting the value on the heap. |
| /// |
| /// This is needed for async functions, where the reference needs to be valid |
| /// for the whole length of the `Future`, rather than the initial synchronous |
| /// call. |
| /// |
| /// 'long ref' is short for 'long-lived reference'. |
| pub trait LongRefFromWasmAbi: WasmDescribe { |
| /// Same as `RefFromWasmAbi::Abi` |
| type Abi: WasmAbi; |
| |
| /// Same as `RefFromWasmAbi::Anchor` |
| type Anchor: Borrow<Self>; |
| |
| /// Same as `RefFromWasmAbi::ref_from_abi` |
| unsafe fn long_ref_from_abi(js: Self::Abi) -> Self::Anchor; |
| } |
| |
| /// Dual of the `RefFromWasmAbi` trait, except for mutable references. |
| pub trait RefMutFromWasmAbi: WasmDescribe { |
| /// Same as `RefFromWasmAbi::Abi` |
| type Abi: WasmAbi; |
| /// Same as `RefFromWasmAbi::Anchor` |
| type Anchor: DerefMut<Target = Self>; |
| /// Same as `RefFromWasmAbi::ref_from_abi` |
| unsafe fn ref_mut_from_abi(js: Self::Abi) -> Self::Anchor; |
| } |
| |
| /// Indicates that this type can be passed to JS as `Option<Self>`. |
| /// |
| /// This trait is used when implementing `IntoWasmAbi for Option<T>`. |
| pub trait OptionIntoWasmAbi: IntoWasmAbi { |
| /// Returns an ABI instance indicating "none", which JS will interpret as |
| /// the `None` branch of this option. |
| /// |
| /// It should be guaranteed that the `IntoWasmAbi` can never produce the ABI |
| /// value returned here. |
| fn none() -> Self::Abi; |
| } |
| |
| /// Indicates that this type can be received from JS as `Option<Self>`. |
| /// |
| /// This trait is used when implementing `FromWasmAbi for Option<T>`. |
| pub trait OptionFromWasmAbi: FromWasmAbi { |
| /// Tests whether the argument is a "none" instance. If so it will be |
| /// deserialized as `None`, and otherwise it will be passed to |
| /// `FromWasmAbi`. |
| fn is_none(abi: &Self::Abi) -> bool; |
| } |
| |
| /// An unsafe trait which represents types that are ABI-safe to pass via wasm |
| /// arguments. |
| /// |
| /// # Safety |
| /// |
| /// This is an unsafe trait to implement as there's no guarantee the type is |
| /// actually safe to transfer across the was boundary, it's up to you to |
| /// guarantee this, so codegen works correctly. |
| pub unsafe trait WasmAbi {} |
| |
| unsafe impl WasmAbi for u32 {} |
| unsafe impl WasmAbi for i32 {} |
| unsafe impl WasmAbi for u64 {} |
| unsafe impl WasmAbi for i64 {} |
| unsafe impl WasmAbi for f32 {} |
| unsafe impl WasmAbi for f64 {} |
| |
| /// A trait representing how to interpret the return value of a function for |
| /// the wasm ABI. |
| /// |
| /// This is very similar to the `IntoWasmAbi` trait and in fact has a blanket |
| /// implementation for all implementors of the `IntoWasmAbi`. The primary use |
| /// case of this trait is to enable functions to return `Result`, interpreting |
| /// an error as "rethrow this to JS" |
| pub trait ReturnWasmAbi: WasmDescribe { |
| /// Same as `IntoWasmAbi::Abi` |
| type Abi: WasmAbi; |
| |
| /// Same as `IntoWasmAbi::into_abi`, except that it may throw and never |
| /// return in the case of `Err`. |
| fn return_abi(self) -> Self::Abi; |
| } |
| |
| impl<T: IntoWasmAbi> ReturnWasmAbi for T { |
| type Abi = T::Abi; |
| |
| #[inline] |
| fn return_abi(self) -> Self::Abi { |
| self.into_abi() |
| } |
| } |