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