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