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