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