Skip to main content

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