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