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