wasm_bindgen/
lib.rs

1//! Runtime support for the `wasm-bindgen` tool
2//!
3//! This crate contains the runtime support necessary for `wasm-bindgen` the
4//! attribute and tool. Crates pull in the `#[wasm_bindgen]` attribute through
5//! this crate and this crate also provides JS bindings through the `JsValue`
6//! interface.
7//!
8//! ## Features
9//!
10//! ### `enable-interning`
11//!
12//! Enables the internal cache for [`wasm_bindgen::intern`].
13//!
14//! This feature currently enables the `std` feature, meaning that it is not
15//! compatible with `no_std` environments.
16//!
17//! ### `msrv` (default)
18//!
19//! Enables Rust language features that require a higher MSRV. Enabling this
20//! feature on older compilers will NOT result in a compilation error, the newer
21//! language features will simply not be used.
22//!
23//! When compiling with Rust v1.78 or later, this feature enables better error messages for invalid methods on structs and enums.
24//!
25//! ### `std` (default)
26//!
27//! Enabling this feature will make the crate depend on the Rust standard library.
28//!
29//! Disable this feature to use this crate in `no_std` environments.
30//!
31//! ### `strict-macro`
32//!
33//! All warnings the `#[wasm_bindgen]` macro emits are turned into hard errors.
34//! This mainly affects unused attribute options.
35//!
36//! ### Deprecated features
37//!
38//! #### `serde-serialize`
39//!
40//! **Deprecated:** Use the [`serde-wasm-bindgen`](https://docs.rs/serde-wasm-bindgen/latest/serde_wasm_bindgen/) crate instead.
41//!
42//! Enables the `JsValue::from_serde` and `JsValue::into_serde` methods for
43//! serializing and deserializing Rust types to and from JavaScript.
44//!
45//! #### `spans`
46//!
47//! **Deprecated:** This feature became a no-op in wasm-bindgen v0.2.20 (Sep 7, 2018).
48
49#![no_std]
50#![cfg_attr(wasm_bindgen_unstable_test_coverage, feature(coverage_attribute))]
51#![cfg_attr(target_feature = "atomics", feature(thread_local))]
52#![cfg_attr(
53    any(target_feature = "atomics", wasm_bindgen_unstable_test_coverage),
54    feature(allow_internal_unstable),
55    allow(internal_features)
56)]
57#![doc(html_root_url = "https://docs.rs/wasm-bindgen/0.2")]
58
59extern crate alloc;
60#[cfg(feature = "std")]
61extern crate std;
62
63use alloc::boxed::Box;
64use alloc::string::String;
65use alloc::vec::Vec;
66use core::convert::TryFrom;
67use core::marker::PhantomData;
68use core::ops::{
69    Add, BitAnd, BitOr, BitXor, Deref, DerefMut, Div, Mul, Neg, Not, Rem, Shl, Shr, Sub,
70};
71use core::ptr::NonNull;
72
73use crate::convert::{TryFromJsValue, VectorIntoWasmAbi};
74
75const _: () = {
76    /// Dummy empty function provided in order to detect linker-injected functions like `__wasm_call_ctors` and others that should be skipped by the wasm-bindgen interpreter.
77    ///
78    /// ## About `__wasm_call_ctors`
79    ///
80    /// There are several ways `__wasm_call_ctors` is introduced by the linker:
81    ///
82    /// * Using `#[link_section = ".init_array"]`;
83    /// * Linking with a C library that uses `__attribute__((constructor))`.
84    ///
85    /// The Wasm linker will insert a call to the `__wasm_call_ctors` function at the beginning of every
86    /// function that your module exports if it regards a module as having "command-style linkage".
87    /// Specifically, it regards a module as having "command-style linkage" if:
88    ///
89    /// * it is not relocatable;
90    /// * it is not a position-independent executable;
91    /// * and it does not call `__wasm_call_ctors`, directly or indirectly, from any
92    ///   exported function.
93    #[no_mangle]
94    pub extern "C" fn __wbindgen_skip_interpret_calls() {}
95};
96
97macro_rules! externs {
98    ($(#[$attr:meta])* extern "C" { $(fn $name:ident($($args:tt)*) -> $ret:ty;)* }) => (
99        #[cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))]
100        $(#[$attr])*
101        extern "C" {
102            $(fn $name($($args)*) -> $ret;)*
103        }
104
105        $(
106            #[cfg(not(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none"))))]
107            #[allow(unused_variables)]
108            unsafe extern "C" fn $name($($args)*) -> $ret {
109                panic!("function not implemented on non-wasm32 targets")
110            }
111        )*
112    )
113}
114
115/// A module which is typically glob imported.
116///
117/// ```
118/// use wasm_bindgen::prelude::*;
119/// ```
120pub mod prelude {
121    pub use crate::closure::Closure;
122    pub use crate::JsCast;
123    pub use crate::JsValue;
124    pub use crate::UnwrapThrowExt;
125    #[doc(hidden)]
126    pub use wasm_bindgen_macro::__wasm_bindgen_class_marker;
127    pub use wasm_bindgen_macro::wasm_bindgen;
128
129    pub use crate::JsError;
130}
131
132pub use wasm_bindgen_macro::link_to;
133
134pub mod closure;
135pub mod convert;
136pub mod describe;
137mod link;
138
139#[cfg(target_feature = "reference-types")]
140mod externref;
141#[cfg(target_feature = "reference-types")]
142use externref::__wbindgen_externref_heap_live_count;
143
144mod cast;
145pub use crate::cast::JsCast;
146
147mod cache;
148pub use cache::intern::{intern, unintern};
149
150#[doc(hidden)]
151#[path = "rt/mod.rs"]
152pub mod __rt;
153use __rt::wbg_cast;
154
155/// Representation of an object owned by JS.
156///
157/// A `JsValue` doesn't actually live in Rust right now but actually in a table
158/// owned by the `wasm-bindgen` generated JS glue code. Eventually the ownership
159/// will transfer into Wasm directly and this will likely become more efficient,
160/// but for now it may be slightly slow.
161pub struct JsValue {
162    idx: u32,
163    _marker: PhantomData<*mut u8>, // not at all threadsafe
164}
165
166const JSIDX_OFFSET: u32 = 128; // keep in sync with js/mod.rs
167const JSIDX_UNDEFINED: u32 = JSIDX_OFFSET;
168const JSIDX_NULL: u32 = JSIDX_OFFSET + 1;
169const JSIDX_TRUE: u32 = JSIDX_OFFSET + 2;
170const JSIDX_FALSE: u32 = JSIDX_OFFSET + 3;
171const JSIDX_RESERVED: u32 = JSIDX_OFFSET + 4;
172
173impl JsValue {
174    /// The `null` JS value constant.
175    pub const NULL: JsValue = JsValue::_new(JSIDX_NULL);
176
177    /// The `undefined` JS value constant.
178    pub const UNDEFINED: JsValue = JsValue::_new(JSIDX_UNDEFINED);
179
180    /// The `true` JS value constant.
181    pub const TRUE: JsValue = JsValue::_new(JSIDX_TRUE);
182
183    /// The `false` JS value constant.
184    pub const FALSE: JsValue = JsValue::_new(JSIDX_FALSE);
185
186    #[inline]
187    const fn _new(idx: u32) -> JsValue {
188        JsValue {
189            idx,
190            _marker: PhantomData,
191        }
192    }
193
194    /// Creates a new JS value which is a string.
195    ///
196    /// The utf-8 string provided is copied to the JS heap and the string will
197    /// be owned by the JS garbage collector.
198    #[allow(clippy::should_implement_trait)] // cannot fix without breaking change
199    #[inline]
200    pub fn from_str(s: &str) -> JsValue {
201        wbg_cast(s)
202    }
203
204    /// Creates a new JS value which is a number.
205    ///
206    /// This function creates a JS value representing a number (a heap
207    /// allocated number) and returns a handle to the JS version of it.
208    #[inline]
209    pub fn from_f64(n: f64) -> JsValue {
210        wbg_cast(n)
211    }
212
213    /// Creates a new JS value which is a bigint from a string representing a number.
214    ///
215    /// This function creates a JS value representing a bigint (a heap
216    /// allocated large integer) and returns a handle to the JS version of it.
217    #[inline]
218    pub fn bigint_from_str(s: &str) -> JsValue {
219        __wbindgen_bigint_from_str(s)
220    }
221
222    /// Creates a new JS value which is a boolean.
223    ///
224    /// This function creates a JS object representing a boolean (a heap
225    /// allocated boolean) and returns a handle to the JS version of it.
226    #[inline]
227    pub const fn from_bool(b: bool) -> JsValue {
228        if b {
229            JsValue::TRUE
230        } else {
231            JsValue::FALSE
232        }
233    }
234
235    /// Creates a new JS value representing `undefined`.
236    #[inline]
237    pub const fn undefined() -> JsValue {
238        JsValue::UNDEFINED
239    }
240
241    /// Creates a new JS value representing `null`.
242    #[inline]
243    pub const fn null() -> JsValue {
244        JsValue::NULL
245    }
246
247    /// Creates a new JS symbol with the optional description specified.
248    ///
249    /// This function will invoke the `Symbol` constructor in JS and return the
250    /// JS object corresponding to the symbol created.
251    pub fn symbol(description: Option<&str>) -> JsValue {
252        __wbindgen_symbol_new(description)
253    }
254
255    /// Creates a new `JsValue` from the JSON serialization of the object `t`
256    /// provided.
257    ///
258    /// **This function is deprecated**, due to [creating a dependency cycle in
259    /// some circumstances][dep-cycle-issue]. Use [`serde-wasm-bindgen`] or
260    /// [`gloo_utils::format::JsValueSerdeExt`] instead.
261    ///
262    /// [dep-cycle-issue]: https://github.com/wasm-bindgen/wasm-bindgen/issues/2770
263    /// [`serde-wasm-bindgen`]: https://docs.rs/serde-wasm-bindgen
264    /// [`gloo_utils::format::JsValueSerdeExt`]: https://docs.rs/gloo-utils/latest/gloo_utils/format/trait.JsValueSerdeExt.html
265    ///
266    /// This function will serialize the provided value `t` to a JSON string,
267    /// send the JSON string to JS, parse it into a JS object, and then return
268    /// a handle to the JS object. This is unlikely to be super speedy so it's
269    /// not recommended for large payloads, but it's a nice to have in some
270    /// situations!
271    ///
272    /// Usage of this API requires activating the `serde-serialize` feature of
273    /// the `wasm-bindgen` crate.
274    ///
275    /// # Errors
276    ///
277    /// Returns any error encountered when serializing `T` into JSON.
278    #[cfg(feature = "serde-serialize")]
279    #[deprecated = "causes dependency cycles, use `serde-wasm-bindgen` or `gloo_utils::format::JsValueSerdeExt` instead"]
280    pub fn from_serde<T>(t: &T) -> serde_json::Result<JsValue>
281    where
282        T: serde::ser::Serialize + ?Sized,
283    {
284        let s = serde_json::to_string(t)?;
285        Ok(__wbindgen_json_parse(s))
286    }
287
288    /// Invokes `JSON.stringify` on this value and then parses the resulting
289    /// JSON into an arbitrary Rust value.
290    ///
291    /// **This function is deprecated**, due to [creating a dependency cycle in
292    /// some circumstances][dep-cycle-issue]. Use [`serde-wasm-bindgen`] or
293    /// [`gloo_utils::format::JsValueSerdeExt`] instead.
294    ///
295    /// [dep-cycle-issue]: https://github.com/wasm-bindgen/wasm-bindgen/issues/2770
296    /// [`serde-wasm-bindgen`]: https://docs.rs/serde-wasm-bindgen
297    /// [`gloo_utils::format::JsValueSerdeExt`]: https://docs.rs/gloo-utils/latest/gloo_utils/format/trait.JsValueSerdeExt.html
298    ///
299    /// This function will first call `JSON.stringify` on the `JsValue` itself.
300    /// The resulting string is then passed into Rust which then parses it as
301    /// JSON into the resulting value.
302    ///
303    /// Usage of this API requires activating the `serde-serialize` feature of
304    /// the `wasm-bindgen` crate.
305    ///
306    /// # Errors
307    ///
308    /// Returns any error encountered when parsing the JSON into a `T`.
309    #[cfg(feature = "serde-serialize")]
310    #[deprecated = "causes dependency cycles, use `serde-wasm-bindgen` or `gloo_utils::format::JsValueSerdeExt` instead"]
311    pub fn into_serde<T>(&self) -> serde_json::Result<T>
312    where
313        T: for<'a> serde::de::Deserialize<'a>,
314    {
315        let s = __wbindgen_json_serialize(self);
316        // Turns out `JSON.stringify(undefined) === undefined`, so if
317        // we're passed `undefined` reinterpret it as `null` for JSON
318        // purposes.
319        serde_json::from_str(s.as_deref().unwrap_or("null"))
320    }
321
322    /// Returns the `f64` value of this JS value if it's an instance of a
323    /// number.
324    ///
325    /// If this JS value is not an instance of a number then this returns
326    /// `None`.
327    #[inline]
328    pub fn as_f64(&self) -> Option<f64> {
329        __wbindgen_number_get(self)
330    }
331
332    /// Tests whether this JS value is a JS string.
333    #[inline]
334    pub fn is_string(&self) -> bool {
335        __wbindgen_is_string(self)
336    }
337
338    /// If this JS value is a string value, this function copies the JS string
339    /// value into Wasm linear memory, encoded as UTF-8, and returns it as a
340    /// Rust `String`.
341    ///
342    /// To avoid the copying and re-encoding, consider the
343    /// `JsString::try_from()` function from [js-sys](https://docs.rs/js-sys)
344    /// instead.
345    ///
346    /// If this JS value is not an instance of a string or if it's not valid
347    /// utf-8 then this returns `None`.
348    ///
349    /// # UTF-16 vs UTF-8
350    ///
351    /// JavaScript strings in general are encoded as UTF-16, but Rust strings
352    /// are encoded as UTF-8. This can cause the Rust string to look a bit
353    /// different than the JS string sometimes. For more details see the
354    /// [documentation about the `str` type][caveats] which contains a few
355    /// caveats about the encodings.
356    ///
357    /// [caveats]: https://wasm-bindgen.github.io/wasm-bindgen/reference/types/str.html
358    #[inline]
359    pub fn as_string(&self) -> Option<String> {
360        __wbindgen_string_get(self)
361    }
362
363    /// Returns the `bool` value of this JS value if it's an instance of a
364    /// boolean.
365    ///
366    /// If this JS value is not an instance of a boolean then this returns
367    /// `None`.
368    #[inline]
369    pub fn as_bool(&self) -> Option<bool> {
370        __wbindgen_boolean_get(self)
371    }
372
373    /// Tests whether this JS value is `null`
374    #[inline]
375    pub fn is_null(&self) -> bool {
376        __wbindgen_is_null(self)
377    }
378
379    /// Tests whether this JS value is `undefined`
380    #[inline]
381    pub fn is_undefined(&self) -> bool {
382        __wbindgen_is_undefined(self)
383    }
384
385    /// Tests whether the type of this JS value is `symbol`
386    #[inline]
387    pub fn is_symbol(&self) -> bool {
388        __wbindgen_is_symbol(self)
389    }
390
391    /// Tests whether `typeof self == "object" && self !== null`.
392    #[inline]
393    pub fn is_object(&self) -> bool {
394        __wbindgen_is_object(self)
395    }
396
397    /// Tests whether this JS value is an instance of Array.
398    #[inline]
399    pub fn is_array(&self) -> bool {
400        __wbindgen_is_array(self)
401    }
402
403    /// Tests whether the type of this JS value is `function`.
404    #[inline]
405    pub fn is_function(&self) -> bool {
406        __wbindgen_is_function(self)
407    }
408
409    /// Tests whether the type of this JS value is `bigint`.
410    #[inline]
411    pub fn is_bigint(&self) -> bool {
412        __wbindgen_is_bigint(self)
413    }
414
415    /// Applies the unary `typeof` JS operator on a `JsValue`.
416    ///
417    /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof)
418    #[inline]
419    pub fn js_typeof(&self) -> JsValue {
420        __wbindgen_typeof(self)
421    }
422
423    /// Applies the binary `in` JS operator on the two `JsValue`s.
424    ///
425    /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/in)
426    #[inline]
427    pub fn js_in(&self, obj: &JsValue) -> bool {
428        __wbindgen_in(self, obj)
429    }
430
431    /// Tests whether the value is ["truthy"].
432    ///
433    /// ["truthy"]: https://developer.mozilla.org/en-US/docs/Glossary/Truthy
434    #[inline]
435    pub fn is_truthy(&self) -> bool {
436        !self.is_falsy()
437    }
438
439    /// Tests whether the value is ["falsy"].
440    ///
441    /// ["falsy"]: https://developer.mozilla.org/en-US/docs/Glossary/Falsy
442    #[inline]
443    pub fn is_falsy(&self) -> bool {
444        __wbindgen_is_falsy(self)
445    }
446
447    /// Get a string representation of the JavaScript object for debugging.
448    fn as_debug_string(&self) -> String {
449        __wbindgen_debug_string(self)
450    }
451
452    /// Compare two `JsValue`s for equality, using the `==` operator in JS.
453    ///
454    /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Equality)
455    #[inline]
456    pub fn loose_eq(&self, other: &Self) -> bool {
457        __wbindgen_jsval_loose_eq(self, other)
458    }
459
460    /// Applies the unary `~` JS operator on a `JsValue`.
461    ///
462    /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_NOT)
463    #[inline]
464    pub fn bit_not(&self) -> JsValue {
465        __wbindgen_bit_not(self)
466    }
467
468    /// Applies the binary `>>>` JS operator on the two `JsValue`s.
469    ///
470    /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Unsigned_right_shift)
471    #[inline]
472    pub fn unsigned_shr(&self, rhs: &Self) -> u32 {
473        __wbindgen_unsigned_shr(self, rhs)
474    }
475
476    /// Applies the binary `/` JS operator on two `JsValue`s, catching and returning any `RangeError` thrown.
477    ///
478    /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Division)
479    #[inline]
480    pub fn checked_div(&self, rhs: &Self) -> Self {
481        __wbindgen_checked_div(self, rhs)
482    }
483
484    /// Applies the binary `**` JS operator on the two `JsValue`s.
485    ///
486    /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Exponentiation)
487    #[inline]
488    pub fn pow(&self, rhs: &Self) -> Self {
489        __wbindgen_pow(self, rhs)
490    }
491
492    /// Applies the binary `<` JS operator on the two `JsValue`s.
493    ///
494    /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Less_than)
495    #[inline]
496    pub fn lt(&self, other: &Self) -> bool {
497        __wbindgen_lt(self, other)
498    }
499
500    /// Applies the binary `<=` JS operator on the two `JsValue`s.
501    ///
502    /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Less_than_or_equal)
503    #[inline]
504    pub fn le(&self, other: &Self) -> bool {
505        __wbindgen_le(self, other)
506    }
507
508    /// Applies the binary `>=` JS operator on the two `JsValue`s.
509    ///
510    /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Greater_than_or_equal)
511    #[inline]
512    pub fn ge(&self, other: &Self) -> bool {
513        __wbindgen_ge(self, other)
514    }
515
516    /// Applies the binary `>` JS operator on the two `JsValue`s.
517    ///
518    /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Greater_than)
519    #[inline]
520    pub fn gt(&self, other: &Self) -> bool {
521        __wbindgen_gt(self, other)
522    }
523
524    /// Applies the unary `+` JS operator on a `JsValue`. Can throw.
525    ///
526    /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Unary_plus)
527    #[inline]
528    pub fn unchecked_into_f64(&self) -> f64 {
529        // Can't use `wbg_cast` here because it expects that the value already has a correct type
530        // and will fail with an assertion error in debug mode.
531        __wbindgen_as_number(self)
532    }
533}
534
535impl PartialEq for JsValue {
536    /// Compares two `JsValue`s for equality, using the `===` operator in JS.
537    ///
538    /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Strict_equality)
539    #[inline]
540    fn eq(&self, other: &Self) -> bool {
541        __wbindgen_jsval_eq(self, other)
542    }
543}
544
545impl PartialEq<bool> for JsValue {
546    #[inline]
547    fn eq(&self, other: &bool) -> bool {
548        self.as_bool() == Some(*other)
549    }
550}
551
552impl PartialEq<str> for JsValue {
553    #[inline]
554    fn eq(&self, other: &str) -> bool {
555        *self == JsValue::from_str(other)
556    }
557}
558
559impl<'a> PartialEq<&'a str> for JsValue {
560    #[inline]
561    fn eq(&self, other: &&'a str) -> bool {
562        <JsValue as PartialEq<str>>::eq(self, other)
563    }
564}
565
566impl PartialEq<String> for JsValue {
567    #[inline]
568    fn eq(&self, other: &String) -> bool {
569        <JsValue as PartialEq<str>>::eq(self, other)
570    }
571}
572impl<'a> PartialEq<&'a String> for JsValue {
573    #[inline]
574    fn eq(&self, other: &&'a String) -> bool {
575        <JsValue as PartialEq<str>>::eq(self, other)
576    }
577}
578
579macro_rules! forward_deref_unop {
580    (impl $imp:ident, $method:ident for $t:ty) => {
581        impl $imp for $t {
582            type Output = <&'static $t as $imp>::Output;
583
584            #[inline]
585            fn $method(self) -> <&'static $t as $imp>::Output {
586                $imp::$method(&self)
587            }
588        }
589    };
590}
591
592macro_rules! forward_deref_binop {
593    (impl $imp:ident, $method:ident for $t:ty) => {
594        impl<'a> $imp<$t> for &'a $t {
595            type Output = <&'static $t as $imp<&'static $t>>::Output;
596
597            #[inline]
598            fn $method(self, other: $t) -> <&'static $t as $imp<&'static $t>>::Output {
599                $imp::$method(self, &other)
600            }
601        }
602
603        impl $imp<&$t> for $t {
604            type Output = <&'static $t as $imp<&'static $t>>::Output;
605
606            #[inline]
607            fn $method(self, other: &$t) -> <&'static $t as $imp<&'static $t>>::Output {
608                $imp::$method(&self, other)
609            }
610        }
611
612        impl $imp<$t> for $t {
613            type Output = <&'static $t as $imp<&'static $t>>::Output;
614
615            #[inline]
616            fn $method(self, other: $t) -> <&'static $t as $imp<&'static $t>>::Output {
617                $imp::$method(&self, &other)
618            }
619        }
620    };
621}
622
623impl Not for &JsValue {
624    type Output = bool;
625
626    /// Applies the `!` JS operator on a `JsValue`.
627    ///
628    /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_NOT)
629    #[inline]
630    fn not(self) -> Self::Output {
631        JsValue::is_falsy(self)
632    }
633}
634
635forward_deref_unop!(impl Not, not for JsValue);
636
637impl TryFrom<JsValue> for f64 {
638    type Error = JsValue;
639
640    /// Applies the unary `+` JS operator on a `JsValue`.
641    /// Returns the numeric result on success, or the JS error value on error.
642    ///
643    /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Unary_plus)
644    #[inline]
645    fn try_from(val: JsValue) -> Result<Self, Self::Error> {
646        f64::try_from(&val)
647    }
648}
649
650impl TryFrom<&JsValue> for f64 {
651    type Error = JsValue;
652
653    /// Applies the unary `+` JS operator on a `JsValue`.
654    /// Returns the numeric result on success, or the JS error value on error.
655    ///
656    /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Unary_plus)
657    #[inline]
658    fn try_from(val: &JsValue) -> Result<Self, Self::Error> {
659        let jsval = __wbindgen_try_into_number(val);
660        match jsval.as_f64() {
661            Some(num) => Ok(num),
662            None => Err(jsval),
663        }
664    }
665}
666
667impl Neg for &JsValue {
668    type Output = JsValue;
669
670    /// Applies the unary `-` JS operator on a `JsValue`.
671    ///
672    /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Unary_negation)
673    #[inline]
674    fn neg(self) -> Self::Output {
675        __wbindgen_neg(self)
676    }
677}
678
679forward_deref_unop!(impl Neg, neg for JsValue);
680
681impl BitAnd for &JsValue {
682    type Output = JsValue;
683
684    /// Applies the binary `&` JS operator on two `JsValue`s.
685    ///
686    /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_AND)
687    #[inline]
688    fn bitand(self, rhs: Self) -> Self::Output {
689        __wbindgen_bit_and(self, rhs)
690    }
691}
692
693forward_deref_binop!(impl BitAnd, bitand for JsValue);
694
695impl BitOr for &JsValue {
696    type Output = JsValue;
697
698    /// Applies the binary `|` JS operator on two `JsValue`s.
699    ///
700    /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_OR)
701    #[inline]
702    fn bitor(self, rhs: Self) -> Self::Output {
703        __wbindgen_bit_or(self, rhs)
704    }
705}
706
707forward_deref_binop!(impl BitOr, bitor for JsValue);
708
709impl BitXor for &JsValue {
710    type Output = JsValue;
711
712    /// Applies the binary `^` JS operator on two `JsValue`s.
713    ///
714    /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_XOR)
715    #[inline]
716    fn bitxor(self, rhs: Self) -> Self::Output {
717        __wbindgen_bit_xor(self, rhs)
718    }
719}
720
721forward_deref_binop!(impl BitXor, bitxor for JsValue);
722
723impl Shl for &JsValue {
724    type Output = JsValue;
725
726    /// Applies the binary `<<` JS operator on two `JsValue`s.
727    ///
728    /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Left_shift)
729    #[inline]
730    fn shl(self, rhs: Self) -> Self::Output {
731        __wbindgen_shl(self, rhs)
732    }
733}
734
735forward_deref_binop!(impl Shl, shl for JsValue);
736
737impl Shr for &JsValue {
738    type Output = JsValue;
739
740    /// Applies the binary `>>` JS operator on two `JsValue`s.
741    ///
742    /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Right_shift)
743    #[inline]
744    fn shr(self, rhs: Self) -> Self::Output {
745        __wbindgen_shr(self, rhs)
746    }
747}
748
749forward_deref_binop!(impl Shr, shr for JsValue);
750
751impl Add for &JsValue {
752    type Output = JsValue;
753
754    /// Applies the binary `+` JS operator on two `JsValue`s.
755    ///
756    /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Addition)
757    #[inline]
758    fn add(self, rhs: Self) -> Self::Output {
759        __wbindgen_add(self, rhs)
760    }
761}
762
763forward_deref_binop!(impl Add, add for JsValue);
764
765impl Sub for &JsValue {
766    type Output = JsValue;
767
768    /// Applies the binary `-` JS operator on two `JsValue`s.
769    ///
770    /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Subtraction)
771    #[inline]
772    fn sub(self, rhs: Self) -> Self::Output {
773        __wbindgen_sub(self, rhs)
774    }
775}
776
777forward_deref_binop!(impl Sub, sub for JsValue);
778
779impl Div for &JsValue {
780    type Output = JsValue;
781
782    /// Applies the binary `/` JS operator on two `JsValue`s.
783    ///
784    /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Division)
785    #[inline]
786    fn div(self, rhs: Self) -> Self::Output {
787        __wbindgen_div(self, rhs)
788    }
789}
790
791forward_deref_binop!(impl Div, div for JsValue);
792
793impl Mul for &JsValue {
794    type Output = JsValue;
795
796    /// Applies the binary `*` JS operator on two `JsValue`s.
797    ///
798    /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Multiplication)
799    #[inline]
800    fn mul(self, rhs: Self) -> Self::Output {
801        __wbindgen_mul(self, rhs)
802    }
803}
804
805forward_deref_binop!(impl Mul, mul for JsValue);
806
807impl Rem for &JsValue {
808    type Output = JsValue;
809
810    /// Applies the binary `%` JS operator on two `JsValue`s.
811    ///
812    /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Remainder)
813    #[inline]
814    fn rem(self, rhs: Self) -> Self::Output {
815        __wbindgen_rem(self, rhs)
816    }
817}
818
819forward_deref_binop!(impl Rem, rem for JsValue);
820
821impl<'a> From<&'a str> for JsValue {
822    #[inline]
823    fn from(s: &'a str) -> JsValue {
824        JsValue::from_str(s)
825    }
826}
827
828impl<T> From<*mut T> for JsValue {
829    #[inline]
830    fn from(s: *mut T) -> JsValue {
831        JsValue::from(s as usize)
832    }
833}
834
835impl<T> From<*const T> for JsValue {
836    #[inline]
837    fn from(s: *const T) -> JsValue {
838        JsValue::from(s as usize)
839    }
840}
841
842impl<T> From<NonNull<T>> for JsValue {
843    #[inline]
844    fn from(s: NonNull<T>) -> JsValue {
845        JsValue::from(s.as_ptr() as usize)
846    }
847}
848
849impl<'a> From<&'a String> for JsValue {
850    #[inline]
851    fn from(s: &'a String) -> JsValue {
852        JsValue::from_str(s)
853    }
854}
855
856impl From<String> for JsValue {
857    #[inline]
858    fn from(s: String) -> JsValue {
859        JsValue::from_str(&s)
860    }
861}
862
863impl TryFrom<JsValue> for String {
864    type Error = JsValue;
865
866    fn try_from(value: JsValue) -> Result<Self, Self::Error> {
867        match value.as_string() {
868            Some(s) => Ok(s),
869            None => Err(value),
870        }
871    }
872}
873
874impl TryFromJsValue for String {
875    type Error = JsValue;
876
877    fn try_from_js_value(value: JsValue) -> Result<Self, Self::Error> {
878        match value.as_string() {
879            Some(s) => Ok(s),
880            None => Err(value),
881        }
882    }
883}
884
885impl From<bool> for JsValue {
886    #[inline]
887    fn from(s: bool) -> JsValue {
888        JsValue::from_bool(s)
889    }
890}
891
892impl<'a, T> From<&'a T> for JsValue
893where
894    T: JsCast,
895{
896    #[inline]
897    fn from(s: &'a T) -> JsValue {
898        s.as_ref().clone()
899    }
900}
901
902impl<T> From<Option<T>> for JsValue
903where
904    JsValue: From<T>,
905{
906    #[inline]
907    fn from(s: Option<T>) -> JsValue {
908        match s {
909            Some(s) => s.into(),
910            None => JsValue::undefined(),
911        }
912    }
913}
914
915impl JsCast for JsValue {
916    // everything is a `JsValue`!
917    #[inline]
918    fn instanceof(_val: &JsValue) -> bool {
919        true
920    }
921    #[inline]
922    fn unchecked_from_js(val: JsValue) -> Self {
923        val
924    }
925    #[inline]
926    fn unchecked_from_js_ref(val: &JsValue) -> &Self {
927        val
928    }
929}
930
931impl AsRef<JsValue> for JsValue {
932    #[inline]
933    fn as_ref(&self) -> &JsValue {
934        self
935    }
936}
937
938macro_rules! numbers {
939    ($($n:ident)*) => ($(
940        impl PartialEq<$n> for JsValue {
941            #[inline]
942            fn eq(&self, other: &$n) -> bool {
943                self.as_f64() == Some(f64::from(*other))
944            }
945        }
946
947        impl From<$n> for JsValue {
948            #[inline]
949            fn from(n: $n) -> JsValue {
950                JsValue::from_f64(n.into())
951            }
952        }
953    )*)
954}
955
956numbers! { i8 u8 i16 u16 i32 u32 f32 f64 }
957
958macro_rules! big_numbers {
959    ($($n:ident)*) => ($(
960        impl PartialEq<$n> for JsValue {
961            #[inline]
962            fn eq(&self, other: &$n) -> bool {
963                self == &JsValue::from(*other)
964            }
965        }
966
967        impl From<$n> for JsValue {
968            #[inline]
969            fn from(arg: $n) -> JsValue {
970                wbg_cast(arg)
971            }
972        }
973    )*)
974}
975
976macro_rules! try_from_for_num64 {
977    ($ty:ty) => {
978        impl TryFrom<JsValue> for $ty {
979            type Error = JsValue;
980
981            #[inline]
982            fn try_from(v: JsValue) -> Result<Self, JsValue> {
983                __wbindgen_bigint_get_as_i64(&v)
984                    // Reinterpret bits; ABI-wise this is safe to do and allows us to avoid
985                    // having separate intrinsics per signed/unsigned types.
986                    .map(|as_i64| as_i64 as Self)
987                    // Double-check that we didn't truncate the bigint to 64 bits.
988                    .filter(|as_self| v == *as_self)
989                    // Not a bigint or not in range.
990                    .ok_or(v)
991            }
992        }
993    };
994}
995
996try_from_for_num64!(i64);
997try_from_for_num64!(u64);
998
999macro_rules! try_from_for_num128 {
1000    ($ty:ty, $hi_ty:ty) => {
1001        impl TryFrom<JsValue> for $ty {
1002            type Error = JsValue;
1003
1004            #[inline]
1005            fn try_from(v: JsValue) -> Result<Self, JsValue> {
1006                // Truncate the bigint to 64 bits, this will give us the lower part.
1007                let lo = match __wbindgen_bigint_get_as_i64(&v) {
1008                    // The lower part must be interpreted as unsigned in both i128 and u128.
1009                    Some(lo) => lo as u64,
1010                    // Not a bigint.
1011                    None => return Err(v),
1012                };
1013                // Now we know it's a bigint, so we can safely use `>> 64n` without
1014                // worrying about a JS exception on type mismatch.
1015                let hi = v >> JsValue::from(64_u64);
1016                // The high part is the one we want checked against a 64-bit range.
1017                // If it fits, then our original number is in the 128-bit range.
1018                let hi = <$hi_ty>::try_from(hi)?;
1019                Ok(Self::from(hi) << 64 | Self::from(lo))
1020            }
1021        }
1022    };
1023}
1024
1025try_from_for_num128!(i128, i64);
1026try_from_for_num128!(u128, u64);
1027
1028big_numbers! { i64 u64 i128 u128 }
1029
1030// `usize` and `isize` have to be treated a bit specially, because we know that
1031// they're 32-bit but the compiler conservatively assumes they might be bigger.
1032// So, we have to manually forward to the `u32`/`i32` versions.
1033impl PartialEq<usize> for JsValue {
1034    #[inline]
1035    fn eq(&self, other: &usize) -> bool {
1036        *self == (*other as u32)
1037    }
1038}
1039
1040impl From<usize> for JsValue {
1041    #[inline]
1042    fn from(n: usize) -> Self {
1043        Self::from(n as u32)
1044    }
1045}
1046
1047impl PartialEq<isize> for JsValue {
1048    #[inline]
1049    fn eq(&self, other: &isize) -> bool {
1050        *self == (*other as i32)
1051    }
1052}
1053
1054impl From<isize> for JsValue {
1055    #[inline]
1056    fn from(n: isize) -> Self {
1057        Self::from(n as i32)
1058    }
1059}
1060
1061// Intrinsics that are simply JS function bindings and can be self-hosted via the macro.
1062#[wasm_bindgen_macro::wasm_bindgen(wasm_bindgen = crate)]
1063extern "C" {
1064    #[wasm_bindgen(js_namespace = Array, js_name = isArray)]
1065    fn __wbindgen_is_array(v: &JsValue) -> bool;
1066
1067    #[wasm_bindgen(js_name = BigInt)]
1068    fn __wbindgen_bigint_from_str(s: &str) -> JsValue;
1069
1070    #[wasm_bindgen(js_name = Symbol)]
1071    fn __wbindgen_symbol_new(description: Option<&str>) -> JsValue;
1072
1073    #[wasm_bindgen(js_name = Error)]
1074    fn __wbindgen_error_new(msg: &str) -> JsValue;
1075
1076    #[wasm_bindgen(js_namespace = JSON, js_name = parse)]
1077    fn __wbindgen_json_parse(json: String) -> JsValue;
1078
1079    #[wasm_bindgen(js_namespace = JSON, js_name = stringify)]
1080    fn __wbindgen_json_serialize(v: &JsValue) -> Option<String>;
1081
1082    #[wasm_bindgen(js_name = Number)]
1083    fn __wbindgen_as_number(v: &JsValue) -> f64;
1084}
1085
1086// Intrinsics which are handled by cli-support but for which we can use
1087// standard wasm-bindgen ABI conversions.
1088#[wasm_bindgen_macro::wasm_bindgen(wasm_bindgen = crate, raw_module = "__wbindgen_placeholder__")]
1089extern "C" {
1090    #[cfg(not(target_feature = "reference-types"))]
1091    fn __wbindgen_externref_heap_live_count() -> u32;
1092
1093    fn __wbindgen_is_null(js: &JsValue) -> bool;
1094    fn __wbindgen_is_undefined(js: &JsValue) -> bool;
1095    fn __wbindgen_is_symbol(js: &JsValue) -> bool;
1096    fn __wbindgen_is_object(js: &JsValue) -> bool;
1097    fn __wbindgen_is_function(js: &JsValue) -> bool;
1098    fn __wbindgen_is_string(js: &JsValue) -> bool;
1099    fn __wbindgen_is_bigint(js: &JsValue) -> bool;
1100    fn __wbindgen_typeof(js: &JsValue) -> JsValue;
1101
1102    fn __wbindgen_in(prop: &JsValue, obj: &JsValue) -> bool;
1103
1104    fn __wbindgen_is_falsy(js: &JsValue) -> bool;
1105    fn __wbindgen_try_into_number(js: &JsValue) -> JsValue;
1106    fn __wbindgen_neg(js: &JsValue) -> JsValue;
1107    fn __wbindgen_bit_and(a: &JsValue, b: &JsValue) -> JsValue;
1108    fn __wbindgen_bit_or(a: &JsValue, b: &JsValue) -> JsValue;
1109    fn __wbindgen_bit_xor(a: &JsValue, b: &JsValue) -> JsValue;
1110    fn __wbindgen_bit_not(js: &JsValue) -> JsValue;
1111    fn __wbindgen_shl(a: &JsValue, b: &JsValue) -> JsValue;
1112    fn __wbindgen_shr(a: &JsValue, b: &JsValue) -> JsValue;
1113    fn __wbindgen_unsigned_shr(a: &JsValue, b: &JsValue) -> u32;
1114    fn __wbindgen_add(a: &JsValue, b: &JsValue) -> JsValue;
1115    fn __wbindgen_sub(a: &JsValue, b: &JsValue) -> JsValue;
1116    fn __wbindgen_div(a: &JsValue, b: &JsValue) -> JsValue;
1117    fn __wbindgen_checked_div(a: &JsValue, b: &JsValue) -> JsValue;
1118    fn __wbindgen_mul(a: &JsValue, b: &JsValue) -> JsValue;
1119    fn __wbindgen_rem(a: &JsValue, b: &JsValue) -> JsValue;
1120    fn __wbindgen_pow(a: &JsValue, b: &JsValue) -> JsValue;
1121    fn __wbindgen_lt(a: &JsValue, b: &JsValue) -> bool;
1122    fn __wbindgen_le(a: &JsValue, b: &JsValue) -> bool;
1123    fn __wbindgen_ge(a: &JsValue, b: &JsValue) -> bool;
1124    fn __wbindgen_gt(a: &JsValue, b: &JsValue) -> bool;
1125
1126    fn __wbindgen_number_get(js: &JsValue) -> Option<f64>;
1127    fn __wbindgen_boolean_get(js: &JsValue) -> Option<bool>;
1128    fn __wbindgen_string_get(js: &JsValue) -> Option<String>;
1129    fn __wbindgen_bigint_get_as_i64(js: &JsValue) -> Option<i64>;
1130
1131    fn __wbindgen_debug_string(js: &JsValue) -> String;
1132
1133    fn __wbindgen_throw(msg: &str) /* -> ! */;
1134    fn __wbindgen_rethrow(js: JsValue) /* -> ! */;
1135
1136    fn __wbindgen_cb_drop(js: &JsValue) -> bool;
1137
1138    fn __wbindgen_jsval_eq(a: &JsValue, b: &JsValue) -> bool;
1139    fn __wbindgen_jsval_loose_eq(a: &JsValue, b: &JsValue) -> bool;
1140
1141    fn __wbindgen_copy_to_typed_array(data: &[u8], js: &JsValue);
1142
1143    fn __wbindgen_init_externref_table();
1144
1145    fn __wbindgen_exports() -> JsValue;
1146    fn __wbindgen_memory() -> JsValue;
1147    fn __wbindgen_module() -> JsValue;
1148    fn __wbindgen_function_table() -> JsValue;
1149}
1150
1151// Intrinsics that have to use raw imports because they're matched by other
1152// parts of the transform codebase instead of just generating JS.
1153externs! {
1154    #[link(wasm_import_module = "__wbindgen_placeholder__")]
1155    extern "C" {
1156        fn __wbindgen_object_clone_ref(idx: u32) -> u32;
1157        fn __wbindgen_object_drop_ref(idx: u32) -> ();
1158
1159        fn __wbindgen_describe(v: u32) -> ();
1160        fn __wbindgen_describe_cast(func: *const (), prims: *const ()) -> *const ();
1161    }
1162}
1163
1164impl Clone for JsValue {
1165    #[inline]
1166    fn clone(&self) -> JsValue {
1167        JsValue::_new(unsafe { __wbindgen_object_clone_ref(self.idx) })
1168    }
1169}
1170
1171impl core::fmt::Debug for JsValue {
1172    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
1173        write!(f, "JsValue({})", self.as_debug_string())
1174    }
1175}
1176
1177impl Drop for JsValue {
1178    #[inline]
1179    fn drop(&mut self) {
1180        unsafe {
1181            // We definitely should never drop anything in the stack area
1182            debug_assert!(self.idx >= JSIDX_OFFSET, "free of stack slot {}", self.idx);
1183
1184            // Otherwise if we're not dropping one of our reserved values,
1185            // actually call the intrinsic. See #1054 for eventually removing
1186            // this branch.
1187            if self.idx >= JSIDX_RESERVED {
1188                __wbindgen_object_drop_ref(self.idx);
1189            }
1190        }
1191    }
1192}
1193
1194impl Default for JsValue {
1195    fn default() -> Self {
1196        Self::UNDEFINED
1197    }
1198}
1199
1200/// Wrapper type for imported statics.
1201///
1202/// This type is used whenever a `static` is imported from a JS module, for
1203/// example this import:
1204///
1205/// ```ignore
1206/// #[wasm_bindgen]
1207/// extern "C" {
1208///     static console: JsValue;
1209/// }
1210/// ```
1211///
1212/// will generate in Rust a value that looks like:
1213///
1214/// ```ignore
1215/// static console: JsStatic<JsValue> = ...;
1216/// ```
1217///
1218/// This type implements `Deref` to the inner type so it's typically used as if
1219/// it were `&T`.
1220#[cfg(feature = "std")]
1221#[deprecated = "use with `#[wasm_bindgen(thread_local_v2)]` instead"]
1222pub struct JsStatic<T: 'static> {
1223    #[doc(hidden)]
1224    pub __inner: &'static std::thread::LocalKey<T>,
1225}
1226
1227#[cfg(feature = "std")]
1228#[allow(deprecated)]
1229#[cfg(not(target_feature = "atomics"))]
1230impl<T: crate::convert::FromWasmAbi + 'static> Deref for JsStatic<T> {
1231    type Target = T;
1232    fn deref(&self) -> &T {
1233        unsafe { self.__inner.with(|ptr| &*(ptr as *const T)) }
1234    }
1235}
1236
1237/// Wrapper type for imported statics.
1238///
1239/// This type is used whenever a `static` is imported from a JS module, for
1240/// example this import:
1241///
1242/// ```ignore
1243/// #[wasm_bindgen]
1244/// extern "C" {
1245///     #[wasm_bindgen(thread_local_v2)]
1246///     static console: JsValue;
1247/// }
1248/// ```
1249///
1250/// will generate in Rust a value that looks like:
1251///
1252/// ```ignore
1253/// static console: JsThreadLocal<JsValue> = ...;
1254/// ```
1255pub struct JsThreadLocal<T: 'static> {
1256    #[doc(hidden)]
1257    #[cfg(not(target_feature = "atomics"))]
1258    pub __inner: &'static __rt::LazyCell<T>,
1259    #[doc(hidden)]
1260    #[cfg(target_feature = "atomics")]
1261    pub __inner: fn() -> *const T,
1262}
1263
1264impl<T> JsThreadLocal<T> {
1265    pub fn with<F, R>(&'static self, f: F) -> R
1266    where
1267        F: FnOnce(&T) -> R,
1268    {
1269        #[cfg(not(target_feature = "atomics"))]
1270        return f(self.__inner);
1271        #[cfg(target_feature = "atomics")]
1272        f(unsafe { &*(self.__inner)() })
1273    }
1274}
1275
1276#[cold]
1277#[inline(never)]
1278#[deprecated(note = "renamed to `throw_str`")]
1279#[doc(hidden)]
1280pub fn throw(s: &str) -> ! {
1281    throw_str(s)
1282}
1283
1284/// Throws a JS exception.
1285///
1286/// This function will throw a JS exception with the message provided. The
1287/// function will not return as the Wasm stack will be popped when the exception
1288/// is thrown.
1289///
1290/// Note that it is very easy to leak memory with this function because this
1291/// function, unlike `panic!` on other platforms, **will not run destructors**.
1292/// It's recommended to return a `Result` where possible to avoid the worry of
1293/// leaks.
1294#[cold]
1295#[inline(never)]
1296pub fn throw_str(s: &str) -> ! {
1297    __wbindgen_throw(s);
1298    unsafe { core::hint::unreachable_unchecked() }
1299}
1300
1301/// Rethrow a JS exception
1302///
1303/// This function will throw a JS exception with the JS value provided. This
1304/// function will not return and the Wasm stack will be popped until the point
1305/// of entry of Wasm itself.
1306///
1307/// Note that it is very easy to leak memory with this function because this
1308/// function, unlike `panic!` on other platforms, **will not run destructors**.
1309/// It's recommended to return a `Result` where possible to avoid the worry of
1310/// leaks.
1311#[cold]
1312#[inline(never)]
1313pub fn throw_val(s: JsValue) -> ! {
1314    __wbindgen_rethrow(s);
1315    unsafe { core::hint::unreachable_unchecked() }
1316}
1317
1318/// Get the count of live `externref`s / `JsValue`s in `wasm-bindgen`'s heap.
1319///
1320/// ## Usage
1321///
1322/// This is intended for debugging and writing tests.
1323///
1324/// To write a test that asserts against unnecessarily keeping `anref`s /
1325/// `JsValue`s alive:
1326///
1327/// * get an initial live count,
1328///
1329/// * perform some series of operations or function calls that should clean up
1330///   after themselves, and should not keep holding onto `externref`s / `JsValue`s
1331///   after completion,
1332///
1333/// * get the final live count,
1334///
1335/// * and assert that the initial and final counts are the same.
1336///
1337/// ## What is Counted
1338///
1339/// Note that this only counts the *owned* `externref`s / `JsValue`s that end up in
1340/// `wasm-bindgen`'s heap. It does not count borrowed `externref`s / `JsValue`s
1341/// that are on its stack.
1342///
1343/// For example, these `JsValue`s are accounted for:
1344///
1345/// ```ignore
1346/// #[wasm_bindgen]
1347/// pub fn my_function(this_is_counted: JsValue) {
1348///     let also_counted = JsValue::from_str("hi");
1349///     assert!(wasm_bindgen::externref_heap_live_count() >= 2);
1350/// }
1351/// ```
1352///
1353/// While this borrowed `JsValue` ends up on the stack, not the heap, and
1354/// therefore is not accounted for:
1355///
1356/// ```ignore
1357/// #[wasm_bindgen]
1358/// pub fn my_other_function(this_is_not_counted: &JsValue) {
1359///     // ...
1360/// }
1361/// ```
1362pub fn externref_heap_live_count() -> u32 {
1363    __wbindgen_externref_heap_live_count()
1364}
1365
1366#[doc(hidden)]
1367pub fn anyref_heap_live_count() -> u32 {
1368    externref_heap_live_count()
1369}
1370
1371/// An extension trait for `Option<T>` and `Result<T, E>` for unwrapping the `T`
1372/// value, or throwing a JS error if it is not available.
1373///
1374/// These methods should have a smaller code size footprint than the normal
1375/// `Option::unwrap` and `Option::expect` methods, but they are specific to
1376/// working with Wasm and JS.
1377///
1378/// On non-wasm32 targets, defaults to the normal unwrap/expect calls.
1379///
1380/// # Example
1381///
1382/// ```
1383/// use wasm_bindgen::prelude::*;
1384///
1385/// // If the value is `Option::Some` or `Result::Ok`, then we just get the
1386/// // contained `T` value.
1387/// let x = Some(42);
1388/// assert_eq!(x.unwrap_throw(), 42);
1389///
1390/// let y: Option<i32> = None;
1391///
1392/// // This call would throw an error to JS!
1393/// //
1394/// //     y.unwrap_throw()
1395/// //
1396/// // And this call would throw an error to JS with a custom error message!
1397/// //
1398/// //     y.expect_throw("woopsie daisy!")
1399/// ```
1400pub trait UnwrapThrowExt<T>: Sized {
1401    /// Unwrap this `Option` or `Result`, but instead of panicking on failure,
1402    /// throw an exception to JavaScript.
1403    #[cfg_attr(
1404        any(
1405            debug_assertions,
1406            not(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))
1407        ),
1408        track_caller
1409    )]
1410    fn unwrap_throw(self) -> T {
1411        if cfg!(all(
1412            debug_assertions,
1413            all(
1414                target_arch = "wasm32",
1415                any(target_os = "unknown", target_os = "none")
1416            )
1417        )) {
1418            let loc = core::panic::Location::caller();
1419            let msg = alloc::format!(
1420                "called `{}::unwrap_throw()` ({}:{}:{})",
1421                core::any::type_name::<Self>(),
1422                loc.file(),
1423                loc.line(),
1424                loc.column()
1425            );
1426            self.expect_throw(&msg)
1427        } else {
1428            self.expect_throw("called `unwrap_throw()`")
1429        }
1430    }
1431
1432    /// Unwrap this container's `T` value, or throw an error to JS with the
1433    /// given message if the `T` value is unavailable (e.g. an `Option<T>` is
1434    /// `None`).
1435    #[cfg_attr(
1436        any(
1437            debug_assertions,
1438            not(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))
1439        ),
1440        track_caller
1441    )]
1442    fn expect_throw(self, message: &str) -> T;
1443}
1444
1445impl<T> UnwrapThrowExt<T> for Option<T> {
1446    fn unwrap_throw(self) -> T {
1447        const MSG: &str = "called `Option::unwrap_throw()` on a `None` value";
1448
1449        if cfg!(all(
1450            target_arch = "wasm32",
1451            any(target_os = "unknown", target_os = "none")
1452        )) {
1453            if let Some(val) = self {
1454                val
1455            } else if cfg!(debug_assertions) {
1456                let loc = core::panic::Location::caller();
1457                let msg =
1458                    alloc::format!("{} ({}:{}:{})", MSG, loc.file(), loc.line(), loc.column(),);
1459
1460                throw_str(&msg)
1461            } else {
1462                throw_str(MSG)
1463            }
1464        } else {
1465            self.expect(MSG)
1466        }
1467    }
1468
1469    fn expect_throw(self, message: &str) -> T {
1470        if cfg!(all(
1471            target_arch = "wasm32",
1472            any(target_os = "unknown", target_os = "none")
1473        )) {
1474            if let Some(val) = self {
1475                val
1476            } else if cfg!(debug_assertions) {
1477                let loc = core::panic::Location::caller();
1478                let msg = alloc::format!(
1479                    "{} ({}:{}:{})",
1480                    message,
1481                    loc.file(),
1482                    loc.line(),
1483                    loc.column(),
1484                );
1485
1486                throw_str(&msg)
1487            } else {
1488                throw_str(message)
1489            }
1490        } else {
1491            self.expect(message)
1492        }
1493    }
1494}
1495
1496impl<T, E> UnwrapThrowExt<T> for Result<T, E>
1497where
1498    E: core::fmt::Debug,
1499{
1500    fn unwrap_throw(self) -> T {
1501        const MSG: &str = "called `Result::unwrap_throw()` on an `Err` value";
1502
1503        if cfg!(all(
1504            target_arch = "wasm32",
1505            any(target_os = "unknown", target_os = "none")
1506        )) {
1507            match self {
1508                Ok(val) => val,
1509                Err(err) => {
1510                    if cfg!(debug_assertions) {
1511                        let loc = core::panic::Location::caller();
1512                        let msg = alloc::format!(
1513                            "{} ({}:{}:{}): {:?}",
1514                            MSG,
1515                            loc.file(),
1516                            loc.line(),
1517                            loc.column(),
1518                            err
1519                        );
1520
1521                        throw_str(&msg)
1522                    } else {
1523                        throw_str(MSG)
1524                    }
1525                }
1526            }
1527        } else {
1528            self.expect(MSG)
1529        }
1530    }
1531
1532    fn expect_throw(self, message: &str) -> T {
1533        if cfg!(all(
1534            target_arch = "wasm32",
1535            any(target_os = "unknown", target_os = "none")
1536        )) {
1537            match self {
1538                Ok(val) => val,
1539                Err(err) => {
1540                    if cfg!(debug_assertions) {
1541                        let loc = core::panic::Location::caller();
1542                        let msg = alloc::format!(
1543                            "{} ({}:{}:{}): {:?}",
1544                            message,
1545                            loc.file(),
1546                            loc.line(),
1547                            loc.column(),
1548                            err
1549                        );
1550
1551                        throw_str(&msg)
1552                    } else {
1553                        throw_str(message)
1554                    }
1555                }
1556            }
1557        } else {
1558            self.expect(message)
1559        }
1560    }
1561}
1562
1563/// Returns a handle to this Wasm instance's `WebAssembly.Module`.
1564/// This is only available when the final Wasm app is built with
1565/// `--target no-modules` or `--target web`.
1566pub fn module() -> JsValue {
1567    __wbindgen_module()
1568}
1569
1570/// Returns a handle to this Wasm instance's `WebAssembly.Instance.prototype.exports`
1571pub fn exports() -> JsValue {
1572    __wbindgen_exports()
1573}
1574
1575/// Returns a handle to this Wasm instance's `WebAssembly.Memory`
1576pub fn memory() -> JsValue {
1577    __wbindgen_memory()
1578}
1579
1580/// Returns a handle to this Wasm instance's `WebAssembly.Table` which is the
1581/// indirect function table used by Rust
1582pub fn function_table() -> JsValue {
1583    __wbindgen_function_table()
1584}
1585
1586/// A wrapper type around slices and vectors for binding the `Uint8ClampedArray`
1587/// array in JS.
1588///
1589/// If you need to invoke a JS API which must take `Uint8ClampedArray` array,
1590/// then you can define it as taking one of these types:
1591///
1592/// * `Clamped<&[u8]>`
1593/// * `Clamped<&mut [u8]>`
1594/// * `Clamped<Vec<u8>>`
1595///
1596/// All of these types will show up as `Uint8ClampedArray` in JS and will have
1597/// different forms of ownership in Rust.
1598#[derive(Copy, Clone, PartialEq, Debug, Eq)]
1599pub struct Clamped<T>(pub T);
1600
1601impl<T> Deref for Clamped<T> {
1602    type Target = T;
1603
1604    fn deref(&self) -> &T {
1605        &self.0
1606    }
1607}
1608
1609impl<T> DerefMut for Clamped<T> {
1610    fn deref_mut(&mut self) -> &mut T {
1611        &mut self.0
1612    }
1613}
1614
1615/// Convenience type for use on exported `fn() -> Result<T, JsError>` functions, where you wish to
1616/// throw a JavaScript `Error` object.
1617///
1618/// You can get wasm_bindgen to throw basic errors by simply returning
1619/// `Err(JsError::new("message"))` from such a function.
1620///
1621/// For more complex error handling, `JsError` implements `From<T> where T: std::error::Error` by
1622/// converting it to a string, so you can use it with `?`. Many Rust error types already do this,
1623/// and you can use [`thiserror`](https://crates.io/crates/thiserror) to derive Display
1624/// implementations easily or use any number of boxed error types that implement it already.
1625///
1626///
1627/// To allow JavaScript code to catch only your errors, you may wish to add a subclass of `Error`
1628/// in a JS module, and then implement `Into<JsValue>` directly on a type and instantiate that
1629/// subclass. In that case, you would not need `JsError` at all.
1630///
1631/// ### Basic example
1632///
1633/// ```rust,no_run
1634/// use wasm_bindgen::prelude::*;
1635///
1636/// #[wasm_bindgen]
1637/// pub fn throwing_function() -> Result<(), JsError> {
1638///     Err(JsError::new("message"))
1639/// }
1640/// ```
1641///
1642/// ### Complex Example
1643///
1644/// ```rust,no_run
1645/// use wasm_bindgen::prelude::*;
1646///
1647/// #[derive(Debug, Clone)]
1648/// enum MyErrorType {
1649///     SomeError,
1650/// }
1651///
1652/// use core::fmt;
1653/// impl std::error::Error for MyErrorType {}
1654/// impl fmt::Display for MyErrorType {
1655///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1656///         write!(f, "display implementation becomes the error message")
1657///     }
1658/// }
1659///
1660/// fn internal_api() -> Result<(), MyErrorType> {
1661///     Err(MyErrorType::SomeError)
1662/// }
1663///
1664/// #[wasm_bindgen]
1665/// pub fn throwing_function() -> Result<(), JsError> {
1666///     internal_api()?;
1667///     Ok(())
1668/// }
1669///
1670/// ```
1671#[derive(Clone, Debug)]
1672pub struct JsError {
1673    value: JsValue,
1674}
1675
1676impl JsError {
1677    /// Construct a JavaScript `Error` object with a string message
1678    #[inline]
1679    pub fn new(s: &str) -> JsError {
1680        Self {
1681            value: __wbindgen_error_new(s),
1682        }
1683    }
1684}
1685
1686#[cfg(feature = "std")]
1687impl<E> From<E> for JsError
1688where
1689    E: std::error::Error,
1690{
1691    fn from(error: E) -> Self {
1692        use std::string::ToString;
1693
1694        JsError::new(&error.to_string())
1695    }
1696}
1697
1698impl From<JsError> for JsValue {
1699    fn from(error: JsError) -> Self {
1700        error.value
1701    }
1702}
1703
1704impl<T: VectorIntoWasmAbi> From<Box<[T]>> for JsValue {
1705    fn from(vector: Box<[T]>) -> Self {
1706        wbg_cast(vector)
1707    }
1708}
1709
1710impl<T: VectorIntoWasmAbi> From<Clamped<Box<[T]>>> for JsValue {
1711    fn from(vector: Clamped<Box<[T]>>) -> Self {
1712        wbg_cast(vector)
1713    }
1714}
1715
1716impl<T: VectorIntoWasmAbi> From<Vec<T>> for JsValue {
1717    fn from(vector: Vec<T>) -> Self {
1718        JsValue::from(vector.into_boxed_slice())
1719    }
1720}
1721
1722impl<T: VectorIntoWasmAbi> From<Clamped<Vec<T>>> for JsValue {
1723    fn from(vector: Clamped<Vec<T>>) -> Self {
1724        JsValue::from(Clamped(vector.0.into_boxed_slice()))
1725    }
1726}