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