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