Skip to main content

wasm_bindgen/
lib.rs

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