summaryrefslogtreecommitdiffstats
path: root/vendor/wasm-bindgen/src
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 12:41:35 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 12:41:35 +0000
commit7e5d7eea9c580ef4b41a765bde624af431942b96 (patch)
tree2c0d9ca12878fc4525650aa4e54d77a81a07cc09 /vendor/wasm-bindgen/src
parentAdding debian version 1.70.0+dfsg1-9. (diff)
downloadrustc-7e5d7eea9c580ef4b41a765bde624af431942b96.tar.xz
rustc-7e5d7eea9c580ef4b41a765bde624af431942b96.zip
Merging upstream version 1.70.0+dfsg2.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/wasm-bindgen/src')
-rw-r--r--vendor/wasm-bindgen/src/cache/intern.rs103
-rw-r--r--vendor/wasm-bindgen/src/cache/mod.rs1
-rw-r--r--vendor/wasm-bindgen/src/cast.rs160
-rw-r--r--vendor/wasm-bindgen/src/closure.rs885
-rw-r--r--vendor/wasm-bindgen/src/convert/closures.rs225
-rw-r--r--vendor/wasm-bindgen/src/convert/impls.rs378
-rw-r--r--vendor/wasm-bindgen/src/convert/mod.rs11
-rw-r--r--vendor/wasm-bindgen/src/convert/slices.rs311
-rw-r--r--vendor/wasm-bindgen/src/convert/traits.rs131
-rw-r--r--vendor/wasm-bindgen/src/describe.rs192
-rw-r--r--vendor/wasm-bindgen/src/externref.rs184
-rw-r--r--vendor/wasm-bindgen/src/lib.rs1800
12 files changed, 4381 insertions, 0 deletions
diff --git a/vendor/wasm-bindgen/src/cache/intern.rs b/vendor/wasm-bindgen/src/cache/intern.rs
new file mode 100644
index 000000000..c8aa51b2c
--- /dev/null
+++ b/vendor/wasm-bindgen/src/cache/intern.rs
@@ -0,0 +1,103 @@
+use cfg_if::cfg_if;
+
+
+cfg_if! {
+ if #[cfg(feature = "enable-interning")] {
+ use std::thread_local;
+ use std::string::String;
+ use std::borrow::ToOwned;
+ use std::cell::RefCell;
+ use std::collections::HashMap;
+ use crate::JsValue;
+
+ struct Cache {
+ entries: RefCell<HashMap<String, JsValue>>,
+ }
+
+ thread_local! {
+ static CACHE: Cache = Cache {
+ entries: RefCell::new(HashMap::new()),
+ };
+ }
+
+ /// This returns the raw index of the cached JsValue, so you must take care
+ /// so that you don't use it after it is freed.
+ pub(crate) fn unsafe_get_str(s: &str) -> Option<u32> {
+ CACHE.with(|cache| {
+ let cache = cache.entries.borrow();
+
+ cache.get(s).map(|x| x.idx)
+ })
+ }
+
+ fn intern_str(key: &str) {
+ CACHE.with(|cache| {
+ let mut cache = cache.entries.borrow_mut();
+
+ // Can't use `entry` because `entry` requires a `String`
+ if !cache.contains_key(key) {
+ cache.insert(key.to_owned(), JsValue::from(key));
+ }
+ })
+ }
+
+ fn unintern_str(key: &str) {
+ CACHE.with(|cache| {
+ let mut cache = cache.entries.borrow_mut();
+
+ cache.remove(key);
+ })
+ }
+ }
+}
+
+
+/// Interns Rust strings so that it's much faster to send them to JS.
+///
+/// Sending strings from Rust to JS is slow, because it has to do a full `O(n)`
+/// copy and *also* encode from UTF-8 to UTF-16. This must be done every single
+/// time a string is sent to JS.
+///
+/// If you are sending the same string multiple times, you can call this `intern`
+/// function, which simply returns its argument unchanged:
+///
+/// ```rust
+/// # use wasm_bindgen::intern;
+/// intern("foo") // returns "foo"
+/// # ;
+/// ```
+///
+/// However, if you enable the `"enable-interning"` feature for wasm-bindgen,
+/// then it will add the string into an internal cache.
+///
+/// When you send that cached string to JS, it will look it up in the cache,
+/// which completely avoids the `O(n)` copy and encoding. This has a significant
+/// speed boost (as high as 783%)!
+///
+/// However, there is a small cost to this caching, so you shouldn't cache every
+/// string. Only cache strings which have a high likelihood of being sent
+/// to JS multiple times.
+///
+/// Also, keep in mind that this function is a *performance hint*: it's not
+/// *guaranteed* that the string will be cached, and the caching strategy
+/// might change at any time, so don't rely upon it.
+#[inline]
+pub fn intern(s: &str) -> &str {
+ #[cfg(feature = "enable-interning")]
+ intern_str(s);
+
+ s
+}
+
+
+/// Removes a Rust string from the intern cache.
+///
+/// This does the opposite of the [`intern`](fn.intern.html) function.
+///
+/// If the [`intern`](fn.intern.html) function is called again then it will re-intern the string.
+#[allow(unused_variables)]
+#[inline]
+pub fn unintern(s: &str) {
+ #[cfg(feature = "enable-interning")]
+ unintern_str(s);
+}
diff --git a/vendor/wasm-bindgen/src/cache/mod.rs b/vendor/wasm-bindgen/src/cache/mod.rs
new file mode 100644
index 000000000..96d1a4920
--- /dev/null
+++ b/vendor/wasm-bindgen/src/cache/mod.rs
@@ -0,0 +1 @@
+pub mod intern;
diff --git a/vendor/wasm-bindgen/src/cast.rs b/vendor/wasm-bindgen/src/cast.rs
new file mode 100644
index 000000000..6be56a2d7
--- /dev/null
+++ b/vendor/wasm-bindgen/src/cast.rs
@@ -0,0 +1,160 @@
+use crate::{describe::WasmDescribe, JsValue};
+
+/// A trait for checked and unchecked casting between JS types.
+///
+/// Specified [in an RFC][rfc] this trait is intended to provide support for
+/// casting JS values between differnet types of one another. In JS there aren't
+/// many static types but we've ascribed JS values with static types in Rust,
+/// yet they often need to be switched to other types temporarily! This trait
+/// provides both checked and unchecked casting into various kinds of values.
+///
+/// This trait is automatically implemented for any type imported in a
+/// `#[wasm_bindgen]` `extern` block.
+///
+/// [rfc]: https://github.com/rustwasm/rfcs/blob/master/text/002-wasm-bindgen-inheritance-casting.md
+pub trait JsCast
+where
+ Self: AsRef<JsValue> + Into<JsValue>,
+{
+ /// Test whether this JS value has a type `T`.
+ ///
+ /// This method will dynamically check to see if this JS object can be
+ /// casted to the JS object of type `T`. Usually this uses the `instanceof`
+ /// operator. This also works with primitive types like
+ /// booleans/strings/numbers as well as cross-realm object like `Array`
+ /// which can originate from other iframes.
+ ///
+ /// In general this is intended to be a more robust version of
+ /// `is_instance_of`, but if you want strictly the `instanceof` operator
+ /// it's recommended to use that instead.
+ fn has_type<T>(&self) -> bool
+ where
+ T: JsCast,
+ {
+ T::is_type_of(self.as_ref())
+ }
+
+ /// Performs a dynamic cast (checked at runtime) of this value into the
+ /// target type `T`.
+ ///
+ /// This method will return `Err(self)` if `self.has_type::<T>()`
+ /// returns `false`, and otherwise it will return `Ok(T)` manufactured with
+ /// an unchecked cast (verified correct via the `has_type` operation).
+ fn dyn_into<T>(self) -> Result<T, Self>
+ where
+ T: JsCast,
+ {
+ if self.has_type::<T>() {
+ Ok(self.unchecked_into())
+ } else {
+ Err(self)
+ }
+ }
+
+ /// Performs a dynamic cast (checked at runtime) of this value into the
+ /// target type `T`.
+ ///
+ /// This method will return `None` if `self.has_type::<T>()`
+ /// returns `false`, and otherwise it will return `Some(&T)` manufactured
+ /// with an unchecked cast (verified correct via the `has_type` operation).
+ fn dyn_ref<T>(&self) -> Option<&T>
+ where
+ T: JsCast,
+ {
+ if self.has_type::<T>() {
+ Some(self.unchecked_ref())
+ } else {
+ None
+ }
+ }
+
+ /// Performs a zero-cost unchecked cast into the specified type.
+ ///
+ /// This method will convert the `self` value to the type `T`, where both
+ /// `self` and `T` are simple wrappers around `JsValue`. This method **does
+ /// not check whether `self` is an instance of `T`**. If used incorrectly
+ /// then this method may cause runtime exceptions in both Rust and JS, this
+ /// should be used with caution.
+ fn unchecked_into<T>(self) -> T
+ where
+ T: JsCast,
+ {
+ T::unchecked_from_js(self.into())
+ }
+
+ /// Performs a zero-cost unchecked cast into a reference to the specified
+ /// type.
+ ///
+ /// This method will convert the `self` value to the type `T`, where both
+ /// `self` and `T` are simple wrappers around `JsValue`. This method **does
+ /// not check whether `self` is an instance of `T`**. If used incorrectly
+ /// then this method may cause runtime exceptions in both Rust and JS, this
+ /// should be used with caution.
+ ///
+ /// This method, unlike `unchecked_into`, does not consume ownership of
+ /// `self` and instead works over a shared reference.
+ fn unchecked_ref<T>(&self) -> &T
+ where
+ T: JsCast,
+ {
+ T::unchecked_from_js_ref(self.as_ref())
+ }
+
+ /// Test whether this JS value is an instance of the type `T`.
+ ///
+ /// This method performs a dynamic check (at runtime) using the JS
+ /// `instanceof` operator. This method returns `self instanceof T`.
+ ///
+ /// Note that `instanceof` does not always work with primitive values or
+ /// across different realms (e.g. iframes). If you're not sure whether you
+ /// specifically need only `instanceof` it's recommended to use `has_type`
+ /// instead.
+ fn is_instance_of<T>(&self) -> bool
+ where
+ T: JsCast,
+ {
+ T::instanceof(self.as_ref())
+ }
+
+ /// Performs a dynamic `instanceof` check to see whether the `JsValue`
+ /// provided is an instance of this type.
+ ///
+ /// This is intended to be an internal implementation detail, you likely
+ /// won't need to call this. It's generally called through the
+ /// `is_instance_of` method instead.
+ fn instanceof(val: &JsValue) -> bool;
+
+ /// Performs a dynamic check to see whether the `JsValue` provided
+ /// is a value of this type.
+ ///
+ /// Unlike `instanceof`, this can be specialised to use a custom check by
+ /// adding a `#[wasm_bindgen(is_type_of = callback)]` attribute to the
+ /// type import declaration.
+ ///
+ /// Other than that, this is intended to be an internal implementation
+ /// detail of `has_type` and you likely won't need to call this.
+ fn is_type_of(val: &JsValue) -> bool {
+ Self::instanceof(val)
+ }
+
+ /// Performs a zero-cost unchecked conversion from a `JsValue` into an
+ /// instance of `Self`
+ ///
+ /// This is intended to be an internal implementation detail, you likely
+ /// won't need to call this.
+ fn unchecked_from_js(val: JsValue) -> Self;
+
+ /// Performs a zero-cost unchecked conversion from a `&JsValue` into an
+ /// instance of `&Self`.
+ ///
+ /// Note the safety of this method, which basically means that `Self` must
+ /// be a newtype wrapper around `JsValue`.
+ ///
+ /// This is intended to be an internal implementation detail, you likely
+ /// won't need to call this.
+ fn unchecked_from_js_ref(val: &JsValue) -> &Self;
+}
+
+/// Trait implemented for wrappers around `JsValue`s generated by `#[wasm_bindgen]`.
+#[doc(hidden)]
+pub trait JsObject: JsCast + WasmDescribe {}
diff --git a/vendor/wasm-bindgen/src/closure.rs b/vendor/wasm-bindgen/src/closure.rs
new file mode 100644
index 000000000..37cef06dc
--- /dev/null
+++ b/vendor/wasm-bindgen/src/closure.rs
@@ -0,0 +1,885 @@
+//! Support for long-lived closures in `wasm-bindgen`
+//!
+//! This module defines the `Closure` type which is used to pass "owned
+//! closures" from Rust to JS. Some more details can be found on the `Closure`
+//! type itself.
+
+use std::fmt;
+use std::mem::{self, ManuallyDrop};
+use std::prelude::v1::*;
+
+use crate::convert::*;
+use crate::describe::*;
+use crate::throw_str;
+use crate::JsValue;
+use crate::UnwrapThrowExt;
+
+/// A handle to both a closure in Rust as well as JS closure which will invoke
+/// the Rust closure.
+///
+/// A `Closure` is the primary way that a `'static` lifetime closure is
+/// transferred from Rust to JS. `Closure` currently requires that the closures
+/// it's created with have the `'static` lifetime in Rust for soundness reasons.
+///
+/// This type is a "handle" in the sense that whenever it is dropped it will
+/// invalidate the JS closure that it refers to. Any usage of the closure in JS
+/// after the `Closure` has been dropped will raise an exception. It's then up
+/// to you to arrange for `Closure` to be properly deallocate at an appropriate
+/// location in your program.
+///
+/// The type parameter on `Closure` is the type of closure that this represents.
+/// Currently this can only be the `Fn` and `FnMut` traits with up to 7
+/// arguments (and an optional return value).
+///
+/// # Examples
+///
+/// Here are a number of examples of using `Closure`.
+///
+/// ## Using the `setInterval` API
+///
+/// Sample usage of `Closure` to invoke the `setInterval` API.
+///
+/// ```rust,no_run
+/// use wasm_bindgen::prelude::*;
+///
+/// #[wasm_bindgen]
+/// extern "C" {
+/// fn setInterval(closure: &Closure<dyn FnMut()>, time: u32) -> i32;
+/// fn clearInterval(id: i32);
+///
+/// #[wasm_bindgen(js_namespace = console)]
+/// fn log(s: &str);
+/// }
+///
+/// #[wasm_bindgen]
+/// pub struct IntervalHandle {
+/// interval_id: i32,
+/// _closure: Closure<dyn FnMut()>,
+/// }
+///
+/// impl Drop for IntervalHandle {
+/// fn drop(&mut self) {
+/// clearInterval(self.interval_id);
+/// }
+/// }
+///
+/// #[wasm_bindgen]
+/// pub fn run() -> IntervalHandle {
+/// // First up we use `Closure::new` to wrap up a Rust closure and create
+/// // a JS closure.
+/// let cb = Closure::new(|| {
+/// log("interval elapsed!");
+/// });
+///
+/// // Next we pass this via reference to the `setInterval` function, and
+/// // `setInterval` gets a handle to the corresponding JS closure.
+/// let interval_id = setInterval(&cb, 1_000);
+///
+/// // If we were to drop `cb` here it would cause an exception to be raised
+/// // whenever the interval elapses. Instead we *return* our handle back to JS
+/// // so JS can decide when to cancel the interval and deallocate the closure.
+/// IntervalHandle {
+/// interval_id,
+/// _closure: cb,
+/// }
+/// }
+/// ```
+///
+/// ## Casting a `Closure` to a `js_sys::Function`
+///
+/// This is the same `setInterval` example as above, except it is using
+/// `web_sys` (which uses `js_sys::Function` for callbacks) instead of manually
+/// writing bindings to `setInterval` and other Web APIs.
+///
+/// ```rust,ignore
+/// use wasm_bindgen::JsCast;
+///
+/// #[wasm_bindgen]
+/// pub struct IntervalHandle {
+/// interval_id: i32,
+/// _closure: Closure<dyn FnMut()>,
+/// }
+///
+/// impl Drop for IntervalHandle {
+/// fn drop(&mut self) {
+/// let window = web_sys::window().unwrap();
+/// window.clear_interval_with_handle(self.interval_id);
+/// }
+/// }
+///
+/// #[wasm_bindgen]
+/// pub fn run() -> Result<IntervalHandle, JsValue> {
+/// let cb = Closure::new(|| {
+/// web_sys::console::log_1(&"interval elapsed!".into());
+/// });
+///
+/// let window = web_sys::window().unwrap();
+/// let interval_id = window.set_interval_with_callback_and_timeout_and_arguments_0(
+/// // Note this method call, which uses `as_ref()` to get a `JsValue`
+/// // from our `Closure` which is then converted to a `&Function`
+/// // using the `JsCast::unchecked_ref` function.
+/// cb.as_ref().unchecked_ref(),
+/// 1_000,
+/// )?;
+///
+/// // Same as above.
+/// Ok(IntervalHandle {
+/// interval_id,
+/// _closure: cb,
+/// })
+/// }
+/// ```
+///
+/// ## Using `FnOnce` and `Closure::once` with `requestAnimationFrame`
+///
+/// Because `requestAnimationFrame` only calls its callback once, we can use
+/// `FnOnce` and `Closure::once` with it.
+///
+/// ```rust,no_run
+/// use wasm_bindgen::prelude::*;
+///
+/// #[wasm_bindgen]
+/// extern "C" {
+/// fn requestAnimationFrame(closure: &Closure<dyn FnMut()>) -> u32;
+/// fn cancelAnimationFrame(id: u32);
+///
+/// #[wasm_bindgen(js_namespace = console)]
+/// fn log(s: &str);
+/// }
+///
+/// #[wasm_bindgen]
+/// pub struct AnimationFrameHandle {
+/// animation_id: u32,
+/// _closure: Closure<dyn FnMut()>,
+/// }
+///
+/// impl Drop for AnimationFrameHandle {
+/// fn drop(&mut self) {
+/// cancelAnimationFrame(self.animation_id);
+/// }
+/// }
+///
+/// // A type that will log a message when it is dropped.
+/// struct LogOnDrop(&'static str);
+/// impl Drop for LogOnDrop {
+/// fn drop(&mut self) {
+/// log(self.0);
+/// }
+/// }
+///
+/// #[wasm_bindgen]
+/// pub fn run() -> AnimationFrameHandle {
+/// // We are using `Closure::once` which takes a `FnOnce`, so the function
+/// // can drop and/or move things that it closes over.
+/// let fired = LogOnDrop("animation frame fired or canceled");
+/// let cb = Closure::once(move || drop(fired));
+///
+/// // Schedule the animation frame!
+/// let animation_id = requestAnimationFrame(&cb);
+///
+/// // Again, return a handle to JS, so that the closure is not dropped
+/// // immediately and JS can decide whether to cancel the animation frame.
+/// AnimationFrameHandle {
+/// animation_id,
+/// _closure: cb,
+/// }
+/// }
+/// ```
+///
+/// ## Converting `FnOnce`s directly into JavaScript Functions with `Closure::once_into_js`
+///
+/// If we don't want to allow a `FnOnce` to be eagerly dropped (maybe because we
+/// just want it to drop after it is called and don't care about cancellation)
+/// then we can use the `Closure::once_into_js` function.
+///
+/// This is the same `requestAnimationFrame` example as above, but without
+/// supporting early cancellation.
+///
+/// ```
+/// use wasm_bindgen::prelude::*;
+///
+/// #[wasm_bindgen]
+/// extern "C" {
+/// // We modify the binding to take an untyped `JsValue` since that is what
+/// // is returned by `Closure::once_into_js`.
+/// //
+/// // If we were using the `web_sys` binding for `requestAnimationFrame`,
+/// // then the call sites would cast the `JsValue` into a `&js_sys::Function`
+/// // using `f.unchecked_ref::<js_sys::Function>()`. See the `web_sys`
+/// // example above for details.
+/// fn requestAnimationFrame(callback: JsValue);
+///
+/// #[wasm_bindgen(js_namespace = console)]
+/// fn log(s: &str);
+/// }
+///
+/// // A type that will log a message when it is dropped.
+/// struct LogOnDrop(&'static str);
+/// impl Drop for LogOnDrop {
+/// fn drop(&mut self) {
+/// log(self.0);
+/// }
+/// }
+///
+/// #[wasm_bindgen]
+/// pub fn run() {
+/// // We are using `Closure::once_into_js` which takes a `FnOnce` and
+/// // converts it into a JavaScript function, which is returned as a
+/// // `JsValue`.
+/// let fired = LogOnDrop("animation frame fired");
+/// let cb = Closure::once_into_js(move || drop(fired));
+///
+/// // Schedule the animation frame!
+/// requestAnimationFrame(cb);
+///
+/// // No need to worry about whether or not we drop a `Closure`
+/// // here or return some sort of handle to JS!
+/// }
+/// ```
+pub struct Closure<T: ?Sized> {
+ js: ManuallyDrop<JsValue>,
+ data: ManuallyDrop<Box<T>>,
+}
+
+union FatPtr<T: ?Sized> {
+ ptr: *mut T,
+ fields: (usize, usize),
+}
+
+impl<T> Closure<T>
+where
+ T: ?Sized + WasmClosure,
+{
+ /// Creates a new instance of `Closure` from the provided Rust function.
+ ///
+ /// Note that the closure provided here, `F`, has a few requirements
+ /// associated with it:
+ ///
+ /// * It must implement `Fn` or `FnMut` (for `FnOnce` functions see
+ /// `Closure::once` and `Closure::once_into_js`).
+ ///
+ /// * It must be `'static`, aka no stack references (use the `move`
+ /// keyword).
+ ///
+ /// * It can have at most 7 arguments.
+ ///
+ /// * Its arguments and return values are all types that can be shared with
+ /// JS (i.e. have `#[wasm_bindgen]` annotations or are simple numbers,
+ /// etc.)
+ pub fn new<F>(t: F) -> Closure<T>
+ where
+ F: IntoWasmClosure<T> + 'static,
+ {
+ Closure::wrap(Box::new(t).unsize())
+ }
+
+ /// A more direct version of `Closure::new` which creates a `Closure` from
+ /// a `Box<dyn Fn>`/`Box<dyn FnMut>`, which is how it's kept internally.
+ pub fn wrap(mut data: Box<T>) -> Closure<T> {
+ assert_eq!(mem::size_of::<*const T>(), mem::size_of::<FatPtr<T>>());
+ let (a, b) = unsafe {
+ FatPtr {
+ ptr: &mut *data as *mut T,
+ }
+ .fields
+ };
+
+ // Here we need to create a `JsValue` with the data and `T::invoke()`
+ // function pointer. To do that we... take a few unconventional turns.
+ // In essence what happens here is this:
+ //
+ // 1. First up, below we call a function, `breaks_if_inlined`. This
+ // function, as the name implies, does not work if it's inlined.
+ // More on that in a moment.
+ // 2. This function internally calls a special import recognized by the
+ // `wasm-bindgen` CLI tool, `__wbindgen_describe_closure`. This
+ // imported symbol is similar to `__wbindgen_describe` in that it's
+ // not intended to show up in the final binary but it's an
+ // intermediate state for a `wasm-bindgen` binary.
+ // 3. The `__wbindgen_describe_closure` import is namely passed a
+ // descriptor function, monomorphized for each invocation.
+ //
+ // Most of this doesn't actually make sense to happen at runtime! The
+ // real magic happens when `wasm-bindgen` comes along and updates our
+ // generated code. When `wasm-bindgen` runs it performs a few tasks:
+ //
+ // * First, it finds all functions that call
+ // `__wbindgen_describe_closure`. These are all `breaks_if_inlined`
+ // defined below as the symbol isn't called anywhere else.
+ // * Next, `wasm-bindgen` executes the `breaks_if_inlined`
+ // monomorphized functions, passing it dummy arguments. This will
+ // execute the function just enough to invoke the special import,
+ // namely telling us about the function pointer that is the describe
+ // shim.
+ // * This knowledge is then used to actually find the descriptor in the
+ // function table which is then executed to figure out the signature
+ // of the closure.
+ // * Finally, and probably most heinously, the call to
+ // `breaks_if_inlined` is rewritten to call an otherwise globally
+ // imported function. This globally imported function will generate
+ // the `JsValue` for this closure specialized for the signature in
+ // question.
+ //
+ // Later on `wasm-gc` will clean up all the dead code and ensure that
+ // we don't actually call `__wbindgen_describe_closure` at runtime. This
+ // means we will end up not actually calling `breaks_if_inlined` in the
+ // final binary, all calls to that function should be pruned.
+ //
+ // See crates/cli-support/src/js/closures.rs for a more information
+ // about what's going on here.
+
+ extern "C" fn describe<T: WasmClosure + ?Sized>() {
+ inform(CLOSURE);
+ T::describe()
+ }
+
+ #[inline(never)]
+ unsafe fn breaks_if_inlined<T: WasmClosure + ?Sized>(a: usize, b: usize) -> u32 {
+ super::__wbindgen_describe_closure(a as u32, b as u32, describe::<T> as u32)
+ }
+
+ let idx = unsafe { breaks_if_inlined::<T>(a, b) };
+
+ Closure {
+ js: ManuallyDrop::new(JsValue::_new(idx)),
+ data: ManuallyDrop::new(data),
+ }
+ }
+
+ /// Release memory management of this closure from Rust to the JS GC.
+ ///
+ /// When a `Closure` is dropped it will release the Rust memory and
+ /// invalidate the associated JS closure, but this isn't always desired.
+ /// Some callbacks are alive for the entire duration of the program or for a
+ /// lifetime dynamically managed by the JS GC. This function can be used
+ /// to drop this `Closure` while keeping the associated JS function still
+ /// valid.
+ ///
+ /// By default this function will leak memory. This can be dangerous if this
+ /// function is called many times in an application because the memory leak
+ /// will overwhelm the page quickly and crash the wasm.
+ ///
+ /// If the browser, however, supports weak references, then this function
+ /// will not leak memory. Instead the Rust memory will be reclaimed when the
+ /// JS closure is GC'd. Weak references are not enabled by default since
+ /// they're still a proposal for the JS standard. They can be enabled with
+ /// `WASM_BINDGEN_WEAKREF=1` when running `wasm-bindgen`, however.
+ pub fn into_js_value(self) -> JsValue {
+ let idx = self.js.idx;
+ mem::forget(self);
+ JsValue::_new(idx)
+ }
+
+ /// Same as `into_js_value`, but doesn't return a value.
+ pub fn forget(self) {
+ drop(self.into_js_value());
+ }
+}
+
+// NB: we use a specific `T` for this `Closure<T>` impl block to avoid every
+// call site having to provide an explicit, turbo-fished type like
+// `Closure::<dyn FnOnce()>::once(...)`.
+impl Closure<dyn FnOnce()> {
+ /// Create a `Closure` from a function that can only be called once.
+ ///
+ /// Since we have no way of enforcing that JS cannot attempt to call this
+ /// `FnOne(A...) -> R` more than once, this produces a `Closure<dyn FnMut(A...)
+ /// -> R>` that will dynamically throw a JavaScript error if called more
+ /// than once.
+ ///
+ /// # Example
+ ///
+ /// ```rust,no_run
+ /// use wasm_bindgen::prelude::*;
+ ///
+ /// // Create an non-`Copy`, owned `String`.
+ /// let mut s = String::from("Hello");
+ ///
+ /// // Close over `s`. Since `f` returns `s`, it is `FnOnce` and can only be
+ /// // called once. If it was called a second time, it wouldn't have any `s`
+ /// // to work with anymore!
+ /// let f = move || {
+ /// s += ", World!";
+ /// s
+ /// };
+ ///
+ /// // Create a `Closure` from `f`. Note that the `Closure`'s type parameter
+ /// // is `FnMut`, even though `f` is `FnOnce`.
+ /// let closure: Closure<dyn FnMut() -> String> = Closure::once(f);
+ /// ```
+ pub fn once<F, A, R>(fn_once: F) -> Closure<F::FnMut>
+ where
+ F: 'static + WasmClosureFnOnce<A, R>,
+ {
+ Closure::wrap(fn_once.into_fn_mut())
+ }
+
+ /// Convert a `FnOnce(A...) -> R` into a JavaScript `Function` object.
+ ///
+ /// If the JavaScript function is invoked more than once, it will throw an
+ /// exception.
+ ///
+ /// Unlike `Closure::once`, this does *not* return a `Closure` that can be
+ /// dropped before the function is invoked to deallocate the closure. The
+ /// only way the `FnOnce` is deallocated is by calling the JavaScript
+ /// function. If the JavaScript function is never called then the `FnOnce`
+ /// and everything it closes over will leak.
+ ///
+ /// ```rust,ignore
+ /// use wasm_bindgen::{prelude::*, JsCast};
+ ///
+ /// let f = Closure::once_into_js(move || {
+ /// // ...
+ /// });
+ ///
+ /// assert!(f.is_instance_of::<js_sys::Function>());
+ /// ```
+ pub fn once_into_js<F, A, R>(fn_once: F) -> JsValue
+ where
+ F: 'static + WasmClosureFnOnce<A, R>,
+ {
+ fn_once.into_js_function()
+ }
+}
+
+/// A trait for converting an `FnOnce(A...) -> R` into a `FnMut(A...) -> R` that
+/// will throw if ever called more than once.
+#[doc(hidden)]
+pub trait WasmClosureFnOnce<A, R>: 'static {
+ type FnMut: ?Sized + 'static + WasmClosure;
+
+ fn into_fn_mut(self) -> Box<Self::FnMut>;
+
+ fn into_js_function(self) -> JsValue;
+}
+
+impl<T: ?Sized> AsRef<JsValue> for Closure<T> {
+ fn as_ref(&self) -> &JsValue {
+ &self.js
+ }
+}
+
+impl<T> WasmDescribe for Closure<T>
+where
+ T: WasmClosure + ?Sized,
+{
+ fn describe() {
+ inform(EXTERNREF);
+ }
+}
+
+// `Closure` can only be passed by reference to imports.
+impl<'a, T> IntoWasmAbi for &'a Closure<T>
+where
+ T: WasmClosure + ?Sized,
+{
+ type Abi = u32;
+
+ fn into_abi(self) -> u32 {
+ (&*self.js).into_abi()
+ }
+}
+
+impl<'a, T> OptionIntoWasmAbi for &'a Closure<T>
+where
+ T: WasmClosure + ?Sized,
+{
+ fn none() -> Self::Abi {
+ 0
+ }
+}
+
+fn _check() {
+ fn _assert<T: IntoWasmAbi>() {}
+ _assert::<&Closure<dyn Fn()>>();
+ _assert::<&Closure<dyn Fn(String)>>();
+ _assert::<&Closure<dyn Fn() -> String>>();
+ _assert::<&Closure<dyn FnMut()>>();
+ _assert::<&Closure<dyn FnMut(String)>>();
+ _assert::<&Closure<dyn FnMut() -> String>>();
+}
+
+impl<T> fmt::Debug for Closure<T>
+where
+ T: ?Sized,
+{
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "Closure {{ ... }}")
+ }
+}
+
+impl<T> Drop for Closure<T>
+where
+ T: ?Sized,
+{
+ fn drop(&mut self) {
+ unsafe {
+ // this will implicitly drop our strong reference in addition to
+ // invalidating all future invocations of the closure
+ if super::__wbindgen_cb_drop(self.js.idx) != 0 {
+ ManuallyDrop::drop(&mut self.data);
+ }
+ }
+ }
+}
+
+/// An internal trait for the `Closure` type.
+///
+/// This trait is not stable and it's not recommended to use this in bounds or
+/// implement yourself.
+#[doc(hidden)]
+pub unsafe trait WasmClosure {
+ fn describe();
+}
+
+/// An internal trait for the `Closure` type.
+///
+/// This trait is not stable and it's not recommended to use this in bounds or
+/// implement yourself.
+#[doc(hidden)]
+pub trait IntoWasmClosure<T: ?Sized> {
+ fn unsize(self: Box<Self>) -> Box<T>;
+}
+
+// The memory safety here in these implementations below is a bit tricky. We
+// want to be able to drop the `Closure` object from within the invocation of a
+// `Closure` for cases like promises. That means that while it's running we
+// might drop the `Closure`, but that shouldn't invalidate the environment yet.
+//
+// Instead what we do is to wrap closures in `Rc` variables. The main `Closure`
+// has a strong reference count which keeps the trait object alive. Each
+// invocation of a closure then *also* clones this and gets a new reference
+// count. When the closure returns it will release the reference count.
+//
+// This means that if the main `Closure` is dropped while it's being invoked
+// then destruction is deferred until execution returns. Otherwise it'll
+// deallocate data immediately.
+
+macro_rules! doit {
+ ($(
+ ($($var:ident)*)
+ )*) => ($(
+ unsafe impl<$($var,)* R> WasmClosure for dyn Fn($($var),*) -> R + 'static
+ where $($var: FromWasmAbi + 'static,)*
+ R: ReturnWasmAbi + 'static,
+ {
+ fn describe() {
+ #[allow(non_snake_case)]
+ unsafe extern "C" fn invoke<$($var: FromWasmAbi,)* R: ReturnWasmAbi>(
+ a: usize,
+ b: usize,
+ $($var: <$var as FromWasmAbi>::Abi),*
+ ) -> <R as ReturnWasmAbi>::Abi {
+ if a == 0 {
+ throw_str("closure invoked recursively or destroyed already");
+ }
+ // Make sure all stack variables are converted before we
+ // convert `ret` as it may throw (for `Result`, for
+ // example)
+ let ret = {
+ let f: *const dyn Fn($($var),*) -> R =
+ FatPtr { fields: (a, b) }.ptr;
+ $(
+ let $var = <$var as FromWasmAbi>::from_abi($var);
+ )*
+ (*f)($($var),*)
+ };
+ ret.return_abi()
+ }
+
+ inform(invoke::<$($var,)* R> as u32);
+
+ unsafe extern fn destroy<$($var: FromWasmAbi,)* R: ReturnWasmAbi>(
+ a: usize,
+ b: usize,
+ ) {
+ // This can be called by the JS glue in erroneous situations
+ // such as when the closure has already been destroyed. If
+ // that's the case let's not make things worse by
+ // segfaulting and/or asserting, so just ignore null
+ // pointers.
+ if a == 0 {
+ return;
+ }
+ drop(Box::from_raw(FatPtr::<dyn Fn($($var,)*) -> R> {
+ fields: (a, b)
+ }.ptr));
+ }
+ inform(destroy::<$($var,)* R> as u32);
+
+ <&Self>::describe();
+ }
+ }
+
+ unsafe impl<$($var,)* R> WasmClosure for dyn FnMut($($var),*) -> R + 'static
+ where $($var: FromWasmAbi + 'static,)*
+ R: ReturnWasmAbi + 'static,
+ {
+ fn describe() {
+ #[allow(non_snake_case)]
+ unsafe extern "C" fn invoke<$($var: FromWasmAbi,)* R: ReturnWasmAbi>(
+ a: usize,
+ b: usize,
+ $($var: <$var as FromWasmAbi>::Abi),*
+ ) -> <R as ReturnWasmAbi>::Abi {
+ if a == 0 {
+ throw_str("closure invoked recursively or destroyed already");
+ }
+ // Make sure all stack variables are converted before we
+ // convert `ret` as it may throw (for `Result`, for
+ // example)
+ let ret = {
+ let f: *const dyn FnMut($($var),*) -> R =
+ FatPtr { fields: (a, b) }.ptr;
+ let f = f as *mut dyn FnMut($($var),*) -> R;
+ $(
+ let $var = <$var as FromWasmAbi>::from_abi($var);
+ )*
+ (*f)($($var),*)
+ };
+ ret.return_abi()
+ }
+
+ inform(invoke::<$($var,)* R> as u32);
+
+ unsafe extern fn destroy<$($var: FromWasmAbi,)* R: ReturnWasmAbi>(
+ a: usize,
+ b: usize,
+ ) {
+ // See `Fn()` above for why we simply return
+ if a == 0 {
+ return;
+ }
+ drop(Box::from_raw(FatPtr::<dyn FnMut($($var,)*) -> R> {
+ fields: (a, b)
+ }.ptr));
+ }
+ inform(destroy::<$($var,)* R> as u32);
+
+ <&mut Self>::describe();
+ }
+ }
+
+ #[allow(non_snake_case, unused_parens)]
+ impl<T, $($var,)* R> WasmClosureFnOnce<($($var),*), R> for T
+ where T: 'static + FnOnce($($var),*) -> R,
+ $($var: FromWasmAbi + 'static,)*
+ R: ReturnWasmAbi + 'static
+ {
+ type FnMut = dyn FnMut($($var),*) -> R;
+
+ fn into_fn_mut(self) -> Box<Self::FnMut> {
+ let mut me = Some(self);
+ Box::new(move |$($var),*| {
+ let me = me.take().expect_throw("FnOnce called more than once");
+ me($($var),*)
+ })
+ }
+
+ fn into_js_function(self) -> JsValue {
+ use std::rc::Rc;
+ use crate::__rt::WasmRefCell;
+
+ let mut me = Some(self);
+
+ let rc1 = Rc::new(WasmRefCell::new(None));
+ let rc2 = rc1.clone();
+
+ let closure = Closure::wrap(Box::new(move |$($var),*| {
+ // Invoke ourself and get the result.
+ let me = me.take().expect_throw("FnOnce called more than once");
+ let result = me($($var),*);
+
+ // And then drop the `Rc` holding this function's `Closure`
+ // alive.
+ debug_assert_eq!(Rc::strong_count(&rc2), 1);
+ let option_closure = rc2.borrow_mut().take();
+ debug_assert!(option_closure.is_some());
+ drop(option_closure);
+
+ result
+ }) as Box<dyn FnMut($($var),*) -> R>);
+
+ let js_val = closure.as_ref().clone();
+
+ *rc1.borrow_mut() = Some(closure);
+ debug_assert_eq!(Rc::strong_count(&rc1), 2);
+ drop(rc1);
+
+ js_val
+ }
+ }
+
+ impl<T, $($var,)* R> IntoWasmClosure<dyn FnMut($($var),*) -> R> for T
+ where T: 'static + FnMut($($var),*) -> R,
+ $($var: FromWasmAbi + 'static,)*
+ R: ReturnWasmAbi + 'static,
+ {
+ fn unsize(self: Box<Self>) -> Box<dyn FnMut($($var),*) -> R> { self }
+ }
+
+ impl<T, $($var,)* R> IntoWasmClosure<dyn Fn($($var),*) -> R> for T
+ where T: 'static + Fn($($var),*) -> R,
+ $($var: FromWasmAbi + 'static,)*
+ R: ReturnWasmAbi + 'static,
+ {
+ fn unsize(self: Box<Self>) -> Box<dyn Fn($($var),*) -> R> { self }
+ }
+ )*)
+}
+
+doit! {
+ ()
+ (A)
+ (A B)
+ (A B C)
+ (A B C D)
+ (A B C D E)
+ (A B C D E F)
+ (A B C D E F G)
+ (A B C D E F G H)
+}
+
+// Copy the above impls down here for where there's only one argument and it's a
+// reference. We could add more impls for more kinds of references, but it
+// becomes a combinatorial explosion quickly. Let's see how far we can get with
+// just this one! Maybe someone else can figure out voodoo so we don't have to
+// duplicate.
+
+unsafe impl<A, R> WasmClosure for dyn Fn(&A) -> R
+where
+ A: RefFromWasmAbi,
+ R: ReturnWasmAbi + 'static,
+{
+ fn describe() {
+ #[allow(non_snake_case)]
+ unsafe extern "C" fn invoke<A: RefFromWasmAbi, R: ReturnWasmAbi>(
+ a: usize,
+ b: usize,
+ arg: <A as RefFromWasmAbi>::Abi,
+ ) -> <R as ReturnWasmAbi>::Abi {
+ if a == 0 {
+ throw_str("closure invoked recursively or destroyed already");
+ }
+ // Make sure all stack variables are converted before we
+ // convert `ret` as it may throw (for `Result`, for
+ // example)
+ let ret = {
+ let f: *const dyn Fn(&A) -> R = FatPtr { fields: (a, b) }.ptr;
+ let arg = <A as RefFromWasmAbi>::ref_from_abi(arg);
+ (*f)(&*arg)
+ };
+ ret.return_abi()
+ }
+
+ inform(invoke::<A, R> as u32);
+
+ unsafe extern "C" fn destroy<A: RefFromWasmAbi, R: ReturnWasmAbi>(a: usize, b: usize) {
+ // See `Fn()` above for why we simply return
+ if a == 0 {
+ return;
+ }
+ drop(Box::from_raw(
+ FatPtr::<dyn Fn(&A) -> R> { fields: (a, b) }.ptr,
+ ));
+ }
+ inform(destroy::<A, R> as u32);
+
+ <&Self>::describe();
+ }
+}
+
+unsafe impl<A, R> WasmClosure for dyn FnMut(&A) -> R
+where
+ A: RefFromWasmAbi,
+ R: ReturnWasmAbi + 'static,
+{
+ fn describe() {
+ #[allow(non_snake_case)]
+ unsafe extern "C" fn invoke<A: RefFromWasmAbi, R: ReturnWasmAbi>(
+ a: usize,
+ b: usize,
+ arg: <A as RefFromWasmAbi>::Abi,
+ ) -> <R as ReturnWasmAbi>::Abi {
+ if a == 0 {
+ throw_str("closure invoked recursively or destroyed already");
+ }
+ // Make sure all stack variables are converted before we
+ // convert `ret` as it may throw (for `Result`, for
+ // example)
+ let ret = {
+ let f: *const dyn FnMut(&A) -> R = FatPtr { fields: (a, b) }.ptr;
+ let f = f as *mut dyn FnMut(&A) -> R;
+ let arg = <A as RefFromWasmAbi>::ref_from_abi(arg);
+ (*f)(&*arg)
+ };
+ ret.return_abi()
+ }
+
+ inform(invoke::<A, R> as u32);
+
+ unsafe extern "C" fn destroy<A: RefFromWasmAbi, R: ReturnWasmAbi>(a: usize, b: usize) {
+ // See `Fn()` above for why we simply return
+ if a == 0 {
+ return;
+ }
+ drop(Box::from_raw(
+ FatPtr::<dyn FnMut(&A) -> R> { fields: (a, b) }.ptr,
+ ));
+ }
+ inform(destroy::<A, R> as u32);
+
+ <&mut Self>::describe();
+ }
+}
+
+#[allow(non_snake_case)]
+impl<T, A, R> WasmClosureFnOnce<(&A,), R> for T
+where
+ T: 'static + FnOnce(&A) -> R,
+ A: RefFromWasmAbi + 'static,
+ R: ReturnWasmAbi + 'static,
+{
+ type FnMut = dyn FnMut(&A) -> R;
+
+ fn into_fn_mut(self) -> Box<Self::FnMut> {
+ let mut me = Some(self);
+ Box::new(move |arg| {
+ let me = me.take().expect_throw("FnOnce called more than once");
+ me(arg)
+ })
+ }
+
+ fn into_js_function(self) -> JsValue {
+ use crate::__rt::WasmRefCell;
+ use std::rc::Rc;
+
+ let mut me = Some(self);
+
+ let rc1 = Rc::new(WasmRefCell::new(None));
+ let rc2 = rc1.clone();
+
+ let closure = Closure::wrap(Box::new(move |arg: &A| {
+ // Invoke ourself and get the result.
+ let me = me.take().expect_throw("FnOnce called more than once");
+ let result = me(arg);
+
+ // And then drop the `Rc` holding this function's `Closure`
+ // alive.
+ debug_assert_eq!(Rc::strong_count(&rc2), 1);
+ let option_closure = rc2.borrow_mut().take();
+ debug_assert!(option_closure.is_some());
+ drop(option_closure);
+
+ result
+ }) as Box<dyn FnMut(&A) -> R>);
+
+ let js_val = closure.as_ref().clone();
+
+ *rc1.borrow_mut() = Some(closure);
+ debug_assert_eq!(Rc::strong_count(&rc1), 2);
+ drop(rc1);
+
+ js_val
+ }
+}
diff --git a/vendor/wasm-bindgen/src/convert/closures.rs b/vendor/wasm-bindgen/src/convert/closures.rs
new file mode 100644
index 000000000..97755b8ee
--- /dev/null
+++ b/vendor/wasm-bindgen/src/convert/closures.rs
@@ -0,0 +1,225 @@
+use core::mem;
+
+use crate::convert::slices::WasmSlice;
+use crate::convert::RefFromWasmAbi;
+use crate::convert::{FromWasmAbi, IntoWasmAbi, ReturnWasmAbi};
+use crate::describe::{inform, WasmDescribe, FUNCTION};
+use crate::throw_str;
+
+macro_rules! stack_closures {
+ ($( ($cnt:tt $invoke:ident $invoke_mut:ident $($var:ident)*) )*) => ($(
+ impl<'a, 'b, $($var,)* R> IntoWasmAbi for &'a (dyn Fn($($var),*) -> R + 'b)
+ where $($var: FromWasmAbi,)*
+ R: ReturnWasmAbi
+ {
+ type Abi = WasmSlice;
+
+ fn into_abi(self) -> WasmSlice {
+ unsafe {
+ let (a, b): (usize, usize) = mem::transmute(self);
+ WasmSlice { ptr: a as u32, len: b as u32 }
+ }
+ }
+ }
+
+ #[allow(non_snake_case)]
+ unsafe extern "C" fn $invoke<$($var: FromWasmAbi,)* R: ReturnWasmAbi>(
+ a: usize,
+ b: usize,
+ $($var: <$var as FromWasmAbi>::Abi),*
+ ) -> <R as ReturnWasmAbi>::Abi {
+ if a == 0 {
+ throw_str("closure invoked recursively or destroyed already");
+ }
+ // Scope all local variables before we call `return_abi` to
+ // ensure they're all destroyed as `return_abi` may throw
+ let ret = {
+ let f: &dyn Fn($($var),*) -> R = mem::transmute((a, b));
+ $(
+ let $var = <$var as FromWasmAbi>::from_abi($var);
+ )*
+ f($($var),*)
+ };
+ ret.return_abi()
+ }
+
+ impl<'a, $($var,)* R> WasmDescribe for dyn Fn($($var),*) -> R + 'a
+ where $($var: FromWasmAbi,)*
+ R: ReturnWasmAbi
+ {
+ fn describe() {
+ inform(FUNCTION);
+ inform($invoke::<$($var,)* R> as u32);
+ inform($cnt);
+ $(<$var as WasmDescribe>::describe();)*
+ <R as WasmDescribe>::describe();
+ <R as WasmDescribe>::describe();
+ }
+ }
+
+ impl<'a, 'b, $($var,)* R> IntoWasmAbi for &'a mut (dyn FnMut($($var),*) -> R + 'b)
+ where $($var: FromWasmAbi,)*
+ R: ReturnWasmAbi
+ {
+ type Abi = WasmSlice;
+
+ fn into_abi(self) -> WasmSlice {
+ unsafe {
+ let (a, b): (usize, usize) = mem::transmute(self);
+ WasmSlice { ptr: a as u32, len: b as u32 }
+ }
+ }
+ }
+
+ #[allow(non_snake_case)]
+ unsafe extern "C" fn $invoke_mut<$($var: FromWasmAbi,)* R: ReturnWasmAbi>(
+ a: usize,
+ b: usize,
+ $($var: <$var as FromWasmAbi>::Abi),*
+ ) -> <R as ReturnWasmAbi>::Abi {
+ if a == 0 {
+ throw_str("closure invoked recursively or destroyed already");
+ }
+ // Scope all local variables before we call `return_abi` to
+ // ensure they're all destroyed as `return_abi` may throw
+ let ret = {
+ let f: &mut dyn FnMut($($var),*) -> R = mem::transmute((a, b));
+ $(
+ let $var = <$var as FromWasmAbi>::from_abi($var);
+ )*
+ f($($var),*)
+ };
+ ret.return_abi()
+ }
+
+ impl<'a, $($var,)* R> WasmDescribe for dyn FnMut($($var),*) -> R + 'a
+ where $($var: FromWasmAbi,)*
+ R: ReturnWasmAbi
+ {
+ fn describe() {
+ inform(FUNCTION);
+ inform($invoke_mut::<$($var,)* R> as u32);
+ inform($cnt);
+ $(<$var as WasmDescribe>::describe();)*
+ <R as WasmDescribe>::describe();
+ <R as WasmDescribe>::describe();
+ }
+ }
+ )*)
+}
+
+stack_closures! {
+ (0 invoke0 invoke0_mut)
+ (1 invoke1 invoke1_mut A)
+ (2 invoke2 invoke2_mut A B)
+ (3 invoke3 invoke3_mut A B C)
+ (4 invoke4 invoke4_mut A B C D)
+ (5 invoke5 invoke5_mut A B C D E)
+ (6 invoke6 invoke6_mut A B C D E F)
+ (7 invoke7 invoke7_mut A B C D E F G)
+ (8 invoke8 invoke8_mut A B C D E F G H)
+}
+
+impl<'a, 'b, A, R> IntoWasmAbi for &'a (dyn Fn(&A) -> R + 'b)
+where
+ A: RefFromWasmAbi,
+ R: ReturnWasmAbi,
+{
+ type Abi = WasmSlice;
+
+ fn into_abi(self) -> WasmSlice {
+ unsafe {
+ let (a, b): (usize, usize) = mem::transmute(self);
+ WasmSlice {
+ ptr: a as u32,
+ len: b as u32,
+ }
+ }
+ }
+}
+
+#[allow(non_snake_case)]
+unsafe extern "C" fn invoke1_ref<A: RefFromWasmAbi, R: ReturnWasmAbi>(
+ a: usize,
+ b: usize,
+ arg: <A as RefFromWasmAbi>::Abi,
+) -> <R as ReturnWasmAbi>::Abi {
+ if a == 0 {
+ throw_str("closure invoked recursively or destroyed already");
+ }
+ // Scope all local variables before we call `return_abi` to
+ // ensure they're all destroyed as `return_abi` may throw
+ let ret = {
+ let f: &dyn Fn(&A) -> R = mem::transmute((a, b));
+ let arg = <A as RefFromWasmAbi>::ref_from_abi(arg);
+ f(&*arg)
+ };
+ ret.return_abi()
+}
+
+impl<'a, A, R> WasmDescribe for dyn Fn(&A) -> R + 'a
+where
+ A: RefFromWasmAbi,
+ R: ReturnWasmAbi,
+{
+ fn describe() {
+ inform(FUNCTION);
+ inform(invoke1_ref::<A, R> as u32);
+ inform(1);
+ <&A as WasmDescribe>::describe();
+ <R as WasmDescribe>::describe();
+ <R as WasmDescribe>::describe();
+ }
+}
+
+impl<'a, 'b, A, R> IntoWasmAbi for &'a mut (dyn FnMut(&A) -> R + 'b)
+where
+ A: RefFromWasmAbi,
+ R: ReturnWasmAbi,
+{
+ type Abi = WasmSlice;
+
+ fn into_abi(self) -> WasmSlice {
+ unsafe {
+ let (a, b): (usize, usize) = mem::transmute(self);
+ WasmSlice {
+ ptr: a as u32,
+ len: b as u32,
+ }
+ }
+ }
+}
+
+#[allow(non_snake_case)]
+unsafe extern "C" fn invoke1_mut_ref<A: RefFromWasmAbi, R: ReturnWasmAbi>(
+ a: usize,
+ b: usize,
+ arg: <A as RefFromWasmAbi>::Abi,
+) -> <R as ReturnWasmAbi>::Abi {
+ if a == 0 {
+ throw_str("closure invoked recursively or destroyed already");
+ }
+ // Scope all local variables before we call `return_abi` to
+ // ensure they're all destroyed as `return_abi` may throw
+ let ret = {
+ let f: &mut dyn FnMut(&A) -> R = mem::transmute((a, b));
+ let arg = <A as RefFromWasmAbi>::ref_from_abi(arg);
+ f(&*arg)
+ };
+ ret.return_abi()
+}
+
+impl<'a, A, R> WasmDescribe for dyn FnMut(&A) -> R + 'a
+where
+ A: RefFromWasmAbi,
+ R: ReturnWasmAbi,
+{
+ fn describe() {
+ inform(FUNCTION);
+ inform(invoke1_mut_ref::<A, R> as u32);
+ inform(1);
+ <&A as WasmDescribe>::describe();
+ <R as WasmDescribe>::describe();
+ <R as WasmDescribe>::describe();
+ }
+}
diff --git a/vendor/wasm-bindgen/src/convert/impls.rs b/vendor/wasm-bindgen/src/convert/impls.rs
new file mode 100644
index 000000000..79ccd67af
--- /dev/null
+++ b/vendor/wasm-bindgen/src/convert/impls.rs
@@ -0,0 +1,378 @@
+use core::char;
+use core::mem::{self, ManuallyDrop};
+
+use crate::convert::traits::WasmAbi;
+use crate::convert::{FromWasmAbi, IntoWasmAbi, RefFromWasmAbi};
+use crate::convert::{OptionFromWasmAbi, OptionIntoWasmAbi, ReturnWasmAbi};
+use crate::{Clamped, JsError, JsValue};
+
+unsafe impl WasmAbi for () {}
+
+#[repr(C, u32)]
+pub enum WasmOption<T: WasmAbi> {
+ None,
+ Some(T),
+}
+
+unsafe impl<T: WasmAbi> WasmAbi for WasmOption<T> {}
+
+impl<Abi: WasmAbi> WasmOption<Abi> {
+ pub fn from_option<T: IntoWasmAbi<Abi = Abi>>(option: Option<T>) -> Self {
+ match option {
+ Some(v) => WasmOption::Some(v.into_abi()),
+ None => WasmOption::None,
+ }
+ }
+
+ pub unsafe fn into_option<T: FromWasmAbi<Abi = Abi>>(v: Self) -> Option<T> {
+ match v {
+ WasmOption::Some(v) => Some(T::from_abi(v)),
+ WasmOption::None => None,
+ }
+ }
+}
+
+macro_rules! type_wasm_native {
+ ($($t:tt as $c:tt)*) => ($(
+ impl IntoWasmAbi for $t {
+ type Abi = $c;
+
+ #[inline]
+ fn into_abi(self) -> $c { self as $c }
+ }
+
+ impl FromWasmAbi for $t {
+ type Abi = $c;
+
+ #[inline]
+ unsafe fn from_abi(js: $c) -> Self { js as $t }
+ }
+
+ impl IntoWasmAbi for Option<$t> {
+ type Abi = WasmOption<$c>;
+
+ #[inline]
+ fn into_abi(self) -> Self::Abi {
+ WasmOption::from_option(self.map(|v| v as $c))
+ }
+ }
+
+ impl FromWasmAbi for Option<$t> {
+ type Abi = WasmOption<$c>;
+
+ #[inline]
+ unsafe fn from_abi(js: Self::Abi) -> Self {
+ WasmOption::into_option(js).map(|v: $c| v as $t)
+ }
+ }
+ )*)
+}
+
+type_wasm_native!(
+ i32 as i32
+ isize as i32
+ u32 as u32
+ usize as u32
+ i64 as i64
+ u64 as u64
+ f32 as f32
+ f64 as f64
+);
+
+macro_rules! type_abi_as_u32 {
+ ($($t:tt)*) => ($(
+ impl IntoWasmAbi for $t {
+ type Abi = u32;
+
+ #[inline]
+ fn into_abi(self) -> u32 { self as u32 }
+ }
+
+ impl FromWasmAbi for $t {
+ type Abi = u32;
+
+ #[inline]
+ unsafe fn from_abi(js: u32) -> Self { js as $t }
+ }
+
+ impl OptionIntoWasmAbi for $t {
+ #[inline]
+ fn none() -> u32 { 0x00FF_FFFFu32 }
+ }
+
+ impl OptionFromWasmAbi for $t {
+ #[inline]
+ fn is_none(js: &u32) -> bool { *js == 0x00FF_FFFFu32 }
+ }
+ )*)
+}
+
+type_abi_as_u32!(i8 u8 i16 u16);
+
+impl IntoWasmAbi for bool {
+ type Abi = u32;
+
+ #[inline]
+ fn into_abi(self) -> u32 {
+ self as u32
+ }
+}
+
+impl FromWasmAbi for bool {
+ type Abi = u32;
+
+ #[inline]
+ unsafe fn from_abi(js: u32) -> bool {
+ js != 0
+ }
+}
+
+impl OptionIntoWasmAbi for bool {
+ #[inline]
+ fn none() -> u32 {
+ 0x00FF_FFFFu32
+ }
+}
+
+impl OptionFromWasmAbi for bool {
+ #[inline]
+ fn is_none(js: &u32) -> bool {
+ *js == 0x00FF_FFFFu32
+ }
+}
+
+impl IntoWasmAbi for char {
+ type Abi = u32;
+
+ #[inline]
+ fn into_abi(self) -> u32 {
+ self as u32
+ }
+}
+
+impl FromWasmAbi for char {
+ type Abi = u32;
+
+ #[inline]
+ unsafe fn from_abi(js: u32) -> char {
+ char::from_u32_unchecked(js)
+ }
+}
+
+impl OptionIntoWasmAbi for char {
+ #[inline]
+ fn none() -> u32 {
+ 0x00FF_FFFFu32
+ }
+}
+
+impl OptionFromWasmAbi for char {
+ #[inline]
+ fn is_none(js: &u32) -> bool {
+ *js == 0x00FF_FFFFu32
+ }
+}
+
+impl<T> IntoWasmAbi for *const T {
+ type Abi = u32;
+
+ #[inline]
+ fn into_abi(self) -> u32 {
+ self as u32
+ }
+}
+
+impl<T> FromWasmAbi for *const T {
+ type Abi = u32;
+
+ #[inline]
+ unsafe fn from_abi(js: u32) -> *const T {
+ js as *const T
+ }
+}
+
+impl<T> IntoWasmAbi for *mut T {
+ type Abi = u32;
+
+ #[inline]
+ fn into_abi(self) -> u32 {
+ self as u32
+ }
+}
+
+impl<T> FromWasmAbi for *mut T {
+ type Abi = u32;
+
+ #[inline]
+ unsafe fn from_abi(js: u32) -> *mut T {
+ js as *mut T
+ }
+}
+
+impl IntoWasmAbi for JsValue {
+ type Abi = u32;
+
+ #[inline]
+ fn into_abi(self) -> u32 {
+ let ret = self.idx;
+ mem::forget(self);
+ ret
+ }
+}
+
+impl FromWasmAbi for JsValue {
+ type Abi = u32;
+
+ #[inline]
+ unsafe fn from_abi(js: u32) -> JsValue {
+ JsValue::_new(js)
+ }
+}
+
+impl<'a> IntoWasmAbi for &'a JsValue {
+ type Abi = u32;
+
+ #[inline]
+ fn into_abi(self) -> u32 {
+ self.idx
+ }
+}
+
+impl RefFromWasmAbi for JsValue {
+ type Abi = u32;
+ type Anchor = ManuallyDrop<JsValue>;
+
+ #[inline]
+ unsafe fn ref_from_abi(js: u32) -> Self::Anchor {
+ ManuallyDrop::new(JsValue::_new(js))
+ }
+}
+
+impl<T: OptionIntoWasmAbi> IntoWasmAbi for Option<T> {
+ type Abi = T::Abi;
+
+ #[inline]
+ fn into_abi(self) -> T::Abi {
+ match self {
+ None => T::none(),
+ Some(me) => me.into_abi(),
+ }
+ }
+}
+
+impl<T: OptionFromWasmAbi> FromWasmAbi for Option<T> {
+ type Abi = T::Abi;
+
+ #[inline]
+ unsafe fn from_abi(js: T::Abi) -> Self {
+ if T::is_none(&js) {
+ None
+ } else {
+ Some(T::from_abi(js))
+ }
+ }
+}
+
+impl<T: IntoWasmAbi> IntoWasmAbi for Clamped<T> {
+ type Abi = T::Abi;
+
+ #[inline]
+ fn into_abi(self) -> Self::Abi {
+ self.0.into_abi()
+ }
+}
+
+impl<T: FromWasmAbi> FromWasmAbi for Clamped<T> {
+ type Abi = T::Abi;
+
+ #[inline]
+ unsafe fn from_abi(js: T::Abi) -> Self {
+ Clamped(T::from_abi(js))
+ }
+}
+
+impl IntoWasmAbi for () {
+ type Abi = ();
+
+ #[inline]
+ fn into_abi(self) {
+ self
+ }
+}
+
+/// This is an encoding of a Result. It can only store things that can be decoded by the JS
+/// bindings.
+///
+/// At the moment, we do not write the exact struct packing layout of everything into the
+/// glue/descriptions of datatypes, so T cannot be arbitrary. The current requirements of the
+/// struct unpacker (StructUnpacker), which apply to ResultAbi<T> as a whole, are as follows:
+///
+/// - repr(C), of course
+/// - u32/i32/f32/f64 fields at the "leaf fields" of the "field tree"
+/// - layout equivalent to a completely flattened repr(C) struct, constructed by an in order
+/// traversal of all the leaf fields in it.
+///
+/// This means that you can't embed struct A(u32, f64) as struct B(u32, A); because the "completely
+/// flattened" struct AB(u32, u32, f64) would miss the 4 byte padding that is actually present
+/// within B and then as a consequence also miss the 4 byte padding within A that repr(C) inserts.
+///
+/// The enemy is padding. Padding is only required when there is an `f64` field. So the enemy is
+/// `f64` after anything else, particularly anything arbitrary. There is no smaller sized type, so
+/// we don't need to worry about 1-byte integers, etc. It's best, therefore, to place your f64s
+/// first in your structs, that's why we have `abi` first, although here it doesn't matter as the
+/// other two fields total 8 bytes anyway.
+///
+#[repr(C)]
+pub struct ResultAbi<T> {
+ /// This field is the same size/align as `T`.
+ abi: ResultAbiUnion<T>,
+ /// Order of args here is such that we can pop() the possible error first, deal with it and
+ /// move on. Later fields are popped off the stack first.
+ err: u32,
+ is_err: u32,
+}
+
+#[repr(C)]
+pub union ResultAbiUnion<T> {
+ // ManuallyDrop is #[repr(transparent)]
+ ok: std::mem::ManuallyDrop<T>,
+ err: (),
+}
+
+unsafe impl<T: WasmAbi> WasmAbi for ResultAbi<T> {}
+unsafe impl<T: WasmAbi> WasmAbi for ResultAbiUnion<T> {}
+
+impl<T: IntoWasmAbi, E: Into<JsValue>> ReturnWasmAbi for Result<T, E> {
+ type Abi = ResultAbi<T::Abi>;
+ #[inline]
+ fn return_abi(self) -> Self::Abi {
+ match self {
+ Ok(v) => {
+ let abi = ResultAbiUnion {
+ ok: std::mem::ManuallyDrop::new(v.into_abi()),
+ };
+ ResultAbi {
+ abi,
+ is_err: 0,
+ err: 0,
+ }
+ }
+ Err(e) => {
+ let jsval = e.into();
+ ResultAbi {
+ abi: ResultAbiUnion { err: () },
+ is_err: 1,
+ err: jsval.into_abi(),
+ }
+ }
+ }
+ }
+}
+
+impl IntoWasmAbi for JsError {
+ type Abi = <JsValue as IntoWasmAbi>::Abi;
+
+ fn into_abi(self) -> Self::Abi {
+ self.value.into_abi()
+ }
+}
diff --git a/vendor/wasm-bindgen/src/convert/mod.rs b/vendor/wasm-bindgen/src/convert/mod.rs
new file mode 100644
index 000000000..ce2c0b2c8
--- /dev/null
+++ b/vendor/wasm-bindgen/src/convert/mod.rs
@@ -0,0 +1,11 @@
+//! This is mostly an internal module, no stability guarantees are provided. Use
+//! at your own risk.
+
+mod closures;
+mod impls;
+mod slices;
+mod traits;
+
+pub use self::impls::*;
+pub use self::slices::WasmSlice;
+pub use self::traits::*;
diff --git a/vendor/wasm-bindgen/src/convert/slices.rs b/vendor/wasm-bindgen/src/convert/slices.rs
new file mode 100644
index 000000000..9d0970f4e
--- /dev/null
+++ b/vendor/wasm-bindgen/src/convert/slices.rs
@@ -0,0 +1,311 @@
+#[cfg(feature = "std")]
+use std::prelude::v1::*;
+
+use core::slice;
+use core::str;
+
+use crate::cast::JsObject;
+use crate::convert::OptionIntoWasmAbi;
+use crate::convert::{FromWasmAbi, IntoWasmAbi, RefFromWasmAbi, RefMutFromWasmAbi, WasmAbi};
+use cfg_if::cfg_if;
+
+if_std! {
+ use core::mem;
+ use crate::convert::OptionFromWasmAbi;
+}
+
+#[repr(C)]
+pub struct WasmSlice {
+ pub ptr: u32,
+ pub len: u32,
+}
+
+unsafe impl WasmAbi for WasmSlice {}
+
+#[inline]
+fn null_slice() -> WasmSlice {
+ WasmSlice { ptr: 0, len: 0 }
+}
+
+macro_rules! vectors {
+ ($($t:ident)*) => ($(
+ if_std! {
+ impl IntoWasmAbi for Box<[$t]> {
+ type Abi = WasmSlice;
+
+ #[inline]
+ fn into_abi(self) -> WasmSlice {
+ let ptr = self.as_ptr();
+ let len = self.len();
+ mem::forget(self);
+ WasmSlice {
+ ptr: ptr.into_abi(),
+ len: len as u32,
+ }
+ }
+ }
+
+ impl OptionIntoWasmAbi for Box<[$t]> {
+ #[inline]
+ fn none() -> WasmSlice { null_slice() }
+ }
+
+ impl FromWasmAbi for Box<[$t]> {
+ type Abi = WasmSlice;
+
+ #[inline]
+ unsafe fn from_abi(js: WasmSlice) -> Self {
+ let ptr = <*mut $t>::from_abi(js.ptr);
+ let len = js.len as usize;
+ Vec::from_raw_parts(ptr, len, len).into_boxed_slice()
+ }
+ }
+
+ impl OptionFromWasmAbi for Box<[$t]> {
+ #[inline]
+ fn is_none(slice: &WasmSlice) -> bool { slice.ptr == 0 }
+ }
+ }
+
+ impl<'a> IntoWasmAbi for &'a [$t] {
+ type Abi = WasmSlice;
+
+ #[inline]
+ fn into_abi(self) -> WasmSlice {
+ WasmSlice {
+ ptr: self.as_ptr().into_abi(),
+ len: self.len() as u32,
+ }
+ }
+ }
+
+ impl<'a> OptionIntoWasmAbi for &'a [$t] {
+ #[inline]
+ fn none() -> WasmSlice { null_slice() }
+ }
+
+ impl<'a> IntoWasmAbi for &'a mut [$t] {
+ type Abi = WasmSlice;
+
+ #[inline]
+ fn into_abi(self) -> WasmSlice {
+ (&*self).into_abi()
+ }
+ }
+
+ impl<'a> OptionIntoWasmAbi for &'a mut [$t] {
+ #[inline]
+ fn none() -> WasmSlice { null_slice() }
+ }
+
+ impl RefFromWasmAbi for [$t] {
+ type Abi = WasmSlice;
+ type Anchor = Box<[$t]>;
+
+ #[inline]
+ unsafe fn ref_from_abi(js: WasmSlice) -> Box<[$t]> {
+ <Box<[$t]>>::from_abi(js)
+ }
+ }
+
+ impl RefMutFromWasmAbi for [$t] {
+ type Abi = WasmSlice;
+ type Anchor = &'static mut [$t];
+
+ #[inline]
+ unsafe fn ref_mut_from_abi(js: WasmSlice)
+ -> &'static mut [$t]
+ {
+ slice::from_raw_parts_mut(
+ <*mut $t>::from_abi(js.ptr),
+ js.len as usize,
+ )
+ }
+ }
+ )*)
+}
+
+vectors! {
+ u8 i8 u16 i16 u32 i32 u64 i64 usize isize f32 f64
+}
+
+cfg_if! {
+ if #[cfg(feature = "enable-interning")] {
+ #[inline]
+ fn unsafe_get_cached_str(x: &str) -> Option<WasmSlice> {
+ // This uses 0 for the ptr as an indication that it is a JsValue and not a str.
+ crate::cache::intern::unsafe_get_str(x).map(|x| WasmSlice { ptr: 0, len: x })
+ }
+
+ } else {
+ #[inline]
+ fn unsafe_get_cached_str(_x: &str) -> Option<WasmSlice> {
+ None
+ }
+ }
+}
+
+if_std! {
+ impl<T> IntoWasmAbi for Vec<T> where Box<[T]>: IntoWasmAbi<Abi = WasmSlice> {
+ type Abi = <Box<[T]> as IntoWasmAbi>::Abi;
+
+ #[inline]
+ fn into_abi(self) -> Self::Abi {
+ self.into_boxed_slice().into_abi()
+ }
+ }
+
+ impl<T> OptionIntoWasmAbi for Vec<T> where Box<[T]>: IntoWasmAbi<Abi = WasmSlice> {
+ #[inline]
+ fn none() -> WasmSlice { null_slice() }
+ }
+
+ impl<T> FromWasmAbi for Vec<T> where Box<[T]>: FromWasmAbi<Abi = WasmSlice> {
+ type Abi = <Box<[T]> as FromWasmAbi>::Abi;
+
+ #[inline]
+ unsafe fn from_abi(js: Self::Abi) -> Self {
+ <Box<[T]>>::from_abi(js).into()
+ }
+ }
+
+ impl<T> OptionFromWasmAbi for Vec<T> where Box<[T]>: FromWasmAbi<Abi = WasmSlice> {
+ #[inline]
+ fn is_none(abi: &WasmSlice) -> bool { abi.ptr == 0 }
+ }
+
+ impl IntoWasmAbi for String {
+ type Abi = <Vec<u8> as IntoWasmAbi>::Abi;
+
+ #[inline]
+ fn into_abi(self) -> Self::Abi {
+ // This is safe because the JsValue is immediately looked up in the heap and
+ // then returned, so use-after-free cannot occur.
+ unsafe_get_cached_str(&self).unwrap_or_else(|| self.into_bytes().into_abi())
+ }
+ }
+
+ impl OptionIntoWasmAbi for String {
+ #[inline]
+ fn none() -> Self::Abi { null_slice() }
+ }
+
+ impl FromWasmAbi for String {
+ type Abi = <Vec<u8> as FromWasmAbi>::Abi;
+
+ #[inline]
+ unsafe fn from_abi(js: Self::Abi) -> Self {
+ String::from_utf8_unchecked(<Vec<u8>>::from_abi(js))
+ }
+ }
+
+ impl OptionFromWasmAbi for String {
+ #[inline]
+ fn is_none(slice: &WasmSlice) -> bool { slice.ptr == 0 }
+ }
+}
+
+impl<'a> IntoWasmAbi for &'a str {
+ type Abi = <&'a [u8] as IntoWasmAbi>::Abi;
+
+ #[inline]
+ fn into_abi(self) -> Self::Abi {
+ // This is safe because the JsValue is immediately looked up in the heap and
+ // then returned, so use-after-free cannot occur.
+ unsafe_get_cached_str(self).unwrap_or_else(|| self.as_bytes().into_abi())
+ }
+}
+
+impl<'a> OptionIntoWasmAbi for &'a str {
+ #[inline]
+ fn none() -> Self::Abi {
+ null_slice()
+ }
+}
+
+impl RefFromWasmAbi for str {
+ type Abi = <[u8] as RefFromWasmAbi>::Abi;
+ type Anchor = Box<str>;
+
+ #[inline]
+ unsafe fn ref_from_abi(js: Self::Abi) -> Self::Anchor {
+ mem::transmute::<Box<[u8]>, Box<str>>(<Box<[u8]>>::from_abi(js))
+ }
+}
+
+if_std! {
+ use crate::JsValue;
+
+ impl IntoWasmAbi for Box<[JsValue]> {
+ type Abi = WasmSlice;
+
+ #[inline]
+ fn into_abi(self) -> WasmSlice {
+ let ptr = self.as_ptr();
+ let len = self.len();
+ mem::forget(self);
+ WasmSlice {
+ ptr: ptr.into_abi(),
+ len: len as u32,
+ }
+ }
+ }
+
+ impl OptionIntoWasmAbi for Box<[JsValue]> {
+ #[inline]
+ fn none() -> WasmSlice { null_slice() }
+ }
+
+ impl FromWasmAbi for Box<[JsValue]> {
+ type Abi = WasmSlice;
+
+ #[inline]
+ unsafe fn from_abi(js: WasmSlice) -> Self {
+ let ptr = <*mut JsValue>::from_abi(js.ptr);
+ let len = js.len as usize;
+ Vec::from_raw_parts(ptr, len, len).into_boxed_slice()
+ }
+ }
+
+ impl OptionFromWasmAbi for Box<[JsValue]> {
+ #[inline]
+ fn is_none(slice: &WasmSlice) -> bool { slice.ptr == 0 }
+ }
+
+ impl<T> IntoWasmAbi for Box<[T]> where T: JsObject {
+ type Abi = WasmSlice;
+
+ #[inline]
+ fn into_abi(self) -> WasmSlice {
+ let ptr = self.as_ptr();
+ let len = self.len();
+ mem::forget(self);
+ WasmSlice {
+ ptr: ptr.into_abi(),
+ len: len as u32,
+ }
+ }
+ }
+
+ impl<T> OptionIntoWasmAbi for Box<[T]> where T: JsObject {
+ #[inline]
+ fn none() -> WasmSlice { null_slice() }
+ }
+
+ impl<T> FromWasmAbi for Box<[T]> where T: JsObject {
+ type Abi = WasmSlice;
+
+ #[inline]
+ unsafe fn from_abi(js: WasmSlice) -> Self {
+ let ptr = <*mut JsValue>::from_abi(js.ptr);
+ let len = js.len as usize;
+ let vec: Vec<T> = Vec::from_raw_parts(ptr, len, len).drain(..).map(|js_value| T::unchecked_from_js(js_value)).collect();
+ return vec.into_boxed_slice();
+ }
+ }
+
+ impl<T> OptionFromWasmAbi for Box<[T]> where T: JsObject {
+ #[inline]
+ fn is_none(slice: &WasmSlice) -> bool { slice.ptr == 0 }
+ }
+}
diff --git a/vendor/wasm-bindgen/src/convert/traits.rs b/vendor/wasm-bindgen/src/convert/traits.rs
new file mode 100644
index 000000000..b9d12b4c8
--- /dev/null
+++ b/vendor/wasm-bindgen/src/convert/traits.rs
@@ -0,0 +1,131 @@
+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;
+}
+
+/// 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.
+///
+/// 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 interepret 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()
+ }
+}
diff --git a/vendor/wasm-bindgen/src/describe.rs b/vendor/wasm-bindgen/src/describe.rs
new file mode 100644
index 000000000..2b7c4b628
--- /dev/null
+++ b/vendor/wasm-bindgen/src/describe.rs
@@ -0,0 +1,192 @@
+//! This is an internal module, no stability guarantees are provided. Use at
+//! your own risk.
+
+#![doc(hidden)]
+
+use crate::{Clamped, JsError, JsValue};
+use cfg_if::cfg_if;
+
+macro_rules! tys {
+ ($($a:ident)*) => (tys! { @ ($($a)*) 0 });
+ (@ () $v:expr) => {};
+ (@ ($a:ident $($b:ident)*) $v:expr) => {
+ pub const $a: u32 = $v;
+ tys!(@ ($($b)*) $v+1);
+ }
+}
+
+// NB: this list must be kept in sync with `crates/cli-support/src/descriptor.rs`
+tys! {
+ I8
+ U8
+ I16
+ U16
+ I32
+ U32
+ I64
+ U64
+ F32
+ F64
+ BOOLEAN
+ FUNCTION
+ CLOSURE
+ CACHED_STRING
+ STRING
+ REF
+ REFMUT
+ SLICE
+ VECTOR
+ EXTERNREF
+ NAMED_EXTERNREF
+ ENUM
+ RUST_STRUCT
+ CHAR
+ OPTIONAL
+ RESULT
+ UNIT
+ CLAMPED
+}
+
+#[inline(always)] // see the wasm-interpreter crate
+pub fn inform(a: u32) {
+ unsafe { super::__wbindgen_describe(a) }
+}
+
+pub trait WasmDescribe {
+ fn describe();
+}
+
+macro_rules! simple {
+ ($($t:ident => $d:ident)*) => ($(
+ impl WasmDescribe for $t {
+ fn describe() { inform($d) }
+ }
+ )*)
+}
+
+simple! {
+ i8 => I8
+ u8 => U8
+ i16 => I16
+ u16 => U16
+ i32 => I32
+ u32 => U32
+ i64 => I64
+ u64 => U64
+ isize => I32
+ usize => U32
+ f32 => F32
+ f64 => F64
+ bool => BOOLEAN
+ char => CHAR
+ JsValue => EXTERNREF
+}
+
+cfg_if! {
+ if #[cfg(feature = "enable-interning")] {
+ simple! {
+ str => CACHED_STRING
+ }
+
+ } else {
+ simple! {
+ str => STRING
+ }
+ }
+}
+
+impl<T> WasmDescribe for *const T {
+ fn describe() {
+ inform(I32)
+ }
+}
+
+impl<T> WasmDescribe for *mut T {
+ fn describe() {
+ inform(I32)
+ }
+}
+
+impl<T: WasmDescribe> WasmDescribe for [T] {
+ fn describe() {
+ inform(SLICE);
+ T::describe();
+ }
+}
+
+impl<'a, T: WasmDescribe + ?Sized> WasmDescribe for &'a T {
+ fn describe() {
+ inform(REF);
+ T::describe();
+ }
+}
+
+impl<'a, T: WasmDescribe + ?Sized> WasmDescribe for &'a mut T {
+ fn describe() {
+ inform(REFMUT);
+ T::describe();
+ }
+}
+
+if_std! {
+ use std::prelude::v1::*;
+
+ cfg_if! {
+ if #[cfg(feature = "enable-interning")] {
+ simple! {
+ String => CACHED_STRING
+ }
+
+ } else {
+ simple! {
+ String => STRING
+ }
+ }
+ }
+
+ impl<T: WasmDescribe> WasmDescribe for Box<[T]> {
+ fn describe() {
+ inform(VECTOR);
+ T::describe();
+ }
+ }
+
+ impl<T> WasmDescribe for Vec<T> where Box<[T]>: WasmDescribe {
+ fn describe() {
+ <Box<[T]>>::describe();
+ }
+ }
+}
+
+impl<T: WasmDescribe> WasmDescribe for Option<T> {
+ fn describe() {
+ inform(OPTIONAL);
+ T::describe();
+ }
+}
+
+impl WasmDescribe for () {
+ fn describe() {
+ inform(UNIT)
+ }
+}
+
+impl<T: WasmDescribe, E: Into<JsValue>> WasmDescribe for Result<T, E> {
+ fn describe() {
+ inform(RESULT);
+ T::describe();
+ }
+}
+
+impl<T: WasmDescribe> WasmDescribe for Clamped<T> {
+ fn describe() {
+ inform(CLAMPED);
+ T::describe();
+ }
+}
+
+impl WasmDescribe for JsError {
+ fn describe() {
+ JsValue::describe();
+ }
+}
diff --git a/vendor/wasm-bindgen/src/externref.rs b/vendor/wasm-bindgen/src/externref.rs
new file mode 100644
index 000000000..a7e5f3ebc
--- /dev/null
+++ b/vendor/wasm-bindgen/src/externref.rs
@@ -0,0 +1,184 @@
+use crate::JsValue;
+use std::alloc::{self, Layout};
+use std::cell::Cell;
+use std::mem;
+use std::ptr;
+use std::slice;
+use std::vec::Vec;
+use std::cmp::max;
+
+externs! {
+ #[link(wasm_import_module = "__wbindgen_externref_xform__")]
+ extern "C" {
+ fn __wbindgen_externref_table_grow(delta: usize) -> i32;
+ fn __wbindgen_externref_table_set_null(idx: usize) -> ();
+ }
+}
+
+pub struct Slab {
+ data: Vec<usize>,
+ head: usize,
+ base: usize,
+}
+
+impl Slab {
+ fn new() -> Slab {
+ Slab {
+ data: Vec::new(),
+ head: 0,
+ base: 0,
+ }
+ }
+
+ fn alloc(&mut self) -> usize {
+ let ret = self.head;
+ if ret == self.data.len() {
+ let curr_len = self.data.len();
+ if curr_len == self.data.capacity() {
+ let extra = max(128, curr_len);
+ let r = unsafe { __wbindgen_externref_table_grow(extra) };
+ if r == -1 {
+ internal_error("table grow failure")
+ }
+ if self.base == 0 {
+ self.base = r as usize;
+ } else if self.base + self.data.len() != r as usize {
+ internal_error("someone else allocated table entires?")
+ }
+
+ // poor man's `try_reserve_exact` until that's stable
+ unsafe {
+ let new_cap = self.data.capacity() + extra;
+ let size = mem::size_of::<usize>() * new_cap;
+ let align = mem::align_of::<usize>();
+ let layout = match Layout::from_size_align(size, align) {
+ Ok(l) => l,
+ Err(_) => internal_error("size/align layout failure"),
+ };
+ let ptr = alloc::alloc(layout) as *mut usize;
+ if ptr.is_null() {
+ internal_error("allocation failure");
+ }
+ ptr::copy_nonoverlapping(self.data.as_ptr(), ptr, self.data.len());
+ let new_vec = Vec::from_raw_parts(ptr, self.data.len(), new_cap);
+ let mut old = mem::replace(&mut self.data, new_vec);
+ old.set_len(0);
+ }
+ }
+
+ // custom condition to ensure `push` below doesn't call `reserve` in
+ // optimized builds which pulls in lots of panic infrastructure
+ if self.data.len() >= self.data.capacity() {
+ internal_error("push should be infallible now")
+ }
+ self.data.push(ret + 1);
+ }
+
+ // usage of `get_mut` thwarts panicking infrastructure in optimized
+ // builds
+ match self.data.get_mut(ret) {
+ Some(slot) => self.head = *slot,
+ None => internal_error("ret out of bounds"),
+ }
+ ret + self.base
+ }
+
+ fn dealloc(&mut self, slot: usize) {
+ if slot < self.base {
+ internal_error("free reserved slot");
+ }
+ let slot = slot - self.base;
+
+ // usage of `get_mut` thwarts panicking infrastructure in optimized
+ // builds
+ match self.data.get_mut(slot) {
+ Some(ptr) => {
+ *ptr = self.head;
+ self.head = slot;
+ }
+ None => internal_error("slot out of bounds"),
+ }
+ }
+
+ fn live_count(&self) -> u32 {
+ let mut free_count = 0;
+ let mut next = self.head;
+ while next < self.data.len() {
+ debug_assert!((free_count as usize) < self.data.len());
+ free_count += 1;
+ match self.data.get(next) {
+ Some(n) => next = *n,
+ None => internal_error("slot out of bounds"),
+ };
+ }
+ self.data.len() as u32 - free_count
+ }
+}
+
+fn internal_error(msg: &str) -> ! {
+ if cfg!(debug_assertions) {
+ super::throw_str(msg)
+ } else {
+ std::process::abort()
+ }
+}
+
+// Management of `externref` is always thread local since an `externref` value
+// can't cross threads in wasm. Indices as a result are always thread-local.
+std::thread_local!(pub static HEAP_SLAB: Cell<Slab> = Cell::new(Slab::new()));
+
+#[no_mangle]
+pub extern "C" fn __externref_table_alloc() -> usize {
+ HEAP_SLAB
+ .try_with(|slot| {
+ let mut slab = slot.replace(Slab::new());
+ let ret = slab.alloc();
+ slot.replace(slab);
+ ret
+ })
+ .unwrap_or_else(|_| internal_error("tls access failure"))
+}
+
+#[no_mangle]
+pub extern "C" fn __externref_table_dealloc(idx: usize) {
+ if idx < super::JSIDX_RESERVED as usize {
+ return;
+ }
+ // clear this value from the table so while the table slot is un-allocated
+ // we don't keep around a strong reference to a potentially large object
+ unsafe {
+ __wbindgen_externref_table_set_null(idx);
+ }
+ HEAP_SLAB
+ .try_with(|slot| {
+ let mut slab = slot.replace(Slab::new());
+ slab.dealloc(idx);
+ slot.replace(slab);
+ })
+ .unwrap_or_else(|_| internal_error("tls access failure"))
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn __externref_drop_slice(ptr: *mut JsValue, len: usize) {
+ for slot in slice::from_raw_parts_mut(ptr, len) {
+ __externref_table_dealloc(slot.idx as usize);
+ }
+}
+
+// Implementation of `__wbindgen_externref_heap_live_count` for when we are using
+// `externref` instead of the JS `heap`.
+#[no_mangle]
+pub unsafe extern "C" fn __externref_heap_live_count() -> u32 {
+ HEAP_SLAB
+ .try_with(|slot| {
+ let slab = slot.replace(Slab::new());
+ let count = slab.live_count();
+ slot.replace(slab);
+ count
+ })
+ .unwrap_or_else(|_| internal_error("tls access failure"))
+}
+
+// see comment in module above this in `link_mem_intrinsics`
+#[inline(never)]
+pub fn link_intrinsics() {}
diff --git a/vendor/wasm-bindgen/src/lib.rs b/vendor/wasm-bindgen/src/lib.rs
new file mode 100644
index 000000000..2ccb284b9
--- /dev/null
+++ b/vendor/wasm-bindgen/src/lib.rs
@@ -0,0 +1,1800 @@
+//! Runtime support for the `wasm-bindgen` tool
+//!
+//! This crate contains the runtime support necessary for `wasm-bindgen` the
+//! attribute and tool. Crates pull in the `#[wasm_bindgen]` attribute through
+//! this crate and this crate also provides JS bindings through the `JsValue`
+//! interface.
+
+#![no_std]
+#![allow(coherence_leak_check)]
+#![doc(html_root_url = "https://docs.rs/wasm-bindgen/0.2")]
+
+use core::convert::TryFrom;
+use core::fmt;
+use core::marker;
+use core::mem;
+use core::ops::{
+ Add, BitAnd, BitOr, BitXor, Deref, DerefMut, Div, Mul, Neg, Not, Rem, Shl, Shr, Sub,
+};
+use core::u32;
+
+use crate::convert::{FromWasmAbi, WasmSlice};
+
+macro_rules! if_std {
+ ($($i:item)*) => ($(
+ #[cfg(feature = "std")] $i
+ )*)
+}
+
+macro_rules! externs {
+ ($(#[$attr:meta])* extern "C" { $(fn $name:ident($($args:tt)*) -> $ret:ty;)* }) => (
+ #[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))]
+ $(#[$attr])*
+ extern "C" {
+ $(fn $name($($args)*) -> $ret;)*
+ }
+
+ $(
+ #[cfg(not(all(target_arch = "wasm32", not(target_os = "emscripten"))))]
+ #[allow(unused_variables)]
+ unsafe extern fn $name($($args)*) -> $ret {
+ panic!("function not implemented on non-wasm32 targets")
+ }
+ )*
+ )
+}
+
+/// A module which is typically glob imported from:
+///
+/// ```
+/// use wasm_bindgen::prelude::*;
+/// ```
+pub mod prelude {
+ pub use crate::JsValue;
+ pub use crate::UnwrapThrowExt;
+ #[doc(hidden)]
+ pub use wasm_bindgen_macro::__wasm_bindgen_class_marker;
+ pub use wasm_bindgen_macro::wasm_bindgen;
+
+ if_std! {
+ pub use crate::closure::Closure;
+ }
+
+ pub use crate::JsError;
+}
+
+pub mod convert;
+pub mod describe;
+
+mod cast;
+pub use crate::cast::{JsCast, JsObject};
+use convert::WasmOption;
+
+if_std! {
+ extern crate std;
+ use std::prelude::v1::*;
+ pub mod closure;
+ mod externref;
+
+ mod cache;
+ pub use cache::intern::{intern, unintern};
+}
+
+/// Representation of an object owned by JS.
+///
+/// A `JsValue` doesn't actually live in Rust right now but actually in a table
+/// owned by the `wasm-bindgen` generated JS glue code. Eventually the ownership
+/// will transfer into wasm directly and this will likely become more efficient,
+/// but for now it may be slightly slow.
+pub struct JsValue {
+ idx: u32,
+ _marker: marker::PhantomData<*mut u8>, // not at all threadsafe
+}
+
+const JSIDX_OFFSET: u32 = 32; // keep in sync with js/mod.rs
+const JSIDX_UNDEFINED: u32 = JSIDX_OFFSET + 0;
+const JSIDX_NULL: u32 = JSIDX_OFFSET + 1;
+const JSIDX_TRUE: u32 = JSIDX_OFFSET + 2;
+const JSIDX_FALSE: u32 = JSIDX_OFFSET + 3;
+const JSIDX_RESERVED: u32 = JSIDX_OFFSET + 4;
+
+impl JsValue {
+ /// The `null` JS value constant.
+ pub const NULL: JsValue = JsValue {
+ idx: JSIDX_NULL,
+ _marker: marker::PhantomData,
+ };
+
+ /// The `undefined` JS value constant.
+ pub const UNDEFINED: JsValue = JsValue {
+ idx: JSIDX_UNDEFINED,
+ _marker: marker::PhantomData,
+ };
+
+ /// The `true` JS value constant.
+ pub const TRUE: JsValue = JsValue {
+ idx: JSIDX_TRUE,
+ _marker: marker::PhantomData,
+ };
+
+ /// The `false` JS value constant.
+ pub const FALSE: JsValue = JsValue {
+ idx: JSIDX_FALSE,
+ _marker: marker::PhantomData,
+ };
+
+ #[inline]
+ fn _new(idx: u32) -> JsValue {
+ JsValue {
+ idx,
+ _marker: marker::PhantomData,
+ }
+ }
+
+ /// Creates a new JS value which is a string.
+ ///
+ /// The utf-8 string provided is copied to the JS heap and the string will
+ /// be owned by the JS garbage collector.
+ #[inline]
+ pub fn from_str(s: &str) -> JsValue {
+ unsafe { JsValue::_new(__wbindgen_string_new(s.as_ptr(), s.len())) }
+ }
+
+ /// Creates a new JS value which is a number.
+ ///
+ /// This function creates a JS value representing a number (a heap
+ /// allocated number) and returns a handle to the JS version of it.
+ #[inline]
+ pub fn from_f64(n: f64) -> JsValue {
+ unsafe { JsValue::_new(__wbindgen_number_new(n)) }
+ }
+
+ /// Creates a new JS value which is a bigint from a string representing a number.
+ ///
+ /// This function creates a JS value representing a bigint (a heap
+ /// allocated large integer) and returns a handle to the JS version of it.
+ #[inline]
+ pub fn bigint_from_str(s: &str) -> JsValue {
+ unsafe { JsValue::_new(__wbindgen_bigint_from_str(s.as_ptr(), s.len())) }
+ }
+
+ /// Creates a new JS value which is a boolean.
+ ///
+ /// This function creates a JS object representing a boolean (a heap
+ /// allocated boolean) and returns a handle to the JS version of it.
+ #[inline]
+ pub fn from_bool(b: bool) -> JsValue {
+ if b {
+ JsValue::TRUE
+ } else {
+ JsValue::FALSE
+ }
+ }
+
+ /// Creates a new JS value representing `undefined`.
+ #[inline]
+ pub fn undefined() -> JsValue {
+ JsValue::UNDEFINED
+ }
+
+ /// Creates a new JS value representing `null`.
+ #[inline]
+ pub fn null() -> JsValue {
+ JsValue::NULL
+ }
+
+ /// Creates a new JS symbol with the optional description specified.
+ ///
+ /// This function will invoke the `Symbol` constructor in JS and return the
+ /// JS object corresponding to the symbol created.
+ pub fn symbol(description: Option<&str>) -> JsValue {
+ unsafe {
+ match description {
+ Some(description) => JsValue::_new(__wbindgen_symbol_named_new(
+ description.as_ptr(),
+ description.len(),
+ )),
+ None => JsValue::_new(__wbindgen_symbol_anonymous_new()),
+ }
+ }
+ }
+
+ /// Creates a new `JsValue` from the JSON serialization of the object `t`
+ /// provided.
+ ///
+ /// **This function is deprecated**, due to [creating a dependency cycle in
+ /// some circumstances][dep-cycle-issue]. Use [`serde-wasm-bindgen`] or
+ /// [`gloo_utils::format::JsValueSerdeExt`] instead.
+ ///
+ /// [dep-cycle-issue]: https://github.com/rustwasm/wasm-bindgen/issues/2770
+ /// [`serde-wasm-bindgen`]: https://docs.rs/serde-wasm-bindgen
+ /// [`gloo_utils::format::JsValueSerdeExt`]: https://docs.rs/gloo-utils/latest/gloo_utils/format/trait.JsValueSerdeExt.html
+ ///
+ /// This function will serialize the provided value `t` to a JSON string,
+ /// send the JSON string to JS, parse it into a JS object, and then return
+ /// a handle to the JS object. This is unlikely to be super speedy so it's
+ /// not recommended for large payloads, but it's a nice to have in some
+ /// situations!
+ ///
+ /// Usage of this API requires activating the `serde-serialize` feature of
+ /// the `wasm-bindgen` crate.
+ ///
+ /// # Errors
+ ///
+ /// Returns any error encountered when serializing `T` into JSON.
+ #[cfg(feature = "serde-serialize")]
+ #[deprecated = "causes dependency cycles, use `serde-wasm-bindgen` or `gloo_utils::format::JsValueSerdeExt` instead"]
+ pub fn from_serde<T>(t: &T) -> serde_json::Result<JsValue>
+ where
+ T: serde::ser::Serialize + ?Sized,
+ {
+ let s = serde_json::to_string(t)?;
+ unsafe { Ok(JsValue::_new(__wbindgen_json_parse(s.as_ptr(), s.len()))) }
+ }
+
+ /// Invokes `JSON.stringify` on this value and then parses the resulting
+ /// JSON into an arbitrary Rust value.
+ ///
+ /// **This function is deprecated**, due to [creating a dependency cycle in
+ /// some circumstances][dep-cycle-issue]. Use [`serde-wasm-bindgen`] or
+ /// [`gloo_utils::format::JsValueSerdeExt`] instead.
+ ///
+ /// [dep-cycle-issue]: https://github.com/rustwasm/wasm-bindgen/issues/2770
+ /// [`serde-wasm-bindgen`]: https://docs.rs/serde-wasm-bindgen
+ /// [`gloo_utils::format::JsValueSerdeExt`]: https://docs.rs/gloo-utils/latest/gloo_utils/format/trait.JsValueSerdeExt.html
+ ///
+ /// This function will first call `JSON.stringify` on the `JsValue` itself.
+ /// The resulting string is then passed into Rust which then parses it as
+ /// JSON into the resulting value.
+ ///
+ /// Usage of this API requires activating the `serde-serialize` feature of
+ /// the `wasm-bindgen` crate.
+ ///
+ /// # Errors
+ ///
+ /// Returns any error encountered when parsing the JSON into a `T`.
+ #[cfg(feature = "serde-serialize")]
+ #[deprecated = "causes dependency cycles, use `serde-wasm-bindgen` or `gloo_utils::format::JsValueSerdeExt` instead"]
+ pub fn into_serde<T>(&self) -> serde_json::Result<T>
+ where
+ T: for<'a> serde::de::Deserialize<'a>,
+ {
+ unsafe {
+ let ret = __wbindgen_json_serialize(self.idx);
+ let s = String::from_abi(ret);
+ serde_json::from_str(&s)
+ }
+ }
+
+ /// Returns the `f64` value of this JS value if it's an instance of a
+ /// number.
+ ///
+ /// If this JS value is not an instance of a number then this returns
+ /// `None`.
+ #[inline]
+ pub fn as_f64(&self) -> Option<f64> {
+ unsafe { FromWasmAbi::from_abi(__wbindgen_number_get(self.idx)) }
+ }
+
+ /// Tests whether this JS value is a JS string.
+ #[inline]
+ pub fn is_string(&self) -> bool {
+ unsafe { __wbindgen_is_string(self.idx) == 1 }
+ }
+
+ /// If this JS value is a string value, this function copies the JS string
+ /// value into wasm linear memory, encoded as UTF-8, and returns it as a
+ /// Rust `String`.
+ ///
+ /// To avoid the copying and re-encoding, consider the
+ /// `JsString::try_from()` function from [js-sys](https://docs.rs/js-sys)
+ /// instead.
+ ///
+ /// If this JS value is not an instance of a string or if it's not valid
+ /// utf-8 then this returns `None`.
+ ///
+ /// # UTF-16 vs UTF-8
+ ///
+ /// JavaScript strings in general are encoded as UTF-16, but Rust strings
+ /// are encoded as UTF-8. This can cause the Rust string to look a bit
+ /// different than the JS string sometimes. For more details see the
+ /// [documentation about the `str` type][caveats] which contains a few
+ /// caveats about the encodings.
+ ///
+ /// [caveats]: https://rustwasm.github.io/docs/wasm-bindgen/reference/types/str.html
+ #[cfg(feature = "std")]
+ #[inline]
+ pub fn as_string(&self) -> Option<String> {
+ unsafe { FromWasmAbi::from_abi(__wbindgen_string_get(self.idx)) }
+ }
+
+ /// Returns the `bool` value of this JS value if it's an instance of a
+ /// boolean.
+ ///
+ /// If this JS value is not an instance of a boolean then this returns
+ /// `None`.
+ #[inline]
+ pub fn as_bool(&self) -> Option<bool> {
+ unsafe {
+ match __wbindgen_boolean_get(self.idx) {
+ 0 => Some(false),
+ 1 => Some(true),
+ _ => None,
+ }
+ }
+ }
+
+ /// Tests whether this JS value is `null`
+ #[inline]
+ pub fn is_null(&self) -> bool {
+ unsafe { __wbindgen_is_null(self.idx) == 1 }
+ }
+
+ /// Tests whether this JS value is `undefined`
+ #[inline]
+ pub fn is_undefined(&self) -> bool {
+ unsafe { __wbindgen_is_undefined(self.idx) == 1 }
+ }
+
+ /// Tests whether the type of this JS value is `symbol`
+ #[inline]
+ pub fn is_symbol(&self) -> bool {
+ unsafe { __wbindgen_is_symbol(self.idx) == 1 }
+ }
+
+ /// Tests whether `typeof self == "object" && self !== null`.
+ #[inline]
+ pub fn is_object(&self) -> bool {
+ unsafe { __wbindgen_is_object(self.idx) == 1 }
+ }
+
+ /// Tests whether the type of this JS value is `function`.
+ #[inline]
+ pub fn is_function(&self) -> bool {
+ unsafe { __wbindgen_is_function(self.idx) == 1 }
+ }
+
+ /// Tests whether the type of this JS value is `bigint`.
+ #[inline]
+ pub fn is_bigint(&self) -> bool {
+ unsafe { __wbindgen_is_bigint(self.idx) == 1 }
+ }
+
+ /// Applies the unary `typeof` JS operator on a `JsValue`.
+ ///
+ /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof)
+ #[inline]
+ pub fn js_typeof(&self) -> JsValue {
+ unsafe { JsValue::_new(__wbindgen_typeof(self.idx)) }
+ }
+
+ /// Applies the binary `in` JS operator on the two `JsValue`s.
+ ///
+ /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/in)
+ #[inline]
+ pub fn js_in(&self, obj: &JsValue) -> bool {
+ unsafe { __wbindgen_in(self.idx, obj.idx) == 1 }
+ }
+
+ /// Tests whether the value is ["truthy"].
+ ///
+ /// ["truthy"]: https://developer.mozilla.org/en-US/docs/Glossary/Truthy
+ #[inline]
+ pub fn is_truthy(&self) -> bool {
+ !self.is_falsy()
+ }
+
+ /// Tests whether the value is ["falsy"].
+ ///
+ /// ["falsy"]: https://developer.mozilla.org/en-US/docs/Glossary/Falsy
+ #[inline]
+ pub fn is_falsy(&self) -> bool {
+ unsafe { __wbindgen_is_falsy(self.idx) == 1 }
+ }
+
+ /// Get a string representation of the JavaScript object for debugging.
+ #[cfg(feature = "std")]
+ fn as_debug_string(&self) -> String {
+ unsafe {
+ let mut ret = [0; 2];
+ __wbindgen_debug_string(&mut ret, self.idx);
+ let data = Vec::from_raw_parts(ret[0] as *mut u8, ret[1], ret[1]);
+ String::from_utf8_unchecked(data)
+ }
+ }
+
+ /// Compare two `JsValue`s for equality, using the `==` operator in JS.
+ ///
+ /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Equality)
+ #[inline]
+ pub fn loose_eq(&self, other: &Self) -> bool {
+ unsafe { __wbindgen_jsval_loose_eq(self.idx, other.idx) != 0 }
+ }
+
+ /// Applies the unary `~` JS operator on a `JsValue`.
+ ///
+ /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_NOT)
+ #[inline]
+ pub fn bit_not(&self) -> JsValue {
+ unsafe { JsValue::_new(__wbindgen_bit_not(self.idx)) }
+ }
+
+ /// Applies the binary `>>>` JS operator on the two `JsValue`s.
+ ///
+ /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Unsigned_right_shift)
+ #[inline]
+ pub fn unsigned_shr(&self, rhs: &Self) -> u32 {
+ unsafe { __wbindgen_unsigned_shr(self.idx, rhs.idx) }
+ }
+
+ /// Applies the binary `/` JS operator on two `JsValue`s, catching and returning any `RangeError` thrown.
+ ///
+ /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Division)
+ #[inline]
+ pub fn checked_div(&self, rhs: &Self) -> Self {
+ unsafe { JsValue::_new(__wbindgen_checked_div(self.idx, rhs.idx)) }
+ }
+
+ /// Applies the binary `**` JS operator on the two `JsValue`s.
+ ///
+ /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Exponentiation)
+ #[inline]
+ pub fn pow(&self, rhs: &Self) -> Self {
+ unsafe { JsValue::_new(__wbindgen_pow(self.idx, rhs.idx)) }
+ }
+
+ /// Applies the binary `<` JS operator on the two `JsValue`s.
+ ///
+ /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Less_than)
+ #[inline]
+ pub fn lt(&self, other: &Self) -> bool {
+ unsafe { __wbindgen_lt(self.idx, other.idx) == 1 }
+ }
+
+ /// Applies the binary `<=` JS operator on the two `JsValue`s.
+ ///
+ /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Less_than_or_equal)
+ #[inline]
+ pub fn le(&self, other: &Self) -> bool {
+ unsafe { __wbindgen_le(self.idx, other.idx) == 1 }
+ }
+
+ /// Applies the binary `>=` JS operator on the two `JsValue`s.
+ ///
+ /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Greater_than_or_equal)
+ #[inline]
+ pub fn ge(&self, other: &Self) -> bool {
+ unsafe { __wbindgen_ge(self.idx, other.idx) == 1 }
+ }
+
+ /// Applies the binary `>` JS operator on the two `JsValue`s.
+ ///
+ /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Greater_than)
+ #[inline]
+ pub fn gt(&self, other: &Self) -> bool {
+ unsafe { __wbindgen_gt(self.idx, other.idx) == 1 }
+ }
+
+ /// Applies the unary `+` JS operator on a `JsValue`. Can throw.
+ ///
+ /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Unary_plus)
+ #[inline]
+ pub fn unchecked_into_f64(&self) -> f64 {
+ unsafe { __wbindgen_as_number(self.idx) }
+ }
+}
+
+impl PartialEq for JsValue {
+ /// Compares two `JsValue`s for equality, using the `===` operator in JS.
+ ///
+ /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Strict_equality)
+ #[inline]
+ fn eq(&self, other: &Self) -> bool {
+ unsafe { __wbindgen_jsval_eq(self.idx, other.idx) != 0 }
+ }
+}
+
+impl PartialEq<bool> for JsValue {
+ #[inline]
+ fn eq(&self, other: &bool) -> bool {
+ self.as_bool() == Some(*other)
+ }
+}
+
+impl PartialEq<str> for JsValue {
+ #[inline]
+ fn eq(&self, other: &str) -> bool {
+ *self == JsValue::from_str(other)
+ }
+}
+
+impl<'a> PartialEq<&'a str> for JsValue {
+ #[inline]
+ fn eq(&self, other: &&'a str) -> bool {
+ <JsValue as PartialEq<str>>::eq(self, other)
+ }
+}
+
+if_std! {
+ impl PartialEq<String> for JsValue {
+ #[inline]
+ fn eq(&self, other: &String) -> bool {
+ <JsValue as PartialEq<str>>::eq(self, other)
+ }
+ }
+ impl<'a> PartialEq<&'a String> for JsValue {
+ #[inline]
+ fn eq(&self, other: &&'a String) -> bool {
+ <JsValue as PartialEq<str>>::eq(self, other)
+ }
+ }
+}
+
+macro_rules! forward_deref_unop {
+ (impl $imp:ident, $method:ident for $t:ty) => {
+ impl $imp for $t {
+ type Output = <&'static $t as $imp>::Output;
+
+ #[inline]
+ fn $method(self) -> <&'static $t as $imp>::Output {
+ $imp::$method(&self)
+ }
+ }
+ };
+}
+
+macro_rules! forward_deref_binop {
+ (impl $imp:ident, $method:ident for $t:ty) => {
+ impl<'a> $imp<$t> for &'a $t {
+ type Output = <&'static $t as $imp<&'static $t>>::Output;
+
+ #[inline]
+ fn $method(self, other: $t) -> <&'static $t as $imp<&'static $t>>::Output {
+ $imp::$method(self, &other)
+ }
+ }
+
+ impl $imp<&$t> for $t {
+ type Output = <&'static $t as $imp<&'static $t>>::Output;
+
+ #[inline]
+ fn $method(self, other: &$t) -> <&'static $t as $imp<&'static $t>>::Output {
+ $imp::$method(&self, other)
+ }
+ }
+
+ impl $imp<$t> for $t {
+ type Output = <&'static $t as $imp<&'static $t>>::Output;
+
+ #[inline]
+ fn $method(self, other: $t) -> <&'static $t as $imp<&'static $t>>::Output {
+ $imp::$method(&self, &other)
+ }
+ }
+ };
+}
+
+impl Not for &JsValue {
+ type Output = bool;
+
+ /// Applies the `!` JS operator on a `JsValue`.
+ ///
+ /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_NOT)
+ #[inline]
+ fn not(self) -> Self::Output {
+ JsValue::is_falsy(self)
+ }
+}
+
+forward_deref_unop!(impl Not, not for JsValue);
+
+impl TryFrom<JsValue> for f64 {
+ type Error = JsValue;
+
+ /// Applies the unary `+` JS operator on a `JsValue`.
+ /// Returns the numeric result on success, or the JS error value on error.
+ ///
+ /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Unary_plus)
+ #[inline]
+ fn try_from(val: JsValue) -> Result<Self, Self::Error> {
+ f64::try_from(&val)
+ }
+}
+
+impl TryFrom<&JsValue> for f64 {
+ type Error = JsValue;
+
+ /// Applies the unary `+` JS operator on a `JsValue`.
+ /// Returns the numeric result on success, or the JS error value on error.
+ ///
+ /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Unary_plus)
+ #[inline]
+ fn try_from(val: &JsValue) -> Result<Self, Self::Error> {
+ let jsval = unsafe { JsValue::_new(__wbindgen_try_into_number(val.idx)) };
+ return match jsval.as_f64() {
+ Some(num) => Ok(num),
+ None => Err(jsval),
+ };
+ }
+}
+
+impl Neg for &JsValue {
+ type Output = JsValue;
+
+ /// Applies the unary `-` JS operator on a `JsValue`.
+ ///
+ /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Unary_negation)
+ #[inline]
+ fn neg(self) -> Self::Output {
+ unsafe { JsValue::_new(__wbindgen_neg(self.idx)) }
+ }
+}
+
+forward_deref_unop!(impl Neg, neg for JsValue);
+
+impl BitAnd for &JsValue {
+ type Output = JsValue;
+
+ /// Applies the binary `&` JS operator on two `JsValue`s.
+ ///
+ /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_AND)
+ #[inline]
+ fn bitand(self, rhs: Self) -> Self::Output {
+ unsafe { JsValue::_new(__wbindgen_bit_and(self.idx, rhs.idx)) }
+ }
+}
+
+forward_deref_binop!(impl BitAnd, bitand for JsValue);
+
+impl BitOr for &JsValue {
+ type Output = JsValue;
+
+ /// Applies the binary `|` JS operator on two `JsValue`s.
+ ///
+ /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_OR)
+ #[inline]
+ fn bitor(self, rhs: Self) -> Self::Output {
+ unsafe { JsValue::_new(__wbindgen_bit_or(self.idx, rhs.idx)) }
+ }
+}
+
+forward_deref_binop!(impl BitOr, bitor for JsValue);
+
+impl BitXor for &JsValue {
+ type Output = JsValue;
+
+ /// Applies the binary `^` JS operator on two `JsValue`s.
+ ///
+ /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_XOR)
+ #[inline]
+ fn bitxor(self, rhs: Self) -> Self::Output {
+ unsafe { JsValue::_new(__wbindgen_bit_xor(self.idx, rhs.idx)) }
+ }
+}
+
+forward_deref_binop!(impl BitXor, bitxor for JsValue);
+
+impl Shl for &JsValue {
+ type Output = JsValue;
+
+ /// Applies the binary `<<` JS operator on two `JsValue`s.
+ ///
+ /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Left_shift)
+ #[inline]
+ fn shl(self, rhs: Self) -> Self::Output {
+ unsafe { JsValue::_new(__wbindgen_shl(self.idx, rhs.idx)) }
+ }
+}
+
+forward_deref_binop!(impl Shl, shl for JsValue);
+
+impl Shr for &JsValue {
+ type Output = JsValue;
+
+ /// Applies the binary `>>` JS operator on two `JsValue`s.
+ ///
+ /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Right_shift)
+ #[inline]
+ fn shr(self, rhs: Self) -> Self::Output {
+ unsafe { JsValue::_new(__wbindgen_shr(self.idx, rhs.idx)) }
+ }
+}
+
+forward_deref_binop!(impl Shr, shr for JsValue);
+
+impl Add for &JsValue {
+ type Output = JsValue;
+
+ /// Applies the binary `+` JS operator on two `JsValue`s.
+ ///
+ /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Addition)
+ #[inline]
+ fn add(self, rhs: Self) -> Self::Output {
+ unsafe { JsValue::_new(__wbindgen_add(self.idx, rhs.idx)) }
+ }
+}
+
+forward_deref_binop!(impl Add, add for JsValue);
+
+impl Sub for &JsValue {
+ type Output = JsValue;
+
+ /// Applies the binary `-` JS operator on two `JsValue`s.
+ ///
+ /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Subtraction)
+ #[inline]
+ fn sub(self, rhs: Self) -> Self::Output {
+ unsafe { JsValue::_new(__wbindgen_sub(self.idx, rhs.idx)) }
+ }
+}
+
+forward_deref_binop!(impl Sub, sub for JsValue);
+
+impl Div for &JsValue {
+ type Output = JsValue;
+
+ /// Applies the binary `/` JS operator on two `JsValue`s.
+ ///
+ /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Division)
+ #[inline]
+ fn div(self, rhs: Self) -> Self::Output {
+ unsafe { JsValue::_new(__wbindgen_div(self.idx, rhs.idx)) }
+ }
+}
+
+forward_deref_binop!(impl Div, div for JsValue);
+
+impl Mul for &JsValue {
+ type Output = JsValue;
+
+ /// Applies the binary `*` JS operator on two `JsValue`s.
+ ///
+ /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Multiplication)
+ #[inline]
+ fn mul(self, rhs: Self) -> Self::Output {
+ unsafe { JsValue::_new(__wbindgen_mul(self.idx, rhs.idx)) }
+ }
+}
+
+forward_deref_binop!(impl Mul, mul for JsValue);
+
+impl Rem for &JsValue {
+ type Output = JsValue;
+
+ /// Applies the binary `%` JS operator on two `JsValue`s.
+ ///
+ /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Remainder)
+ #[inline]
+ fn rem(self, rhs: Self) -> Self::Output {
+ unsafe { JsValue::_new(__wbindgen_rem(self.idx, rhs.idx)) }
+ }
+}
+
+forward_deref_binop!(impl Rem, rem for JsValue);
+
+impl<'a> From<&'a str> for JsValue {
+ #[inline]
+ fn from(s: &'a str) -> JsValue {
+ JsValue::from_str(s)
+ }
+}
+
+if_std! {
+ impl<'a> From<&'a String> for JsValue {
+ #[inline]
+ fn from(s: &'a String) -> JsValue {
+ JsValue::from_str(s)
+ }
+ }
+
+ impl From<String> for JsValue {
+ #[inline]
+ fn from(s: String) -> JsValue {
+ JsValue::from_str(&s)
+ }
+ }
+}
+
+impl From<bool> for JsValue {
+ #[inline]
+ fn from(s: bool) -> JsValue {
+ JsValue::from_bool(s)
+ }
+}
+
+impl<'a, T> From<&'a T> for JsValue
+where
+ T: JsCast,
+{
+ #[inline]
+ fn from(s: &'a T) -> JsValue {
+ s.as_ref().clone()
+ }
+}
+
+impl<T> From<Option<T>> for JsValue
+where
+ JsValue: From<T>,
+{
+ #[inline]
+ fn from(s: Option<T>) -> JsValue {
+ match s {
+ Some(s) => s.into(),
+ None => JsValue::undefined(),
+ }
+ }
+}
+
+impl JsCast for JsValue {
+ // everything is a `JsValue`!
+ #[inline]
+ fn instanceof(_val: &JsValue) -> bool {
+ true
+ }
+ #[inline]
+ fn unchecked_from_js(val: JsValue) -> Self {
+ val
+ }
+ #[inline]
+ fn unchecked_from_js_ref(val: &JsValue) -> &Self {
+ val
+ }
+}
+
+impl AsRef<JsValue> for JsValue {
+ #[inline]
+ fn as_ref(&self) -> &JsValue {
+ self
+ }
+}
+
+macro_rules! numbers {
+ ($($n:ident)*) => ($(
+ impl PartialEq<$n> for JsValue {
+ #[inline]
+ fn eq(&self, other: &$n) -> bool {
+ self.as_f64() == Some(f64::from(*other))
+ }
+ }
+
+ impl From<$n> for JsValue {
+ #[inline]
+ fn from(n: $n) -> JsValue {
+ JsValue::from_f64(n.into())
+ }
+ }
+ )*)
+}
+
+numbers! { i8 u8 i16 u16 i32 u32 f32 f64 }
+
+macro_rules! big_numbers {
+ (|$arg:ident|, $($n:ident = $handle:expr,)*) => ($(
+ impl PartialEq<$n> for JsValue {
+ #[inline]
+ fn eq(&self, other: &$n) -> bool {
+ self == &JsValue::from(*other)
+ }
+ }
+
+ impl From<$n> for JsValue {
+ #[inline]
+ fn from($arg: $n) -> JsValue {
+ unsafe { JsValue::_new($handle) }
+ }
+ }
+ )*)
+}
+
+fn bigint_get_as_i64(v: &JsValue) -> Option<i64> {
+ unsafe { Option::from_abi(__wbindgen_bigint_get_as_i64(v.idx)) }
+}
+
+macro_rules! try_from_for_num64 {
+ ($ty:ty) => {
+ impl TryFrom<JsValue> for $ty {
+ type Error = JsValue;
+
+ #[inline]
+ fn try_from(v: JsValue) -> Result<Self, JsValue> {
+ bigint_get_as_i64(&v)
+ // Reinterpret bits; ABI-wise this is safe to do and allows us to avoid
+ // having separate intrinsics per signed/unsigned types.
+ .map(|as_i64| as_i64 as Self)
+ // Double-check that we didn't truncate the bigint to 64 bits.
+ .filter(|as_self| v == *as_self)
+ // Not a bigint or not in range.
+ .ok_or(v)
+ }
+ }
+ };
+}
+
+try_from_for_num64!(i64);
+try_from_for_num64!(u64);
+
+macro_rules! try_from_for_num128 {
+ ($ty:ty, $hi_ty:ty) => {
+ impl TryFrom<JsValue> for $ty {
+ type Error = JsValue;
+
+ #[inline]
+ fn try_from(v: JsValue) -> Result<Self, JsValue> {
+ // Truncate the bigint to 64 bits, this will give us the lower part.
+ let lo = match bigint_get_as_i64(&v) {
+ // The lower part must be interpreted as unsigned in both i128 and u128.
+ Some(lo) => lo as u64,
+ // Not a bigint.
+ None => return Err(v),
+ };
+ // Now we know it's a bigint, so we can safely use `>> 64n` without
+ // worrying about a JS exception on type mismatch.
+ let hi = v >> JsValue::from(64_u64);
+ // The high part is the one we want checked against a 64-bit range.
+ // If it fits, then our original number is in the 128-bit range.
+ let hi = <$hi_ty>::try_from(hi)?;
+ Ok(Self::from(hi) << 64 | Self::from(lo))
+ }
+ }
+ };
+}
+
+try_from_for_num128!(i128, i64);
+try_from_for_num128!(u128, u64);
+
+big_numbers! {
+ |n|,
+ i64 = __wbindgen_bigint_from_i64(n),
+ u64 = __wbindgen_bigint_from_u64(n),
+ i128 = __wbindgen_bigint_from_i128((n >> 64) as i64, n as u64),
+ u128 = __wbindgen_bigint_from_u128((n >> 64) as u64, n as u64),
+}
+
+// `usize` and `isize` have to be treated a bit specially, because we know that
+// they're 32-bit but the compiler conservatively assumes they might be bigger.
+// So, we have to manually forward to the `u32`/`i32` versions.
+impl PartialEq<usize> for JsValue {
+ #[inline]
+ fn eq(&self, other: &usize) -> bool {
+ *self == (*other as u32)
+ }
+}
+
+impl From<usize> for JsValue {
+ #[inline]
+ fn from(n: usize) -> Self {
+ Self::from(n as u32)
+ }
+}
+
+impl PartialEq<isize> for JsValue {
+ #[inline]
+ fn eq(&self, other: &isize) -> bool {
+ *self == (*other as i32)
+ }
+}
+
+impl From<isize> for JsValue {
+ #[inline]
+ fn from(n: isize) -> Self {
+ Self::from(n as i32)
+ }
+}
+
+externs! {
+ #[link(wasm_import_module = "__wbindgen_placeholder__")]
+ extern "C" {
+ fn __wbindgen_object_clone_ref(idx: u32) -> u32;
+ fn __wbindgen_object_drop_ref(idx: u32) -> ();
+
+ fn __wbindgen_string_new(ptr: *const u8, len: usize) -> u32;
+ fn __wbindgen_number_new(f: f64) -> u32;
+ fn __wbindgen_bigint_from_str(ptr: *const u8, len: usize) -> u32;
+ fn __wbindgen_bigint_from_i64(n: i64) -> u32;
+ fn __wbindgen_bigint_from_u64(n: u64) -> u32;
+ fn __wbindgen_bigint_from_i128(hi: i64, lo: u64) -> u32;
+ fn __wbindgen_bigint_from_u128(hi: u64, lo: u64) -> u32;
+ fn __wbindgen_symbol_named_new(ptr: *const u8, len: usize) -> u32;
+ fn __wbindgen_symbol_anonymous_new() -> u32;
+
+ fn __wbindgen_externref_heap_live_count() -> u32;
+
+ fn __wbindgen_is_null(idx: u32) -> u32;
+ fn __wbindgen_is_undefined(idx: u32) -> u32;
+ fn __wbindgen_is_symbol(idx: u32) -> u32;
+ fn __wbindgen_is_object(idx: u32) -> u32;
+ fn __wbindgen_is_function(idx: u32) -> u32;
+ fn __wbindgen_is_string(idx: u32) -> u32;
+ fn __wbindgen_is_bigint(idx: u32) -> u32;
+ fn __wbindgen_typeof(idx: u32) -> u32;
+
+ fn __wbindgen_in(prop: u32, obj: u32) -> u32;
+
+ fn __wbindgen_is_falsy(idx: u32) -> u32;
+ fn __wbindgen_as_number(idx: u32) -> f64;
+ fn __wbindgen_try_into_number(idx: u32) -> u32;
+ fn __wbindgen_neg(idx: u32) -> u32;
+ fn __wbindgen_bit_and(a: u32, b: u32) -> u32;
+ fn __wbindgen_bit_or(a: u32, b: u32) -> u32;
+ fn __wbindgen_bit_xor(a: u32, b: u32) -> u32;
+ fn __wbindgen_bit_not(idx: u32) -> u32;
+ fn __wbindgen_shl(a: u32, b: u32) -> u32;
+ fn __wbindgen_shr(a: u32, b: u32) -> u32;
+ fn __wbindgen_unsigned_shr(a: u32, b: u32) -> u32;
+ fn __wbindgen_add(a: u32, b: u32) -> u32;
+ fn __wbindgen_sub(a: u32, b: u32) -> u32;
+ fn __wbindgen_div(a: u32, b: u32) -> u32;
+ fn __wbindgen_checked_div(a: u32, b: u32) -> u32;
+ fn __wbindgen_mul(a: u32, b: u32) -> u32;
+ fn __wbindgen_rem(a: u32, b: u32) -> u32;
+ fn __wbindgen_pow(a: u32, b: u32) -> u32;
+ fn __wbindgen_lt(a: u32, b: u32) -> u32;
+ fn __wbindgen_le(a: u32, b: u32) -> u32;
+ fn __wbindgen_ge(a: u32, b: u32) -> u32;
+ fn __wbindgen_gt(a: u32, b: u32) -> u32;
+
+ fn __wbindgen_number_get(idx: u32) -> WasmOption<f64>;
+ fn __wbindgen_boolean_get(idx: u32) -> u32;
+ fn __wbindgen_string_get(idx: u32) -> WasmSlice;
+ fn __wbindgen_bigint_get_as_i64(idx: u32) -> WasmOption<i64>;
+
+ fn __wbindgen_debug_string(ret: *mut [usize; 2], idx: u32) -> ();
+
+ fn __wbindgen_throw(a: *const u8, b: usize) -> !;
+ fn __wbindgen_rethrow(a: u32) -> !;
+ fn __wbindgen_error_new(a: *const u8, b: usize) -> u32;
+
+ fn __wbindgen_cb_drop(idx: u32) -> u32;
+
+ fn __wbindgen_describe(v: u32) -> ();
+ fn __wbindgen_describe_closure(a: u32, b: u32, c: u32) -> u32;
+
+ fn __wbindgen_json_parse(ptr: *const u8, len: usize) -> u32;
+ fn __wbindgen_json_serialize(idx: u32) -> WasmSlice;
+ fn __wbindgen_jsval_eq(a: u32, b: u32) -> u32;
+ fn __wbindgen_jsval_loose_eq(a: u32, b: u32) -> u32;
+
+ fn __wbindgen_not(idx: u32) -> u32;
+
+ fn __wbindgen_memory() -> u32;
+ fn __wbindgen_module() -> u32;
+ fn __wbindgen_function_table() -> u32;
+ }
+}
+
+impl Clone for JsValue {
+ #[inline]
+ fn clone(&self) -> JsValue {
+ unsafe {
+ let idx = __wbindgen_object_clone_ref(self.idx);
+ JsValue::_new(idx)
+ }
+ }
+}
+
+#[cfg(feature = "std")]
+impl fmt::Debug for JsValue {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "JsValue({})", self.as_debug_string())
+ }
+}
+
+#[cfg(not(feature = "std"))]
+impl fmt::Debug for JsValue {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.write_str("JsValue")
+ }
+}
+
+impl Drop for JsValue {
+ #[inline]
+ fn drop(&mut self) {
+ unsafe {
+ // We definitely should never drop anything in the stack area
+ debug_assert!(self.idx >= JSIDX_OFFSET, "free of stack slot {}", self.idx);
+
+ // Otherwise if we're not dropping one of our reserved values,
+ // actually call the intrinsic. See #1054 for eventually removing
+ // this branch.
+ if self.idx >= JSIDX_RESERVED {
+ __wbindgen_object_drop_ref(self.idx);
+ }
+ }
+ }
+}
+
+impl Default for JsValue {
+ fn default() -> Self {
+ Self::UNDEFINED
+ }
+}
+
+/// Wrapper type for imported statics.
+///
+/// This type is used whenever a `static` is imported from a JS module, for
+/// example this import:
+///
+/// ```ignore
+/// #[wasm_bindgen]
+/// extern "C" {
+/// static console: JsValue;
+/// }
+/// ```
+///
+/// will generate in Rust a value that looks like:
+///
+/// ```ignore
+/// static console: JsStatic<JsValue> = ...;
+/// ```
+///
+/// This type implements `Deref` to the inner type so it's typically used as if
+/// it were `&T`.
+#[cfg(feature = "std")]
+pub struct JsStatic<T: 'static> {
+ #[doc(hidden)]
+ pub __inner: &'static std::thread::LocalKey<T>,
+}
+
+#[cfg(feature = "std")]
+impl<T: FromWasmAbi + 'static> Deref for JsStatic<T> {
+ type Target = T;
+ fn deref(&self) -> &T {
+ // We know that our tls key is never overwritten after initialization,
+ // so it should be safe (on that axis at least) to hand out a reference
+ // that lives longer than the closure below.
+ //
+ // FIXME: this is not sound if we ever implement thread exit hooks on
+ // wasm, as the pointer will eventually be invalidated but you can get
+ // `&'static T` from this interface. We... probably need to deprecate
+ // and/or remove this interface nowadays.
+ unsafe { self.__inner.with(|ptr| &*(ptr as *const T)) }
+ }
+}
+
+#[cold]
+#[inline(never)]
+#[deprecated(note = "renamed to `throw_str`")]
+#[doc(hidden)]
+pub fn throw(s: &str) -> ! {
+ throw_str(s)
+}
+
+/// Throws a JS exception.
+///
+/// This function will throw a JS exception with the message provided. The
+/// function will not return as the wasm stack will be popped when the exception
+/// is thrown.
+///
+/// Note that it is very easy to leak memory with this function because this
+/// function, unlike `panic!` on other platforms, **will not run destructors**.
+/// It's recommended to return a `Result` where possible to avoid the worry of
+/// leaks.
+#[cold]
+#[inline(never)]
+pub fn throw_str(s: &str) -> ! {
+ unsafe {
+ __wbindgen_throw(s.as_ptr(), s.len());
+ }
+}
+
+/// Rethrow a JS exception
+///
+/// This function will throw a JS exception with the JS value provided. This
+/// function will not return and the wasm stack will be popped until the point
+/// of entry of wasm itself.
+///
+/// Note that it is very easy to leak memory with this function because this
+/// function, unlike `panic!` on other platforms, **will not run destructors**.
+/// It's recommended to return a `Result` where possible to avoid the worry of
+/// leaks.
+#[cold]
+#[inline(never)]
+pub fn throw_val(s: JsValue) -> ! {
+ unsafe {
+ let idx = s.idx;
+ mem::forget(s);
+ __wbindgen_rethrow(idx);
+ }
+}
+
+/// Get the count of live `externref`s / `JsValue`s in `wasm-bindgen`'s heap.
+///
+/// ## Usage
+///
+/// This is intended for debugging and writing tests.
+///
+/// To write a test that asserts against unnecessarily keeping `anref`s /
+/// `JsValue`s alive:
+///
+/// * get an initial live count,
+///
+/// * perform some series of operations or function calls that should clean up
+/// after themselves, and should not keep holding onto `externref`s / `JsValue`s
+/// after completion,
+///
+/// * get the final live count,
+///
+/// * and assert that the initial and final counts are the same.
+///
+/// ## What is Counted
+///
+/// Note that this only counts the *owned* `externref`s / `JsValue`s that end up in
+/// `wasm-bindgen`'s heap. It does not count borrowed `externref`s / `JsValue`s
+/// that are on its stack.
+///
+/// For example, these `JsValue`s are accounted for:
+///
+/// ```ignore
+/// #[wasm_bindgen]
+/// pub fn my_function(this_is_counted: JsValue) {
+/// let also_counted = JsValue::from_str("hi");
+/// assert!(wasm_bindgen::externref_heap_live_count() >= 2);
+/// }
+/// ```
+///
+/// While this borrowed `JsValue` ends up on the stack, not the heap, and
+/// therefore is not accounted for:
+///
+/// ```ignore
+/// #[wasm_bindgen]
+/// pub fn my_other_function(this_is_not_counted: &JsValue) {
+/// // ...
+/// }
+/// ```
+pub fn externref_heap_live_count() -> u32 {
+ unsafe { __wbindgen_externref_heap_live_count() }
+}
+
+#[doc(hidden)]
+pub fn anyref_heap_live_count() -> u32 {
+ externref_heap_live_count()
+}
+
+/// An extension trait for `Option<T>` and `Result<T, E>` for unwrapping the `T`
+/// value, or throwing a JS error if it is not available.
+///
+/// These methods should have a smaller code size footprint than the normal
+/// `Option::unwrap` and `Option::expect` methods, but they are specific to
+/// working with wasm and JS.
+///
+/// On non-wasm32 targets, defaults to the normal unwrap/expect calls.
+///
+/// # Example
+///
+/// ```
+/// use wasm_bindgen::prelude::*;
+///
+/// // If the value is `Option::Some` or `Result::Ok`, then we just get the
+/// // contained `T` value.
+/// let x = Some(42);
+/// assert_eq!(x.unwrap_throw(), 42);
+///
+/// let y: Option<i32> = None;
+///
+/// // This call would throw an error to JS!
+/// //
+/// // y.unwrap_throw()
+/// //
+/// // And this call would throw an error to JS with a custom error message!
+/// //
+/// // y.expect_throw("woopsie daisy!")
+/// ```
+pub trait UnwrapThrowExt<T>: Sized {
+ /// Unwrap this `Option` or `Result`, but instead of panicking on failure,
+ /// throw an exception to JavaScript.
+ fn unwrap_throw(self) -> T {
+ self.expect_throw("`unwrap_throw` failed")
+ }
+
+ /// Unwrap this container's `T` value, or throw an error to JS with the
+ /// given message if the `T` value is unavailable (e.g. an `Option<T>` is
+ /// `None`).
+ fn expect_throw(self, message: &str) -> T;
+}
+
+impl<T> UnwrapThrowExt<T> for Option<T> {
+ fn expect_throw(self, message: &str) -> T {
+ if cfg!(all(target_arch = "wasm32", not(target_os = "emscripten"))) {
+ match self {
+ Some(val) => val,
+ None => throw_str(message),
+ }
+ } else {
+ self.expect(message)
+ }
+ }
+}
+
+impl<T, E> UnwrapThrowExt<T> for Result<T, E>
+where
+ E: core::fmt::Debug,
+{
+ fn expect_throw(self, message: &str) -> T {
+ if cfg!(all(target_arch = "wasm32", not(target_os = "emscripten"))) {
+ match self {
+ Ok(val) => val,
+ Err(_) => throw_str(message),
+ }
+ } else {
+ self.expect(message)
+ }
+ }
+}
+
+/// Returns a handle to this wasm instance's `WebAssembly.Module`
+///
+/// Note that this is only available when the final wasm app is built with
+/// `--target no-modules`, it's not recommended to rely on this API yet! This is
+/// largely just an experimental addition to enable threading demos. Using this
+/// may prevent your wasm module from building down the road.
+#[doc(hidden)]
+pub fn module() -> JsValue {
+ unsafe { JsValue::_new(__wbindgen_module()) }
+}
+
+/// Returns a handle to this wasm instance's `WebAssembly.Memory`
+pub fn memory() -> JsValue {
+ unsafe { JsValue::_new(__wbindgen_memory()) }
+}
+
+/// Returns a handle to this wasm instance's `WebAssembly.Table` which is the
+/// indirect function table used by Rust
+pub fn function_table() -> JsValue {
+ unsafe { JsValue::_new(__wbindgen_function_table()) }
+}
+
+#[doc(hidden)]
+pub mod __rt {
+ use crate::JsValue;
+ use core::cell::{Cell, UnsafeCell};
+ use core::ops::{Deref, DerefMut};
+
+ pub extern crate core;
+ #[cfg(feature = "std")]
+ pub extern crate std;
+
+ #[macro_export]
+ #[doc(hidden)]
+ #[cfg(feature = "std")]
+ macro_rules! __wbindgen_if_not_std {
+ ($($i:item)*) => {};
+ }
+
+ #[macro_export]
+ #[doc(hidden)]
+ #[cfg(not(feature = "std"))]
+ macro_rules! __wbindgen_if_not_std {
+ ($($i:item)*) => ($($i)*)
+ }
+
+ #[inline]
+ pub fn assert_not_null<T>(s: *mut T) {
+ if s.is_null() {
+ throw_null();
+ }
+ }
+
+ #[cold]
+ #[inline(never)]
+ fn throw_null() -> ! {
+ super::throw_str("null pointer passed to rust");
+ }
+
+ /// A vendored version of `RefCell` from the standard library.
+ ///
+ /// Now why, you may ask, would we do that? Surely `RefCell` in libstd is
+ /// quite good. And you're right, it is indeed quite good! Functionally
+ /// nothing more is needed from `RefCell` in the standard library but for
+ /// now this crate is also sort of optimizing for compiled code size.
+ ///
+ /// One major factor to larger binaries in Rust is when a panic happens.
+ /// Panicking in the standard library involves a fair bit of machinery
+ /// (formatting, panic hooks, synchronization, etc). It's all worthwhile if
+ /// you need it but for something like `WasmRefCell` here we don't actually
+ /// need all that!
+ ///
+ /// This is just a wrapper around all Rust objects passed to JS intended to
+ /// guard accidental reentrancy, so this vendored version is intended solely
+ /// to not panic in libstd. Instead when it "panics" it calls our `throw`
+ /// function in this crate which raises an error in JS.
+ pub struct WasmRefCell<T: ?Sized> {
+ borrow: Cell<usize>,
+ value: UnsafeCell<T>,
+ }
+
+ impl<T: ?Sized> WasmRefCell<T> {
+ pub fn new(value: T) -> WasmRefCell<T>
+ where
+ T: Sized,
+ {
+ WasmRefCell {
+ value: UnsafeCell::new(value),
+ borrow: Cell::new(0),
+ }
+ }
+
+ pub fn get_mut(&mut self) -> &mut T {
+ unsafe { &mut *self.value.get() }
+ }
+
+ pub fn borrow(&self) -> Ref<T> {
+ unsafe {
+ if self.borrow.get() == usize::max_value() {
+ borrow_fail();
+ }
+ self.borrow.set(self.borrow.get() + 1);
+ Ref {
+ value: &*self.value.get(),
+ borrow: &self.borrow,
+ }
+ }
+ }
+
+ pub fn borrow_mut(&self) -> RefMut<T> {
+ unsafe {
+ if self.borrow.get() != 0 {
+ borrow_fail();
+ }
+ self.borrow.set(usize::max_value());
+ RefMut {
+ value: &mut *self.value.get(),
+ borrow: &self.borrow,
+ }
+ }
+ }
+
+ pub fn into_inner(self) -> T
+ where
+ T: Sized,
+ {
+ self.value.into_inner()
+ }
+ }
+
+ pub struct Ref<'b, T: ?Sized + 'b> {
+ value: &'b T,
+ borrow: &'b Cell<usize>,
+ }
+
+ impl<'b, T: ?Sized> Deref for Ref<'b, T> {
+ type Target = T;
+
+ #[inline]
+ fn deref(&self) -> &T {
+ self.value
+ }
+ }
+
+ impl<'b, T: ?Sized> Drop for Ref<'b, T> {
+ fn drop(&mut self) {
+ self.borrow.set(self.borrow.get() - 1);
+ }
+ }
+
+ pub struct RefMut<'b, T: ?Sized + 'b> {
+ value: &'b mut T,
+ borrow: &'b Cell<usize>,
+ }
+
+ impl<'b, T: ?Sized> Deref for RefMut<'b, T> {
+ type Target = T;
+
+ #[inline]
+ fn deref(&self) -> &T {
+ self.value
+ }
+ }
+
+ impl<'b, T: ?Sized> DerefMut for RefMut<'b, T> {
+ #[inline]
+ fn deref_mut(&mut self) -> &mut T {
+ self.value
+ }
+ }
+
+ impl<'b, T: ?Sized> Drop for RefMut<'b, T> {
+ fn drop(&mut self) {
+ self.borrow.set(0);
+ }
+ }
+
+ fn borrow_fail() -> ! {
+ super::throw_str(
+ "recursive use of an object detected which would lead to \
+ unsafe aliasing in rust",
+ );
+ }
+
+ if_std! {
+ use std::alloc::{alloc, dealloc, realloc, Layout};
+ use std::mem;
+
+ #[no_mangle]
+ pub extern "C" fn __wbindgen_malloc(size: usize) -> *mut u8 {
+ let align = mem::align_of::<usize>();
+ if let Ok(layout) = Layout::from_size_align(size, align) {
+ unsafe {
+ if layout.size() > 0 {
+ let ptr = alloc(layout);
+ if !ptr.is_null() {
+ return ptr
+ }
+ } else {
+ return align as *mut u8
+ }
+ }
+ }
+
+ malloc_failure();
+ }
+
+ #[no_mangle]
+ pub unsafe extern "C" fn __wbindgen_realloc(ptr: *mut u8, old_size: usize, new_size: usize) -> *mut u8 {
+ let align = mem::align_of::<usize>();
+ debug_assert!(old_size > 0);
+ debug_assert!(new_size > 0);
+ if let Ok(layout) = Layout::from_size_align(old_size, align) {
+ let ptr = realloc(ptr, layout, new_size);
+ if !ptr.is_null() {
+ return ptr
+ }
+ }
+ malloc_failure();
+ }
+
+ #[cold]
+ fn malloc_failure() -> ! {
+ if cfg!(debug_assertions) {
+ super::throw_str("invalid malloc request")
+ } else {
+ std::process::abort();
+ }
+ }
+
+ #[no_mangle]
+ pub unsafe extern "C" fn __wbindgen_free(ptr: *mut u8, size: usize) {
+ // This happens for zero-length slices, and in that case `ptr` is
+ // likely bogus so don't actually send this to the system allocator
+ if size == 0 {
+ return
+ }
+ let align = mem::align_of::<usize>();
+ let layout = Layout::from_size_align_unchecked(size, align);
+ dealloc(ptr, layout);
+ }
+ }
+
+ /// This is a curious function necessary to get wasm-bindgen working today,
+ /// and it's a bit of an unfortunate hack.
+ ///
+ /// The general problem is that somehow we need the above two symbols to
+ /// exist in the final output binary (__wbindgen_malloc and
+ /// __wbindgen_free). These symbols may be called by JS for various
+ /// bindings, so we for sure need to make sure they're exported.
+ ///
+ /// The problem arises, though, when what if no Rust code uses the symbols?
+ /// For all intents and purposes it looks to LLVM and the linker like the
+ /// above two symbols are dead code, so they're completely discarded!
+ ///
+ /// Specifically what happens is this:
+ ///
+ /// * The above two symbols are generated into some object file inside of
+ /// libwasm_bindgen.rlib
+ /// * The linker, LLD, will not load this object file unless *some* symbol
+ /// is loaded from the object. In this case, if the Rust code never calls
+ /// __wbindgen_malloc or __wbindgen_free then the symbols never get linked
+ /// in.
+ /// * Later when `wasm-bindgen` attempts to use the symbols they don't
+ /// exist, causing an error.
+ ///
+ /// This function is a weird hack for this problem. We inject a call to this
+ /// function in all generated code. Usage of this function should then
+ /// ensure that the above two intrinsics are translated.
+ ///
+ /// Due to how rustc creates object files this function (and anything inside
+ /// it) will be placed into the same object file as the two intrinsics
+ /// above. That means if this function is called and referenced we'll pull
+ /// in the object file and link the intrinsics.
+ ///
+ /// Ideas for how to improve this are most welcome!
+ pub fn link_mem_intrinsics() {
+ crate::externref::link_intrinsics();
+ }
+
+ static mut GLOBAL_EXNDATA: [u32; 2] = [0; 2];
+
+ #[no_mangle]
+ pub unsafe extern "C" fn __wbindgen_exn_store(idx: u32) {
+ debug_assert_eq!(GLOBAL_EXNDATA[0], 0);
+ GLOBAL_EXNDATA[0] = 1;
+ GLOBAL_EXNDATA[1] = idx;
+ }
+
+ pub fn take_last_exception() -> Result<(), super::JsValue> {
+ unsafe {
+ let ret = if GLOBAL_EXNDATA[0] == 1 {
+ Err(super::JsValue::_new(GLOBAL_EXNDATA[1]))
+ } else {
+ Ok(())
+ };
+ GLOBAL_EXNDATA[0] = 0;
+ GLOBAL_EXNDATA[1] = 0;
+ return ret;
+ }
+ }
+
+ /// An internal helper trait for usage in `#[wasm_bindgen]` on `async`
+ /// functions to convert the return value of the function to
+ /// `Result<JsValue, JsValue>` which is what we'll return to JS (where an
+ /// error is a failed future).
+ pub trait IntoJsResult {
+ fn into_js_result(self) -> Result<JsValue, JsValue>;
+ }
+
+ impl IntoJsResult for () {
+ fn into_js_result(self) -> Result<JsValue, JsValue> {
+ Ok(JsValue::undefined())
+ }
+ }
+
+ impl<T: Into<JsValue>> IntoJsResult for T {
+ fn into_js_result(self) -> Result<JsValue, JsValue> {
+ Ok(self.into())
+ }
+ }
+
+ impl<T: Into<JsValue>, E: Into<JsValue>> IntoJsResult for Result<T, E> {
+ fn into_js_result(self) -> Result<JsValue, JsValue> {
+ match self {
+ Ok(e) => Ok(e.into()),
+ Err(e) => Err(e.into()),
+ }
+ }
+ }
+
+ impl<E: Into<JsValue>> IntoJsResult for Result<(), E> {
+ fn into_js_result(self) -> Result<JsValue, JsValue> {
+ match self {
+ Ok(()) => Ok(JsValue::undefined()),
+ Err(e) => Err(e.into()),
+ }
+ }
+ }
+
+ /// An internal helper trait for usage in `#[wasm_bindgen(start)]`
+ /// functions to throw the error (if it is `Err`).
+ pub trait Start {
+ fn start(self);
+ }
+
+ impl Start for () {
+ #[inline]
+ fn start(self) {}
+ }
+
+ impl<E: Into<JsValue>> Start for Result<(), E> {
+ #[inline]
+ fn start(self) {
+ if let Err(e) = self {
+ crate::throw_val(e.into());
+ }
+ }
+ }
+}
+
+/// A wrapper type around slices and vectors for binding the `Uint8ClampedArray`
+/// array in JS.
+///
+/// If you need to invoke a JS API which must take `Uint8ClampedArray` array,
+/// then you can define it as taking one of these types:
+///
+/// * `Clamped<&[u8]>`
+/// * `Clamped<&mut [u8]>`
+/// * `Clamped<Vec<u8>>`
+///
+/// All of these types will show up as `Uint8ClampedArray` in JS and will have
+/// different forms of ownership in Rust.
+#[derive(Copy, Clone, PartialEq, Debug, Eq)]
+pub struct Clamped<T>(pub T);
+
+impl<T> Deref for Clamped<T> {
+ type Target = T;
+
+ fn deref(&self) -> &T {
+ &self.0
+ }
+}
+
+impl<T> DerefMut for Clamped<T> {
+ fn deref_mut(&mut self) -> &mut T {
+ &mut self.0
+ }
+}
+
+/// Convenience type for use on exported `fn() -> Result<T, JsError>` functions, where you wish to
+/// throw a JavaScript `Error` object.
+///
+/// You can get wasm_bindgen to throw basic errors by simply returning
+/// `Err(JsError::new("message"))` from such a function.
+///
+/// For more complex error handling, `JsError` implements `From<T> where T: std::error::Error` by
+/// converting it to a string, so you can use it with `?`. Many Rust error types already do this,
+/// and you can use [`thiserror`](https://crates.io/crates/thiserror) to derive Display
+/// implementations easily or use any number of boxed error types that implement it already.
+///
+///
+/// To allow JavaScript code to catch only your errors, you may wish to add a subclass of `Error`
+/// in a JS module, and then implement `Into<JsValue>` directly on a type and instantiate that
+/// subclass. In that case, you would not need `JsError` at all.
+///
+/// ### Basic example
+///
+/// ```rust,no_run
+/// use wasm_bindgen::prelude::*;
+///
+/// #[wasm_bindgen]
+/// pub fn throwing_function() -> Result<(), JsError> {
+/// Err(JsError::new("message"))
+/// }
+/// ```
+///
+/// ### Complex Example
+///
+/// ```rust,no_run
+/// use wasm_bindgen::prelude::*;
+///
+/// #[derive(Debug, Clone)]
+/// enum MyErrorType {
+/// SomeError,
+/// }
+///
+/// use core::fmt;
+/// impl std::error::Error for MyErrorType {}
+/// impl fmt::Display for MyErrorType {
+/// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+/// write!(f, "display implementation becomes the error message")
+/// }
+/// }
+///
+/// fn internal_api() -> Result<(), MyErrorType> {
+/// Err(MyErrorType::SomeError)
+/// }
+///
+/// #[wasm_bindgen]
+/// pub fn throwing_function() -> Result<(), JsError> {
+/// internal_api()?;
+/// Ok(())
+/// }
+///
+/// ```
+#[derive(Clone)]
+pub struct JsError {
+ value: JsValue,
+}
+
+impl JsError {
+ /// Construct a JavaScript `Error` object with a string message
+ #[inline]
+ pub fn new(s: &str) -> JsError {
+ Self {
+ value: unsafe { JsValue::_new(crate::__wbindgen_error_new(s.as_ptr(), s.len())) },
+ }
+ }
+}
+
+if_std! {
+ impl<E> From<E> for JsError
+ where
+ E: std::error::Error,
+ {
+ fn from(error: E) -> Self {
+ JsError::new(&error.to_string())
+ }
+ }
+}
+
+impl From<JsError> for JsValue {
+ fn from(error: JsError) -> Self {
+ error.value
+ }
+}