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#![no_std]
9#![cfg_attr(
10    wasm_bindgen_unstable_test_coverage,
11    feature(coverage_attribute, allow_internal_unstable),
12    allow(internal_features)
13)]
14#![cfg_attr(
15    all(not(feature = "std"), target_feature = "atomics"),
16    feature(thread_local, allow_internal_unstable),
17    allow(internal_features)
18)]
19#![allow(coherence_leak_check)]
20#![doc(html_root_url = "https://docs.rs/wasm-bindgen/0.2")]
21
22extern crate alloc;
23
24use alloc::boxed::Box;
25use alloc::string::String;
26use alloc::vec::Vec;
27use core::convert::TryFrom;
28use core::marker;
29use core::mem;
30use core::ops::{
31    Add, BitAnd, BitOr, BitXor, Deref, DerefMut, Div, Mul, Neg, Not, Rem, Shl, Shr, Sub,
32};
33use core::ptr::NonNull;
34
35use crate::convert::{FromWasmAbi, TryFromJsValue, WasmRet, WasmSlice};
36
37macro_rules! if_std {
38    ($($i:item)*) => ($(
39        #[cfg(feature = "std")] $i
40    )*)
41}
42
43macro_rules! externs {
44    ($(#[$attr:meta])* extern "C" { $(fn $name:ident($($args:tt)*) -> $ret:ty;)* }) => (
45        #[cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))]
46        $(#[$attr])*
47        extern "C" {
48            $(fn $name($($args)*) -> $ret;)*
49        }
50
51        $(
52            #[cfg(not(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none"))))]
53            #[allow(unused_variables)]
54            unsafe extern fn $name($($args)*) -> $ret {
55                panic!("function not implemented on non-wasm32 targets")
56            }
57        )*
58    )
59}
60
61/// A module which is typically glob imported.
62///
63/// ```
64/// use wasm_bindgen::prelude::*;
65/// ```
66pub mod prelude {
67    pub use crate::closure::Closure;
68    pub use crate::JsCast;
69    pub use crate::JsValue;
70    pub use crate::UnwrapThrowExt;
71    #[doc(hidden)]
72    pub use wasm_bindgen_macro::__wasm_bindgen_class_marker;
73    pub use wasm_bindgen_macro::wasm_bindgen;
74
75    pub use crate::JsError;
76}
77
78pub use wasm_bindgen_macro::link_to;
79
80pub mod closure;
81pub mod convert;
82pub mod describe;
83mod externref;
84mod link;
85
86mod cast;
87pub use crate::cast::{JsCast, JsObject};
88
89if_std! {
90    extern crate std;
91    use std::prelude::v1::*;
92    mod cache;
93    pub use cache::intern::{intern, unintern};
94}
95
96/// Representation of an object owned by JS.
97///
98/// A `JsValue` doesn't actually live in Rust right now but actually in a table
99/// owned by the `wasm-bindgen` generated JS glue code. Eventually the ownership
100/// will transfer into Wasm directly and this will likely become more efficient,
101/// but for now it may be slightly slow.
102pub struct JsValue {
103    idx: u32,
104    _marker: marker::PhantomData<*mut u8>, // not at all threadsafe
105}
106
107const JSIDX_OFFSET: u32 = 128; // keep in sync with js/mod.rs
108const JSIDX_UNDEFINED: u32 = JSIDX_OFFSET;
109const JSIDX_NULL: u32 = JSIDX_OFFSET + 1;
110const JSIDX_TRUE: u32 = JSIDX_OFFSET + 2;
111const JSIDX_FALSE: u32 = JSIDX_OFFSET + 3;
112const JSIDX_RESERVED: u32 = JSIDX_OFFSET + 4;
113
114impl JsValue {
115    /// The `null` JS value constant.
116    pub const NULL: JsValue = JsValue::_new(JSIDX_NULL);
117
118    /// The `undefined` JS value constant.
119    pub const UNDEFINED: JsValue = JsValue::_new(JSIDX_UNDEFINED);
120
121    /// The `true` JS value constant.
122    pub const TRUE: JsValue = JsValue::_new(JSIDX_TRUE);
123
124    /// The `false` JS value constant.
125    pub const FALSE: JsValue = JsValue::_new(JSIDX_FALSE);
126
127    #[inline]
128    const fn _new(idx: u32) -> JsValue {
129        JsValue {
130            idx,
131            _marker: marker::PhantomData,
132        }
133    }
134
135    /// Creates a new JS value which is a string.
136    ///
137    /// The utf-8 string provided is copied to the JS heap and the string will
138    /// be owned by the JS garbage collector.
139    #[allow(clippy::should_implement_trait)] // cannot fix without breaking change
140    #[inline]
141    pub fn from_str(s: &str) -> JsValue {
142        unsafe { JsValue::_new(__wbindgen_string_new(s.as_ptr(), s.len())) }
143    }
144
145    /// Creates a new JS value which is a number.
146    ///
147    /// This function creates a JS value representing a number (a heap
148    /// allocated number) and returns a handle to the JS version of it.
149    #[inline]
150    pub fn from_f64(n: f64) -> JsValue {
151        unsafe { JsValue::_new(__wbindgen_number_new(n)) }
152    }
153
154    /// Creates a new JS value which is a bigint from a string representing a number.
155    ///
156    /// This function creates a JS value representing a bigint (a heap
157    /// allocated large integer) and returns a handle to the JS version of it.
158    #[inline]
159    pub fn bigint_from_str(s: &str) -> JsValue {
160        unsafe { JsValue::_new(__wbindgen_bigint_from_str(s.as_ptr(), s.len())) }
161    }
162
163    /// Creates a new JS value which is a boolean.
164    ///
165    /// This function creates a JS object representing a boolean (a heap
166    /// allocated boolean) and returns a handle to the JS version of it.
167    #[inline]
168    pub const fn from_bool(b: bool) -> JsValue {
169        if b {
170            JsValue::TRUE
171        } else {
172            JsValue::FALSE
173        }
174    }
175
176    /// Creates a new JS value representing `undefined`.
177    #[inline]
178    pub const fn undefined() -> JsValue {
179        JsValue::UNDEFINED
180    }
181
182    /// Creates a new JS value representing `null`.
183    #[inline]
184    pub const fn null() -> JsValue {
185        JsValue::NULL
186    }
187
188    /// Creates a new JS symbol with the optional description specified.
189    ///
190    /// This function will invoke the `Symbol` constructor in JS and return the
191    /// JS object corresponding to the symbol created.
192    pub fn symbol(description: Option<&str>) -> JsValue {
193        unsafe {
194            match description {
195                Some(description) => JsValue::_new(__wbindgen_symbol_named_new(
196                    description.as_ptr(),
197                    description.len(),
198                )),
199                None => JsValue::_new(__wbindgen_symbol_anonymous_new()),
200            }
201        }
202    }
203
204    /// Creates a new `JsValue` from the JSON serialization of the object `t`
205    /// provided.
206    ///
207    /// **This function is deprecated**, due to [creating a dependency cycle in
208    /// some circumstances][dep-cycle-issue]. Use [`serde-wasm-bindgen`] or
209    /// [`gloo_utils::format::JsValueSerdeExt`] instead.
210    ///
211    /// [dep-cycle-issue]: https://github.com/rustwasm/wasm-bindgen/issues/2770
212    /// [`serde-wasm-bindgen`]: https://docs.rs/serde-wasm-bindgen
213    /// [`gloo_utils::format::JsValueSerdeExt`]: https://docs.rs/gloo-utils/latest/gloo_utils/format/trait.JsValueSerdeExt.html
214    ///
215    /// This function will serialize the provided value `t` to a JSON string,
216    /// send the JSON string to JS, parse it into a JS object, and then return
217    /// a handle to the JS object. This is unlikely to be super speedy so it's
218    /// not recommended for large payloads, but it's a nice to have in some
219    /// situations!
220    ///
221    /// Usage of this API requires activating the `serde-serialize` feature of
222    /// the `wasm-bindgen` crate.
223    ///
224    /// # Errors
225    ///
226    /// Returns any error encountered when serializing `T` into JSON.
227    #[cfg(feature = "serde-serialize")]
228    #[deprecated = "causes dependency cycles, use `serde-wasm-bindgen` or `gloo_utils::format::JsValueSerdeExt` instead"]
229    pub fn from_serde<T>(t: &T) -> serde_json::Result<JsValue>
230    where
231        T: serde::ser::Serialize + ?Sized,
232    {
233        let s = serde_json::to_string(t)?;
234        unsafe { Ok(JsValue::_new(__wbindgen_json_parse(s.as_ptr(), s.len()))) }
235    }
236
237    /// Invokes `JSON.stringify` on this value and then parses the resulting
238    /// JSON into an arbitrary Rust value.
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 first call `JSON.stringify` on the `JsValue` itself.
249    /// The resulting string is then passed into Rust which then parses it as
250    /// JSON into the resulting value.
251    ///
252    /// Usage of this API requires activating the `serde-serialize` feature of
253    /// the `wasm-bindgen` crate.
254    ///
255    /// # Errors
256    ///
257    /// Returns any error encountered when parsing the JSON into a `T`.
258    #[cfg(feature = "serde-serialize")]
259    #[deprecated = "causes dependency cycles, use `serde-wasm-bindgen` or `gloo_utils::format::JsValueSerdeExt` instead"]
260    pub fn into_serde<T>(&self) -> serde_json::Result<T>
261    where
262        T: for<'a> serde::de::Deserialize<'a>,
263    {
264        unsafe {
265            let ret = __wbindgen_json_serialize(self.idx);
266            let s = String::from_abi(ret);
267            serde_json::from_str(&s)
268        }
269    }
270
271    /// Returns the `f64` value of this JS value if it's an instance of a
272    /// number.
273    ///
274    /// If this JS value is not an instance of a number then this returns
275    /// `None`.
276    #[inline]
277    pub fn as_f64(&self) -> Option<f64> {
278        unsafe { __wbindgen_number_get(self.idx).join() }
279    }
280
281    /// Tests whether this JS value is a JS string.
282    #[inline]
283    pub fn is_string(&self) -> bool {
284        unsafe { __wbindgen_is_string(self.idx) == 1 }
285    }
286
287    /// If this JS value is a string value, this function copies the JS string
288    /// value into Wasm linear memory, encoded as UTF-8, and returns it as a
289    /// Rust `String`.
290    ///
291    /// To avoid the copying and re-encoding, consider the
292    /// `JsString::try_from()` function from [js-sys](https://docs.rs/js-sys)
293    /// instead.
294    ///
295    /// If this JS value is not an instance of a string or if it's not valid
296    /// utf-8 then this returns `None`.
297    ///
298    /// # UTF-16 vs UTF-8
299    ///
300    /// JavaScript strings in general are encoded as UTF-16, but Rust strings
301    /// are encoded as UTF-8. This can cause the Rust string to look a bit
302    /// different than the JS string sometimes. For more details see the
303    /// [documentation about the `str` type][caveats] which contains a few
304    /// caveats about the encodings.
305    ///
306    /// [caveats]: https://rustwasm.github.io/docs/wasm-bindgen/reference/types/str.html
307    #[inline]
308    pub fn as_string(&self) -> Option<String> {
309        unsafe { FromWasmAbi::from_abi(__wbindgen_string_get(self.idx)) }
310    }
311
312    /// Returns the `bool` value of this JS value if it's an instance of a
313    /// boolean.
314    ///
315    /// If this JS value is not an instance of a boolean then this returns
316    /// `None`.
317    #[inline]
318    pub fn as_bool(&self) -> Option<bool> {
319        unsafe {
320            match __wbindgen_boolean_get(self.idx) {
321                0 => Some(false),
322                1 => Some(true),
323                _ => None,
324            }
325        }
326    }
327
328    /// Tests whether this JS value is `null`
329    #[inline]
330    pub fn is_null(&self) -> bool {
331        unsafe { __wbindgen_is_null(self.idx) == 1 }
332    }
333
334    /// Tests whether this JS value is `undefined`
335    #[inline]
336    pub fn is_undefined(&self) -> bool {
337        unsafe { __wbindgen_is_undefined(self.idx) == 1 }
338    }
339
340    /// Tests whether the type of this JS value is `symbol`
341    #[inline]
342    pub fn is_symbol(&self) -> bool {
343        unsafe { __wbindgen_is_symbol(self.idx) == 1 }
344    }
345
346    /// Tests whether `typeof self == "object" && self !== null`.
347    #[inline]
348    pub fn is_object(&self) -> bool {
349        unsafe { __wbindgen_is_object(self.idx) == 1 }
350    }
351
352    /// Tests whether this JS value is an instance of Array.
353    #[inline]
354    pub fn is_array(&self) -> bool {
355        unsafe { __wbindgen_is_array(self.idx) == 1 }
356    }
357
358    /// Tests whether the type of this JS value is `function`.
359    #[inline]
360    pub fn is_function(&self) -> bool {
361        unsafe { __wbindgen_is_function(self.idx) == 1 }
362    }
363
364    /// Tests whether the type of this JS value is `bigint`.
365    #[inline]
366    pub fn is_bigint(&self) -> bool {
367        unsafe { __wbindgen_is_bigint(self.idx) == 1 }
368    }
369
370    /// Applies the unary `typeof` JS operator on a `JsValue`.
371    ///
372    /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof)
373    #[inline]
374    pub fn js_typeof(&self) -> JsValue {
375        unsafe { JsValue::_new(__wbindgen_typeof(self.idx)) }
376    }
377
378    /// Applies the binary `in` JS operator on the two `JsValue`s.
379    ///
380    /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/in)
381    #[inline]
382    pub fn js_in(&self, obj: &JsValue) -> bool {
383        unsafe { __wbindgen_in(self.idx, obj.idx) == 1 }
384    }
385
386    /// Tests whether the value is ["truthy"].
387    ///
388    /// ["truthy"]: https://developer.mozilla.org/en-US/docs/Glossary/Truthy
389    #[inline]
390    pub fn is_truthy(&self) -> bool {
391        !self.is_falsy()
392    }
393
394    /// Tests whether the value is ["falsy"].
395    ///
396    /// ["falsy"]: https://developer.mozilla.org/en-US/docs/Glossary/Falsy
397    #[inline]
398    pub fn is_falsy(&self) -> bool {
399        unsafe { __wbindgen_is_falsy(self.idx) == 1 }
400    }
401
402    /// Get a string representation of the JavaScript object for debugging.
403    #[cfg(feature = "std")]
404    fn as_debug_string(&self) -> String {
405        unsafe {
406            let mut ret = [0; 2];
407            __wbindgen_debug_string(&mut ret, self.idx);
408            let data = Vec::from_raw_parts(ret[0] as *mut u8, ret[1], ret[1]);
409            String::from_utf8_unchecked(data)
410        }
411    }
412
413    /// Compare two `JsValue`s for equality, using the `==` operator in JS.
414    ///
415    /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Equality)
416    #[inline]
417    pub fn loose_eq(&self, other: &Self) -> bool {
418        unsafe { __wbindgen_jsval_loose_eq(self.idx, other.idx) != 0 }
419    }
420
421    /// Applies the unary `~` JS operator on a `JsValue`.
422    ///
423    /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_NOT)
424    #[inline]
425    pub fn bit_not(&self) -> JsValue {
426        unsafe { JsValue::_new(__wbindgen_bit_not(self.idx)) }
427    }
428
429    /// Applies the binary `>>>` JS operator on the two `JsValue`s.
430    ///
431    /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Unsigned_right_shift)
432    #[inline]
433    pub fn unsigned_shr(&self, rhs: &Self) -> u32 {
434        unsafe { __wbindgen_unsigned_shr(self.idx, rhs.idx) }
435    }
436
437    /// Applies the binary `/` JS operator on two `JsValue`s, catching and returning any `RangeError` thrown.
438    ///
439    /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Division)
440    #[inline]
441    pub fn checked_div(&self, rhs: &Self) -> Self {
442        unsafe { JsValue::_new(__wbindgen_checked_div(self.idx, rhs.idx)) }
443    }
444
445    /// Applies the binary `**` JS operator on the two `JsValue`s.
446    ///
447    /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Exponentiation)
448    #[inline]
449    pub fn pow(&self, rhs: &Self) -> Self {
450        unsafe { JsValue::_new(__wbindgen_pow(self.idx, rhs.idx)) }
451    }
452
453    /// Applies the binary `<` JS operator on the two `JsValue`s.
454    ///
455    /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Less_than)
456    #[inline]
457    pub fn lt(&self, other: &Self) -> bool {
458        unsafe { __wbindgen_lt(self.idx, other.idx) == 1 }
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/Less_than_or_equal)
464    #[inline]
465    pub fn le(&self, other: &Self) -> bool {
466        unsafe { __wbindgen_le(self.idx, other.idx) == 1 }
467    }
468
469    /// Applies the binary `>=` JS operator on the two `JsValue`s.
470    ///
471    /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Greater_than_or_equal)
472    #[inline]
473    pub fn ge(&self, other: &Self) -> bool {
474        unsafe { __wbindgen_ge(self.idx, other.idx) == 1 }
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/Greater_than)
480    #[inline]
481    pub fn gt(&self, other: &Self) -> bool {
482        unsafe { __wbindgen_gt(self.idx, other.idx) == 1 }
483    }
484
485    /// Applies the unary `+` JS operator on a `JsValue`. Can throw.
486    ///
487    /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Unary_plus)
488    #[inline]
489    pub fn unchecked_into_f64(&self) -> f64 {
490        unsafe { __wbindgen_as_number(self.idx) }
491    }
492}
493
494impl PartialEq for JsValue {
495    /// Compares two `JsValue`s for equality, using the `===` operator in JS.
496    ///
497    /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Strict_equality)
498    #[inline]
499    fn eq(&self, other: &Self) -> bool {
500        unsafe { __wbindgen_jsval_eq(self.idx, other.idx) != 0 }
501    }
502}
503
504impl PartialEq<bool> for JsValue {
505    #[inline]
506    fn eq(&self, other: &bool) -> bool {
507        self.as_bool() == Some(*other)
508    }
509}
510
511impl PartialEq<str> for JsValue {
512    #[inline]
513    fn eq(&self, other: &str) -> bool {
514        *self == JsValue::from_str(other)
515    }
516}
517
518impl<'a> PartialEq<&'a str> for JsValue {
519    #[inline]
520    fn eq(&self, other: &&'a str) -> bool {
521        <JsValue as PartialEq<str>>::eq(self, other)
522    }
523}
524
525impl PartialEq<String> for JsValue {
526    #[inline]
527    fn eq(&self, other: &String) -> bool {
528        <JsValue as PartialEq<str>>::eq(self, other)
529    }
530}
531impl<'a> PartialEq<&'a String> for JsValue {
532    #[inline]
533    fn eq(&self, other: &&'a String) -> bool {
534        <JsValue as PartialEq<str>>::eq(self, other)
535    }
536}
537
538macro_rules! forward_deref_unop {
539    (impl $imp:ident, $method:ident for $t:ty) => {
540        impl $imp for $t {
541            type Output = <&'static $t as $imp>::Output;
542
543            #[inline]
544            fn $method(self) -> <&'static $t as $imp>::Output {
545                $imp::$method(&self)
546            }
547        }
548    };
549}
550
551macro_rules! forward_deref_binop {
552    (impl $imp:ident, $method:ident for $t:ty) => {
553        impl<'a> $imp<$t> for &'a $t {
554            type Output = <&'static $t as $imp<&'static $t>>::Output;
555
556            #[inline]
557            fn $method(self, other: $t) -> <&'static $t as $imp<&'static $t>>::Output {
558                $imp::$method(self, &other)
559            }
560        }
561
562        impl $imp<&$t> for $t {
563            type Output = <&'static $t as $imp<&'static $t>>::Output;
564
565            #[inline]
566            fn $method(self, other: &$t) -> <&'static $t as $imp<&'static $t>>::Output {
567                $imp::$method(&self, other)
568            }
569        }
570
571        impl $imp<$t> for $t {
572            type Output = <&'static $t as $imp<&'static $t>>::Output;
573
574            #[inline]
575            fn $method(self, other: $t) -> <&'static $t as $imp<&'static $t>>::Output {
576                $imp::$method(&self, &other)
577            }
578        }
579    };
580}
581
582impl Not for &JsValue {
583    type Output = bool;
584
585    /// Applies the `!` JS operator on a `JsValue`.
586    ///
587    /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_NOT)
588    #[inline]
589    fn not(self) -> Self::Output {
590        JsValue::is_falsy(self)
591    }
592}
593
594forward_deref_unop!(impl Not, not for JsValue);
595
596impl TryFrom<JsValue> for f64 {
597    type Error = JsValue;
598
599    /// Applies the unary `+` JS operator on a `JsValue`.
600    /// Returns the numeric result on success, or the JS error value on error.
601    ///
602    /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Unary_plus)
603    #[inline]
604    fn try_from(val: JsValue) -> Result<Self, Self::Error> {
605        f64::try_from(&val)
606    }
607}
608
609impl TryFrom<&JsValue> for f64 {
610    type Error = JsValue;
611
612    /// Applies the unary `+` JS operator on a `JsValue`.
613    /// Returns the numeric result on success, or the JS error value on error.
614    ///
615    /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Unary_plus)
616    #[inline]
617    fn try_from(val: &JsValue) -> Result<Self, Self::Error> {
618        let jsval = unsafe { JsValue::_new(__wbindgen_try_into_number(val.idx)) };
619        match jsval.as_f64() {
620            Some(num) => Ok(num),
621            None => Err(jsval),
622        }
623    }
624}
625
626impl Neg for &JsValue {
627    type Output = JsValue;
628
629    /// Applies the unary `-` JS operator on a `JsValue`.
630    ///
631    /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Unary_negation)
632    #[inline]
633    fn neg(self) -> Self::Output {
634        unsafe { JsValue::_new(__wbindgen_neg(self.idx)) }
635    }
636}
637
638forward_deref_unop!(impl Neg, neg for JsValue);
639
640impl BitAnd for &JsValue {
641    type Output = JsValue;
642
643    /// Applies the binary `&` JS operator on two `JsValue`s.
644    ///
645    /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_AND)
646    #[inline]
647    fn bitand(self, rhs: Self) -> Self::Output {
648        unsafe { JsValue::_new(__wbindgen_bit_and(self.idx, rhs.idx)) }
649    }
650}
651
652forward_deref_binop!(impl BitAnd, bitand for JsValue);
653
654impl BitOr for &JsValue {
655    type Output = JsValue;
656
657    /// Applies the binary `|` JS operator on two `JsValue`s.
658    ///
659    /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_OR)
660    #[inline]
661    fn bitor(self, rhs: Self) -> Self::Output {
662        unsafe { JsValue::_new(__wbindgen_bit_or(self.idx, rhs.idx)) }
663    }
664}
665
666forward_deref_binop!(impl BitOr, bitor for JsValue);
667
668impl BitXor for &JsValue {
669    type Output = JsValue;
670
671    /// Applies the binary `^` JS operator on two `JsValue`s.
672    ///
673    /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_XOR)
674    #[inline]
675    fn bitxor(self, rhs: Self) -> Self::Output {
676        unsafe { JsValue::_new(__wbindgen_bit_xor(self.idx, rhs.idx)) }
677    }
678}
679
680forward_deref_binop!(impl BitXor, bitxor for JsValue);
681
682impl Shl for &JsValue {
683    type Output = JsValue;
684
685    /// Applies the binary `<<` JS operator on two `JsValue`s.
686    ///
687    /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Left_shift)
688    #[inline]
689    fn shl(self, rhs: Self) -> Self::Output {
690        unsafe { JsValue::_new(__wbindgen_shl(self.idx, rhs.idx)) }
691    }
692}
693
694forward_deref_binop!(impl Shl, shl for JsValue);
695
696impl Shr for &JsValue {
697    type Output = JsValue;
698
699    /// Applies the binary `>>` JS operator on two `JsValue`s.
700    ///
701    /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Right_shift)
702    #[inline]
703    fn shr(self, rhs: Self) -> Self::Output {
704        unsafe { JsValue::_new(__wbindgen_shr(self.idx, rhs.idx)) }
705    }
706}
707
708forward_deref_binop!(impl Shr, shr for JsValue);
709
710impl Add for &JsValue {
711    type Output = JsValue;
712
713    /// Applies the binary `+` JS operator on two `JsValue`s.
714    ///
715    /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Addition)
716    #[inline]
717    fn add(self, rhs: Self) -> Self::Output {
718        unsafe { JsValue::_new(__wbindgen_add(self.idx, rhs.idx)) }
719    }
720}
721
722forward_deref_binop!(impl Add, add for JsValue);
723
724impl Sub for &JsValue {
725    type Output = JsValue;
726
727    /// Applies the binary `-` JS operator on two `JsValue`s.
728    ///
729    /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Subtraction)
730    #[inline]
731    fn sub(self, rhs: Self) -> Self::Output {
732        unsafe { JsValue::_new(__wbindgen_sub(self.idx, rhs.idx)) }
733    }
734}
735
736forward_deref_binop!(impl Sub, sub for JsValue);
737
738impl Div for &JsValue {
739    type Output = JsValue;
740
741    /// Applies the binary `/` JS operator on two `JsValue`s.
742    ///
743    /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Division)
744    #[inline]
745    fn div(self, rhs: Self) -> Self::Output {
746        unsafe { JsValue::_new(__wbindgen_div(self.idx, rhs.idx)) }
747    }
748}
749
750forward_deref_binop!(impl Div, div for JsValue);
751
752impl Mul for &JsValue {
753    type Output = JsValue;
754
755    /// Applies the binary `*` JS operator on two `JsValue`s.
756    ///
757    /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Multiplication)
758    #[inline]
759    fn mul(self, rhs: Self) -> Self::Output {
760        unsafe { JsValue::_new(__wbindgen_mul(self.idx, rhs.idx)) }
761    }
762}
763
764forward_deref_binop!(impl Mul, mul for JsValue);
765
766impl Rem for &JsValue {
767    type Output = JsValue;
768
769    /// Applies the binary `%` JS operator on two `JsValue`s.
770    ///
771    /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Remainder)
772    #[inline]
773    fn rem(self, rhs: Self) -> Self::Output {
774        unsafe { JsValue::_new(__wbindgen_rem(self.idx, rhs.idx)) }
775    }
776}
777
778forward_deref_binop!(impl Rem, rem for JsValue);
779
780impl<'a> From<&'a str> for JsValue {
781    #[inline]
782    fn from(s: &'a str) -> JsValue {
783        JsValue::from_str(s)
784    }
785}
786
787impl<T> From<*mut T> for JsValue {
788    #[inline]
789    fn from(s: *mut T) -> JsValue {
790        JsValue::from(s as usize)
791    }
792}
793
794impl<T> From<*const T> for JsValue {
795    #[inline]
796    fn from(s: *const T) -> JsValue {
797        JsValue::from(s as usize)
798    }
799}
800
801impl<T> From<NonNull<T>> for JsValue {
802    #[inline]
803    fn from(s: NonNull<T>) -> JsValue {
804        JsValue::from(s.as_ptr() as usize)
805    }
806}
807
808impl<'a> From<&'a String> for JsValue {
809    #[inline]
810    fn from(s: &'a String) -> JsValue {
811        JsValue::from_str(s)
812    }
813}
814
815impl From<String> for JsValue {
816    #[inline]
817    fn from(s: String) -> JsValue {
818        JsValue::from_str(&s)
819    }
820}
821
822impl TryFrom<JsValue> for String {
823    type Error = JsValue;
824
825    fn try_from(value: JsValue) -> Result<Self, Self::Error> {
826        match value.as_string() {
827            Some(s) => Ok(s),
828            None => Err(value),
829        }
830    }
831}
832
833impl TryFromJsValue for String {
834    type Error = JsValue;
835
836    fn try_from_js_value(value: JsValue) -> Result<Self, Self::Error> {
837        match value.as_string() {
838            Some(s) => Ok(s),
839            None => Err(value),
840        }
841    }
842}
843
844impl From<bool> for JsValue {
845    #[inline]
846    fn from(s: bool) -> JsValue {
847        JsValue::from_bool(s)
848    }
849}
850
851impl<'a, T> From<&'a T> for JsValue
852where
853    T: JsCast,
854{
855    #[inline]
856    fn from(s: &'a T) -> JsValue {
857        s.as_ref().clone()
858    }
859}
860
861impl<T> From<Option<T>> for JsValue
862where
863    JsValue: From<T>,
864{
865    #[inline]
866    fn from(s: Option<T>) -> JsValue {
867        match s {
868            Some(s) => s.into(),
869            None => JsValue::undefined(),
870        }
871    }
872}
873
874impl JsCast for JsValue {
875    // everything is a `JsValue`!
876    #[inline]
877    fn instanceof(_val: &JsValue) -> bool {
878        true
879    }
880    #[inline]
881    fn unchecked_from_js(val: JsValue) -> Self {
882        val
883    }
884    #[inline]
885    fn unchecked_from_js_ref(val: &JsValue) -> &Self {
886        val
887    }
888}
889
890impl AsRef<JsValue> for JsValue {
891    #[inline]
892    fn as_ref(&self) -> &JsValue {
893        self
894    }
895}
896
897macro_rules! numbers {
898    ($($n:ident)*) => ($(
899        impl PartialEq<$n> for JsValue {
900            #[inline]
901            fn eq(&self, other: &$n) -> bool {
902                self.as_f64() == Some(f64::from(*other))
903            }
904        }
905
906        impl From<$n> for JsValue {
907            #[inline]
908            fn from(n: $n) -> JsValue {
909                JsValue::from_f64(n.into())
910            }
911        }
912    )*)
913}
914
915numbers! { i8 u8 i16 u16 i32 u32 f32 f64 }
916
917macro_rules! big_numbers {
918    (|$arg:ident|, $($n:ident = $handle:expr,)*) => ($(
919        impl PartialEq<$n> for JsValue {
920            #[inline]
921            fn eq(&self, other: &$n) -> bool {
922                self == &JsValue::from(*other)
923            }
924        }
925
926        impl From<$n> for JsValue {
927            #[inline]
928            fn from($arg: $n) -> JsValue {
929                unsafe { JsValue::_new($handle) }
930            }
931        }
932    )*)
933}
934
935fn bigint_get_as_i64(v: &JsValue) -> Option<i64> {
936    unsafe { __wbindgen_bigint_get_as_i64(v.idx).join() }
937}
938
939macro_rules! try_from_for_num64 {
940    ($ty:ty) => {
941        impl TryFrom<JsValue> for $ty {
942            type Error = JsValue;
943
944            #[inline]
945            fn try_from(v: JsValue) -> Result<Self, JsValue> {
946                bigint_get_as_i64(&v)
947                    // Reinterpret bits; ABI-wise this is safe to do and allows us to avoid
948                    // having separate intrinsics per signed/unsigned types.
949                    .map(|as_i64| as_i64 as Self)
950                    // Double-check that we didn't truncate the bigint to 64 bits.
951                    .filter(|as_self| v == *as_self)
952                    // Not a bigint or not in range.
953                    .ok_or(v)
954            }
955        }
956    };
957}
958
959try_from_for_num64!(i64);
960try_from_for_num64!(u64);
961
962macro_rules! try_from_for_num128 {
963    ($ty:ty, $hi_ty:ty) => {
964        impl TryFrom<JsValue> for $ty {
965            type Error = JsValue;
966
967            #[inline]
968            fn try_from(v: JsValue) -> Result<Self, JsValue> {
969                // Truncate the bigint to 64 bits, this will give us the lower part.
970                let lo = match bigint_get_as_i64(&v) {
971                    // The lower part must be interpreted as unsigned in both i128 and u128.
972                    Some(lo) => lo as u64,
973                    // Not a bigint.
974                    None => return Err(v),
975                };
976                // Now we know it's a bigint, so we can safely use `>> 64n` without
977                // worrying about a JS exception on type mismatch.
978                let hi = v >> JsValue::from(64_u64);
979                // The high part is the one we want checked against a 64-bit range.
980                // If it fits, then our original number is in the 128-bit range.
981                let hi = <$hi_ty>::try_from(hi)?;
982                Ok(Self::from(hi) << 64 | Self::from(lo))
983            }
984        }
985    };
986}
987
988try_from_for_num128!(i128, i64);
989try_from_for_num128!(u128, u64);
990
991big_numbers! {
992    |n|,
993    i64 = __wbindgen_bigint_from_i64(n),
994    u64 = __wbindgen_bigint_from_u64(n),
995    i128 = __wbindgen_bigint_from_i128((n >> 64) as i64, n as u64),
996    u128 = __wbindgen_bigint_from_u128((n >> 64) as u64, n as u64),
997}
998
999// `usize` and `isize` have to be treated a bit specially, because we know that
1000// they're 32-bit but the compiler conservatively assumes they might be bigger.
1001// So, we have to manually forward to the `u32`/`i32` versions.
1002impl PartialEq<usize> for JsValue {
1003    #[inline]
1004    fn eq(&self, other: &usize) -> bool {
1005        *self == (*other as u32)
1006    }
1007}
1008
1009impl From<usize> for JsValue {
1010    #[inline]
1011    fn from(n: usize) -> Self {
1012        Self::from(n as u32)
1013    }
1014}
1015
1016impl PartialEq<isize> for JsValue {
1017    #[inline]
1018    fn eq(&self, other: &isize) -> bool {
1019        *self == (*other as i32)
1020    }
1021}
1022
1023impl From<isize> for JsValue {
1024    #[inline]
1025    fn from(n: isize) -> Self {
1026        Self::from(n as i32)
1027    }
1028}
1029
1030externs! {
1031    #[link(wasm_import_module = "__wbindgen_placeholder__")]
1032    extern "C" {
1033        fn __wbindgen_object_clone_ref(idx: u32) -> u32;
1034        fn __wbindgen_object_drop_ref(idx: u32) -> ();
1035
1036        fn __wbindgen_string_new(ptr: *const u8, len: usize) -> u32;
1037        fn __wbindgen_number_new(f: f64) -> u32;
1038        fn __wbindgen_bigint_from_str(ptr: *const u8, len: usize) -> u32;
1039        fn __wbindgen_bigint_from_i64(n: i64) -> u32;
1040        fn __wbindgen_bigint_from_u64(n: u64) -> u32;
1041        fn __wbindgen_bigint_from_i128(hi: i64, lo: u64) -> u32;
1042        fn __wbindgen_bigint_from_u128(hi: u64, lo: u64) -> u32;
1043        fn __wbindgen_symbol_named_new(ptr: *const u8, len: usize) -> u32;
1044        fn __wbindgen_symbol_anonymous_new() -> u32;
1045
1046        fn __wbindgen_externref_heap_live_count() -> u32;
1047
1048        fn __wbindgen_is_null(idx: u32) -> u32;
1049        fn __wbindgen_is_undefined(idx: u32) -> u32;
1050        fn __wbindgen_is_symbol(idx: u32) -> u32;
1051        fn __wbindgen_is_object(idx: u32) -> u32;
1052        fn __wbindgen_is_array(idx: u32) -> u32;
1053        fn __wbindgen_is_function(idx: u32) -> u32;
1054        fn __wbindgen_is_string(idx: u32) -> u32;
1055        fn __wbindgen_is_bigint(idx: u32) -> u32;
1056        fn __wbindgen_typeof(idx: u32) -> u32;
1057
1058        fn __wbindgen_in(prop: u32, obj: u32) -> u32;
1059
1060        fn __wbindgen_is_falsy(idx: u32) -> u32;
1061        fn __wbindgen_as_number(idx: u32) -> f64;
1062        fn __wbindgen_try_into_number(idx: u32) -> u32;
1063        fn __wbindgen_neg(idx: u32) -> u32;
1064        fn __wbindgen_bit_and(a: u32, b: u32) -> u32;
1065        fn __wbindgen_bit_or(a: u32, b: u32) -> u32;
1066        fn __wbindgen_bit_xor(a: u32, b: u32) -> u32;
1067        fn __wbindgen_bit_not(idx: u32) -> u32;
1068        fn __wbindgen_shl(a: u32, b: u32) -> u32;
1069        fn __wbindgen_shr(a: u32, b: u32) -> u32;
1070        fn __wbindgen_unsigned_shr(a: u32, b: u32) -> u32;
1071        fn __wbindgen_add(a: u32, b: u32) -> u32;
1072        fn __wbindgen_sub(a: u32, b: u32) -> u32;
1073        fn __wbindgen_div(a: u32, b: u32) -> u32;
1074        fn __wbindgen_checked_div(a: u32, b: u32) -> u32;
1075        fn __wbindgen_mul(a: u32, b: u32) -> u32;
1076        fn __wbindgen_rem(a: u32, b: u32) -> u32;
1077        fn __wbindgen_pow(a: u32, b: u32) -> u32;
1078        fn __wbindgen_lt(a: u32, b: u32) -> u32;
1079        fn __wbindgen_le(a: u32, b: u32) -> u32;
1080        fn __wbindgen_ge(a: u32, b: u32) -> u32;
1081        fn __wbindgen_gt(a: u32, b: u32) -> u32;
1082
1083        fn __wbindgen_number_get(idx: u32) -> WasmRet<Option<f64>>;
1084        fn __wbindgen_boolean_get(idx: u32) -> u32;
1085        fn __wbindgen_string_get(idx: u32) -> WasmSlice;
1086        fn __wbindgen_bigint_get_as_i64(idx: u32) -> WasmRet<Option<i64>>;
1087
1088        fn __wbindgen_debug_string(ret: *mut [usize; 2], idx: u32) -> ();
1089
1090        fn __wbindgen_throw(a: *const u8, b: usize) -> !;
1091        fn __wbindgen_rethrow(a: u32) -> !;
1092        fn __wbindgen_error_new(a: *const u8, b: usize) -> u32;
1093
1094        fn __wbindgen_cb_drop(idx: u32) -> u32;
1095
1096        fn __wbindgen_describe(v: u32) -> ();
1097        fn __wbindgen_describe_closure(a: u32, b: u32, c: u32) -> u32;
1098
1099        fn __wbindgen_json_parse(ptr: *const u8, len: usize) -> u32;
1100        fn __wbindgen_json_serialize(idx: u32) -> WasmSlice;
1101        fn __wbindgen_jsval_eq(a: u32, b: u32) -> u32;
1102        fn __wbindgen_jsval_loose_eq(a: u32, b: u32) -> u32;
1103
1104        fn __wbindgen_copy_to_typed_array(ptr: *const u8, len: usize, idx: u32) -> ();
1105
1106        fn __wbindgen_uint8_array_new(ptr: *mut u8, len: usize) -> u32;
1107        fn __wbindgen_uint8_clamped_array_new(ptr: *mut u8, len: usize) -> u32;
1108        fn __wbindgen_uint16_array_new(ptr: *mut u16, len: usize) -> u32;
1109        fn __wbindgen_uint32_array_new(ptr: *mut u32, len: usize) -> u32;
1110        fn __wbindgen_biguint64_array_new(ptr: *mut u64, len: usize) -> u32;
1111        fn __wbindgen_int8_array_new(ptr: *mut i8, len: usize) -> u32;
1112        fn __wbindgen_int16_array_new(ptr: *mut i16, len: usize) -> u32;
1113        fn __wbindgen_int32_array_new(ptr: *mut i32, len: usize) -> u32;
1114        fn __wbindgen_bigint64_array_new(ptr: *mut i64, len: usize) -> u32;
1115        fn __wbindgen_float32_array_new(ptr: *mut f32, len: usize) -> u32;
1116        fn __wbindgen_float64_array_new(ptr: *mut f64, len: usize) -> u32;
1117
1118        fn __wbindgen_array_new() -> u32;
1119        fn __wbindgen_array_push(array: u32, value: u32) -> ();
1120
1121        fn __wbindgen_not(idx: u32) -> u32;
1122
1123        fn __wbindgen_exports() -> u32;
1124        fn __wbindgen_memory() -> u32;
1125        fn __wbindgen_module() -> u32;
1126        fn __wbindgen_function_table() -> u32;
1127    }
1128}
1129
1130impl Clone for JsValue {
1131    #[inline]
1132    fn clone(&self) -> JsValue {
1133        unsafe {
1134            let idx = __wbindgen_object_clone_ref(self.idx);
1135            JsValue::_new(idx)
1136        }
1137    }
1138}
1139
1140#[cfg(feature = "std")]
1141impl core::fmt::Debug for JsValue {
1142    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
1143        write!(f, "JsValue({})", self.as_debug_string())
1144    }
1145}
1146
1147#[cfg(not(feature = "std"))]
1148impl core::fmt::Debug for JsValue {
1149    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
1150        f.write_str("JsValue")
1151    }
1152}
1153
1154impl Drop for JsValue {
1155    #[inline]
1156    fn drop(&mut self) {
1157        unsafe {
1158            // We definitely should never drop anything in the stack area
1159            debug_assert!(self.idx >= JSIDX_OFFSET, "free of stack slot {}", self.idx);
1160
1161            // Otherwise if we're not dropping one of our reserved values,
1162            // actually call the intrinsic. See #1054 for eventually removing
1163            // this branch.
1164            if self.idx >= JSIDX_RESERVED {
1165                __wbindgen_object_drop_ref(self.idx);
1166            }
1167        }
1168    }
1169}
1170
1171impl Default for JsValue {
1172    fn default() -> Self {
1173        Self::UNDEFINED
1174    }
1175}
1176
1177/// Wrapper type for imported statics.
1178///
1179/// This type is used whenever a `static` is imported from a JS module, for
1180/// example this import:
1181///
1182/// ```ignore
1183/// #[wasm_bindgen]
1184/// extern "C" {
1185///     static console: JsValue;
1186/// }
1187/// ```
1188///
1189/// will generate in Rust a value that looks like:
1190///
1191/// ```ignore
1192/// static console: JsStatic<JsValue> = ...;
1193/// ```
1194///
1195/// This type implements `Deref` to the inner type so it's typically used as if
1196/// it were `&T`.
1197#[cfg(feature = "std")]
1198#[deprecated = "use with `#[wasm_bindgen(thread_local_v2)]` instead"]
1199pub struct JsStatic<T: 'static> {
1200    #[doc(hidden)]
1201    pub __inner: &'static std::thread::LocalKey<T>,
1202}
1203
1204#[cfg(feature = "std")]
1205#[allow(deprecated)]
1206#[cfg(not(target_feature = "atomics"))]
1207impl<T: FromWasmAbi + 'static> Deref for JsStatic<T> {
1208    type Target = T;
1209    fn deref(&self) -> &T {
1210        unsafe { self.__inner.with(|ptr| &*(ptr as *const T)) }
1211    }
1212}
1213
1214/// Wrapper type for imported statics.
1215///
1216/// This type is used whenever a `static` is imported from a JS module, for
1217/// example this import:
1218///
1219/// ```ignore
1220/// #[wasm_bindgen]
1221/// extern "C" {
1222///     #[wasm_bindgen(thread_local_v2)]
1223///     static console: JsValue;
1224/// }
1225/// ```
1226///
1227/// will generate in Rust a value that looks like:
1228///
1229/// ```ignore
1230/// static console: JsThreadLocal<JsValue> = ...;
1231/// ```
1232pub struct JsThreadLocal<T: 'static> {
1233    #[doc(hidden)]
1234    #[cfg(feature = "std")]
1235    pub __inner: &'static std::thread::LocalKey<T>,
1236    #[doc(hidden)]
1237    #[cfg(all(not(feature = "std"), not(target_feature = "atomics")))]
1238    pub __inner: &'static __rt::LazyCell<T>,
1239    #[doc(hidden)]
1240    #[cfg(all(not(feature = "std"), target_feature = "atomics"))]
1241    pub __inner: fn() -> *const T,
1242}
1243
1244impl<T> JsThreadLocal<T> {
1245    pub fn with<F, R>(&'static self, f: F) -> R
1246    where
1247        F: FnOnce(&T) -> R,
1248    {
1249        #[cfg(feature = "std")]
1250        return self.__inner.with(f);
1251        #[cfg(all(not(feature = "std"), not(target_feature = "atomics")))]
1252        return f(self.__inner);
1253        #[cfg(all(not(feature = "std"), target_feature = "atomics"))]
1254        f(unsafe { &*(self.__inner)() })
1255    }
1256}
1257
1258#[cold]
1259#[inline(never)]
1260#[deprecated(note = "renamed to `throw_str`")]
1261#[doc(hidden)]
1262pub fn throw(s: &str) -> ! {
1263    throw_str(s)
1264}
1265
1266/// Throws a JS exception.
1267///
1268/// This function will throw a JS exception with the message provided. The
1269/// function will not return as the Wasm stack will be popped when the exception
1270/// is thrown.
1271///
1272/// Note that it is very easy to leak memory with this function because this
1273/// function, unlike `panic!` on other platforms, **will not run destructors**.
1274/// It's recommended to return a `Result` where possible to avoid the worry of
1275/// leaks.
1276#[cold]
1277#[inline(never)]
1278pub fn throw_str(s: &str) -> ! {
1279    unsafe {
1280        __wbindgen_throw(s.as_ptr(), s.len());
1281    }
1282}
1283
1284/// Rethrow a JS exception
1285///
1286/// This function will throw a JS exception with the JS value provided. This
1287/// function will not return and the Wasm stack will be popped until the point
1288/// of entry of Wasm itself.
1289///
1290/// Note that it is very easy to leak memory with this function because this
1291/// function, unlike `panic!` on other platforms, **will not run destructors**.
1292/// It's recommended to return a `Result` where possible to avoid the worry of
1293/// leaks.
1294#[cold]
1295#[inline(never)]
1296pub fn throw_val(s: JsValue) -> ! {
1297    unsafe {
1298        let idx = s.idx;
1299        mem::forget(s);
1300        __wbindgen_rethrow(idx);
1301    }
1302}
1303
1304/// Get the count of live `externref`s / `JsValue`s in `wasm-bindgen`'s heap.
1305///
1306/// ## Usage
1307///
1308/// This is intended for debugging and writing tests.
1309///
1310/// To write a test that asserts against unnecessarily keeping `anref`s /
1311/// `JsValue`s alive:
1312///
1313/// * get an initial live count,
1314///
1315/// * perform some series of operations or function calls that should clean up
1316///   after themselves, and should not keep holding onto `externref`s / `JsValue`s
1317///   after completion,
1318///
1319/// * get the final live count,
1320///
1321/// * and assert that the initial and final counts are the same.
1322///
1323/// ## What is Counted
1324///
1325/// Note that this only counts the *owned* `externref`s / `JsValue`s that end up in
1326/// `wasm-bindgen`'s heap. It does not count borrowed `externref`s / `JsValue`s
1327/// that are on its stack.
1328///
1329/// For example, these `JsValue`s are accounted for:
1330///
1331/// ```ignore
1332/// #[wasm_bindgen]
1333/// pub fn my_function(this_is_counted: JsValue) {
1334///     let also_counted = JsValue::from_str("hi");
1335///     assert!(wasm_bindgen::externref_heap_live_count() >= 2);
1336/// }
1337/// ```
1338///
1339/// While this borrowed `JsValue` ends up on the stack, not the heap, and
1340/// therefore is not accounted for:
1341///
1342/// ```ignore
1343/// #[wasm_bindgen]
1344/// pub fn my_other_function(this_is_not_counted: &JsValue) {
1345///     // ...
1346/// }
1347/// ```
1348pub fn externref_heap_live_count() -> u32 {
1349    unsafe { __wbindgen_externref_heap_live_count() }
1350}
1351
1352#[doc(hidden)]
1353pub fn anyref_heap_live_count() -> u32 {
1354    externref_heap_live_count()
1355}
1356
1357/// An extension trait for `Option<T>` and `Result<T, E>` for unwrapping the `T`
1358/// value, or throwing a JS error if it is not available.
1359///
1360/// These methods should have a smaller code size footprint than the normal
1361/// `Option::unwrap` and `Option::expect` methods, but they are specific to
1362/// working with Wasm and JS.
1363///
1364/// On non-wasm32 targets, defaults to the normal unwrap/expect calls.
1365///
1366/// # Example
1367///
1368/// ```
1369/// use wasm_bindgen::prelude::*;
1370///
1371/// // If the value is `Option::Some` or `Result::Ok`, then we just get the
1372/// // contained `T` value.
1373/// let x = Some(42);
1374/// assert_eq!(x.unwrap_throw(), 42);
1375///
1376/// let y: Option<i32> = None;
1377///
1378/// // This call would throw an error to JS!
1379/// //
1380/// //     y.unwrap_throw()
1381/// //
1382/// // And this call would throw an error to JS with a custom error message!
1383/// //
1384/// //     y.expect_throw("woopsie daisy!")
1385/// ```
1386pub trait UnwrapThrowExt<T>: Sized {
1387    /// Unwrap this `Option` or `Result`, but instead of panicking on failure,
1388    /// throw an exception to JavaScript.
1389    #[cfg_attr(
1390        any(
1391            debug_assertions,
1392            not(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))
1393        ),
1394        track_caller
1395    )]
1396    fn unwrap_throw(self) -> T {
1397        if cfg!(all(
1398            debug_assertions,
1399            all(
1400                target_arch = "wasm32",
1401                any(target_os = "unknown", target_os = "none")
1402            )
1403        )) {
1404            let loc = core::panic::Location::caller();
1405            let msg = alloc::format!(
1406                "called `{}::unwrap_throw()` ({}:{}:{})",
1407                core::any::type_name::<Self>(),
1408                loc.file(),
1409                loc.line(),
1410                loc.column()
1411            );
1412            self.expect_throw(&msg)
1413        } else {
1414            self.expect_throw("called `unwrap_throw()`")
1415        }
1416    }
1417
1418    /// Unwrap this container's `T` value, or throw an error to JS with the
1419    /// given message if the `T` value is unavailable (e.g. an `Option<T>` is
1420    /// `None`).
1421    #[cfg_attr(
1422        any(
1423            debug_assertions,
1424            not(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))
1425        ),
1426        track_caller
1427    )]
1428    fn expect_throw(self, message: &str) -> T;
1429}
1430
1431impl<T> UnwrapThrowExt<T> for Option<T> {
1432    fn unwrap_throw(self) -> T {
1433        const MSG: &str = "called `Option::unwrap_throw()` on a `None` value";
1434
1435        if cfg!(all(
1436            target_arch = "wasm32",
1437            any(target_os = "unknown", target_os = "none")
1438        )) {
1439            if let Some(val) = self {
1440                val
1441            } else if cfg!(debug_assertions) {
1442                let loc = core::panic::Location::caller();
1443                let msg =
1444                    alloc::format!("{} ({}:{}:{})", MSG, loc.file(), loc.line(), loc.column(),);
1445
1446                throw_str(&msg)
1447            } else {
1448                throw_str(MSG)
1449            }
1450        } else {
1451            self.expect(MSG)
1452        }
1453    }
1454
1455    fn expect_throw(self, message: &str) -> T {
1456        if cfg!(all(
1457            target_arch = "wasm32",
1458            any(target_os = "unknown", target_os = "none")
1459        )) {
1460            if let Some(val) = self {
1461                val
1462            } else if cfg!(debug_assertions) {
1463                let loc = core::panic::Location::caller();
1464                let msg = alloc::format!(
1465                    "{} ({}:{}:{})",
1466                    message,
1467                    loc.file(),
1468                    loc.line(),
1469                    loc.column(),
1470                );
1471
1472                throw_str(&msg)
1473            } else {
1474                throw_str(message)
1475            }
1476        } else {
1477            self.expect(message)
1478        }
1479    }
1480}
1481
1482impl<T, E> UnwrapThrowExt<T> for Result<T, E>
1483where
1484    E: core::fmt::Debug,
1485{
1486    fn unwrap_throw(self) -> T {
1487        const MSG: &str = "called `Result::unwrap_throw()` on an `Err` value";
1488
1489        if cfg!(all(
1490            target_arch = "wasm32",
1491            any(target_os = "unknown", target_os = "none")
1492        )) {
1493            match self {
1494                Ok(val) => val,
1495                Err(err) => {
1496                    if cfg!(debug_assertions) {
1497                        let loc = core::panic::Location::caller();
1498                        let msg = alloc::format!(
1499                            "{} ({}:{}:{}): {:?}",
1500                            MSG,
1501                            loc.file(),
1502                            loc.line(),
1503                            loc.column(),
1504                            err
1505                        );
1506
1507                        throw_str(&msg)
1508                    } else {
1509                        throw_str(MSG)
1510                    }
1511                }
1512            }
1513        } else {
1514            self.expect(MSG)
1515        }
1516    }
1517
1518    fn expect_throw(self, message: &str) -> T {
1519        if cfg!(all(
1520            target_arch = "wasm32",
1521            any(target_os = "unknown", target_os = "none")
1522        )) {
1523            match self {
1524                Ok(val) => val,
1525                Err(err) => {
1526                    if cfg!(debug_assertions) {
1527                        let loc = core::panic::Location::caller();
1528                        let msg = alloc::format!(
1529                            "{} ({}:{}:{}): {:?}",
1530                            message,
1531                            loc.file(),
1532                            loc.line(),
1533                            loc.column(),
1534                            err
1535                        );
1536
1537                        throw_str(&msg)
1538                    } else {
1539                        throw_str(message)
1540                    }
1541                }
1542            }
1543        } else {
1544            self.expect(message)
1545        }
1546    }
1547}
1548
1549/// Returns a handle to this Wasm instance's `WebAssembly.Module`.
1550/// This is only available when the final Wasm app is built with
1551/// `--target no-modules` or `--target web`.
1552pub fn module() -> JsValue {
1553    unsafe { JsValue::_new(__wbindgen_module()) }
1554}
1555
1556/// Returns a handle to this Wasm instance's `WebAssembly.Instance.prototype.exports`
1557pub fn exports() -> JsValue {
1558    unsafe { JsValue::_new(__wbindgen_exports()) }
1559}
1560
1561/// Returns a handle to this Wasm instance's `WebAssembly.Memory`
1562pub fn memory() -> JsValue {
1563    unsafe { JsValue::_new(__wbindgen_memory()) }
1564}
1565
1566/// Returns a handle to this Wasm instance's `WebAssembly.Table` which is the
1567/// indirect function table used by Rust
1568pub fn function_table() -> JsValue {
1569    unsafe { JsValue::_new(__wbindgen_function_table()) }
1570}
1571
1572#[doc(hidden)]
1573pub mod __rt {
1574    use crate::JsValue;
1575    use core::borrow::{Borrow, BorrowMut};
1576    use core::cell::{Cell, UnsafeCell};
1577    use core::convert::Infallible;
1578    use core::mem;
1579    use core::ops::{Deref, DerefMut};
1580    #[cfg(all(target_feature = "atomics", not(feature = "std")))]
1581    use core::sync::atomic::{AtomicU8, Ordering};
1582
1583    pub extern crate alloc;
1584    pub extern crate core;
1585    #[cfg(feature = "std")]
1586    pub extern crate std;
1587
1588    use alloc::alloc::{alloc, dealloc, realloc, Layout};
1589    use alloc::boxed::Box;
1590    use alloc::rc::Rc;
1591
1592    /// Wrapper around [`::once_cell::unsync::Lazy`] adding some compatibility methods with
1593    /// [`std::thread::LocalKey`] and adding `Send + Sync` when `atomics` is not enabled.
1594    #[cfg(not(feature = "std"))]
1595    pub struct LazyCell<T, F = fn() -> T>(::once_cell::unsync::Lazy<T, F>);
1596
1597    #[cfg(all(not(target_feature = "atomics"), not(feature = "std")))]
1598    unsafe impl<T, F> Sync for LazyCell<T, F> {}
1599
1600    #[cfg(all(not(target_feature = "atomics"), not(feature = "std")))]
1601    unsafe impl<T, F> Send for LazyCell<T, F> {}
1602
1603    #[cfg(not(feature = "std"))]
1604    impl<T, F> LazyCell<T, F> {
1605        pub const fn new(init: F) -> LazyCell<T, F> {
1606            Self(::once_cell::unsync::Lazy::new(init))
1607        }
1608    }
1609
1610    #[cfg(not(feature = "std"))]
1611    impl<T, F: FnOnce() -> T> LazyCell<T, F> {
1612        pub(crate) fn try_with<R>(
1613            &self,
1614            f: impl FnOnce(&T) -> R,
1615        ) -> Result<R, core::convert::Infallible> {
1616            Ok(f(&self.0))
1617        }
1618
1619        pub fn force(this: &Self) -> &T {
1620            &this.0
1621        }
1622    }
1623
1624    #[cfg(not(feature = "std"))]
1625    impl<T> Deref for LazyCell<T> {
1626        type Target = T;
1627
1628        fn deref(&self) -> &T {
1629            ::once_cell::unsync::Lazy::force(&self.0)
1630        }
1631    }
1632
1633    #[cfg(feature = "std")]
1634    pub use once_cell::sync::Lazy as LazyLock;
1635
1636    #[cfg(all(not(target_feature = "atomics"), not(feature = "std")))]
1637    pub use LazyCell as LazyLock;
1638
1639    #[cfg(all(target_feature = "atomics", not(feature = "std")))]
1640    pub struct LazyLock<T, F = fn() -> T> {
1641        state: AtomicU8,
1642        data: UnsafeCell<Data<T, F>>,
1643    }
1644
1645    #[cfg(all(target_feature = "atomics", not(feature = "std")))]
1646    enum Data<T, F> {
1647        Value(T),
1648        Init(F),
1649    }
1650
1651    #[cfg(all(target_feature = "atomics", not(feature = "std")))]
1652    unsafe impl<T, F> Sync for LazyLock<T, F> {}
1653
1654    #[cfg(all(target_feature = "atomics", not(feature = "std")))]
1655    unsafe impl<T, F> Send for LazyLock<T, F> {}
1656
1657    #[cfg(all(target_feature = "atomics", not(feature = "std")))]
1658    impl<T, F> LazyLock<T, F> {
1659        const STATE_UNINIT: u8 = 0;
1660        const STATE_INITIALIZING: u8 = 1;
1661        const STATE_INIT: u8 = 2;
1662
1663        pub const fn new(init: F) -> LazyLock<T, F> {
1664            Self {
1665                state: AtomicU8::new(Self::STATE_UNINIT),
1666                data: UnsafeCell::new(Data::Init(init)),
1667            }
1668        }
1669    }
1670
1671    #[cfg(all(target_feature = "atomics", not(feature = "std")))]
1672    impl<T> Deref for LazyLock<T> {
1673        type Target = T;
1674
1675        fn deref(&self) -> &T {
1676            let mut state = self.state.load(Ordering::Acquire);
1677
1678            loop {
1679                match state {
1680                    Self::STATE_INIT => {
1681                        let Data::Value(value) = (unsafe { &*self.data.get() }) else {
1682                            unreachable!()
1683                        };
1684                        return value;
1685                    }
1686                    Self::STATE_UNINIT => {
1687                        if let Err(new_state) = self.state.compare_exchange_weak(
1688                            Self::STATE_UNINIT,
1689                            Self::STATE_INITIALIZING,
1690                            Ordering::Acquire,
1691                            Ordering::Relaxed,
1692                        ) {
1693                            state = new_state;
1694                            continue;
1695                        }
1696
1697                        let data = unsafe { &mut *self.data.get() };
1698                        let Data::Init(init) = data else {
1699                            unreachable!()
1700                        };
1701                        *data = Data::Value(init());
1702                        self.state.store(Self::STATE_INIT, Ordering::Release);
1703                        state = Self::STATE_INIT;
1704                    }
1705                    Self::STATE_INITIALIZING => {
1706                        // TODO: Block here if possible. This would require
1707                        // detecting if we can in the first place.
1708                        state = self.state.load(Ordering::Acquire);
1709                    }
1710                    _ => unreachable!(),
1711                }
1712            }
1713        }
1714    }
1715
1716    #[macro_export]
1717    #[doc(hidden)]
1718    #[cfg(all(not(feature = "std"), not(target_feature = "atomics")))]
1719    macro_rules! __wbindgen_thread_local {
1720        ($wasm_bindgen:tt, $actual_ty:ty) => {{
1721            static _VAL: $wasm_bindgen::__rt::LazyCell<$actual_ty> =
1722                $wasm_bindgen::__rt::LazyCell::new(init);
1723            $wasm_bindgen::JsThreadLocal { __inner: &_VAL }
1724        }};
1725    }
1726
1727    #[macro_export]
1728    #[doc(hidden)]
1729    #[cfg(all(not(feature = "std"), target_feature = "atomics"))]
1730    #[allow_internal_unstable(thread_local)]
1731    macro_rules! __wbindgen_thread_local {
1732        ($wasm_bindgen:tt, $actual_ty:ty) => {{
1733            #[thread_local]
1734            static _VAL: $wasm_bindgen::__rt::LazyCell<$actual_ty> =
1735                $wasm_bindgen::__rt::LazyCell::new(init);
1736            $wasm_bindgen::JsThreadLocal {
1737                __inner: || unsafe {
1738                    $wasm_bindgen::__rt::LazyCell::force(&_VAL) as *const $actual_ty
1739                },
1740            }
1741        }};
1742    }
1743
1744    #[macro_export]
1745    #[doc(hidden)]
1746    #[cfg(not(wasm_bindgen_unstable_test_coverage))]
1747    macro_rules! __wbindgen_coverage {
1748        ($item:item) => {
1749            $item
1750        };
1751    }
1752
1753    #[macro_export]
1754    #[doc(hidden)]
1755    #[cfg(wasm_bindgen_unstable_test_coverage)]
1756    #[allow_internal_unstable(coverage_attribute)]
1757    macro_rules! __wbindgen_coverage {
1758        ($item:item) => {
1759            #[coverage(off)]
1760            $item
1761        };
1762    }
1763
1764    #[inline]
1765    pub fn assert_not_null<T>(s: *mut T) {
1766        if s.is_null() {
1767            throw_null();
1768        }
1769    }
1770
1771    #[cold]
1772    #[inline(never)]
1773    fn throw_null() -> ! {
1774        super::throw_str("null pointer passed to rust");
1775    }
1776
1777    /// A vendored version of `RefCell` from the standard library.
1778    ///
1779    /// Now why, you may ask, would we do that? Surely `RefCell` in libstd is
1780    /// quite good. And you're right, it is indeed quite good! Functionally
1781    /// nothing more is needed from `RefCell` in the standard library but for
1782    /// now this crate is also sort of optimizing for compiled code size.
1783    ///
1784    /// One major factor to larger binaries in Rust is when a panic happens.
1785    /// Panicking in the standard library involves a fair bit of machinery
1786    /// (formatting, panic hooks, synchronization, etc). It's all worthwhile if
1787    /// you need it but for something like `WasmRefCell` here we don't actually
1788    /// need all that!
1789    ///
1790    /// This is just a wrapper around all Rust objects passed to JS intended to
1791    /// guard accidental reentrancy, so this vendored version is intended solely
1792    /// to not panic in libstd. Instead when it "panics" it calls our `throw`
1793    /// function in this crate which raises an error in JS.
1794    pub struct WasmRefCell<T: ?Sized> {
1795        borrow: Cell<usize>,
1796        value: UnsafeCell<T>,
1797    }
1798
1799    impl<T: ?Sized> WasmRefCell<T> {
1800        pub fn new(value: T) -> WasmRefCell<T>
1801        where
1802            T: Sized,
1803        {
1804            WasmRefCell {
1805                value: UnsafeCell::new(value),
1806                borrow: Cell::new(0),
1807            }
1808        }
1809
1810        pub fn get_mut(&mut self) -> &mut T {
1811            unsafe { &mut *self.value.get() }
1812        }
1813
1814        pub fn borrow(&self) -> Ref<T> {
1815            unsafe {
1816                if self.borrow.get() == usize::MAX {
1817                    borrow_fail();
1818                }
1819                self.borrow.set(self.borrow.get() + 1);
1820                Ref {
1821                    value: &*self.value.get(),
1822                    borrow: &self.borrow,
1823                }
1824            }
1825        }
1826
1827        pub fn borrow_mut(&self) -> RefMut<T> {
1828            unsafe {
1829                if self.borrow.get() != 0 {
1830                    borrow_fail();
1831                }
1832                self.borrow.set(usize::MAX);
1833                RefMut {
1834                    value: &mut *self.value.get(),
1835                    borrow: &self.borrow,
1836                }
1837            }
1838        }
1839
1840        pub fn into_inner(self) -> T
1841        where
1842            T: Sized,
1843        {
1844            self.value.into_inner()
1845        }
1846    }
1847
1848    pub struct Ref<'b, T: ?Sized + 'b> {
1849        value: &'b T,
1850        borrow: &'b Cell<usize>,
1851    }
1852
1853    impl<T: ?Sized> Deref for Ref<'_, T> {
1854        type Target = T;
1855
1856        #[inline]
1857        fn deref(&self) -> &T {
1858            self.value
1859        }
1860    }
1861
1862    impl<T: ?Sized> Borrow<T> for Ref<'_, T> {
1863        #[inline]
1864        fn borrow(&self) -> &T {
1865            self.value
1866        }
1867    }
1868
1869    impl<T: ?Sized> Drop for Ref<'_, T> {
1870        fn drop(&mut self) {
1871            self.borrow.set(self.borrow.get() - 1);
1872        }
1873    }
1874
1875    pub struct RefMut<'b, T: ?Sized + 'b> {
1876        value: &'b mut T,
1877        borrow: &'b Cell<usize>,
1878    }
1879
1880    impl<T: ?Sized> Deref for RefMut<'_, T> {
1881        type Target = T;
1882
1883        #[inline]
1884        fn deref(&self) -> &T {
1885            self.value
1886        }
1887    }
1888
1889    impl<T: ?Sized> DerefMut for RefMut<'_, T> {
1890        #[inline]
1891        fn deref_mut(&mut self) -> &mut T {
1892            self.value
1893        }
1894    }
1895
1896    impl<T: ?Sized> Borrow<T> for RefMut<'_, T> {
1897        #[inline]
1898        fn borrow(&self) -> &T {
1899            self.value
1900        }
1901    }
1902
1903    impl<T: ?Sized> BorrowMut<T> for RefMut<'_, T> {
1904        #[inline]
1905        fn borrow_mut(&mut self) -> &mut T {
1906            self.value
1907        }
1908    }
1909
1910    impl<T: ?Sized> Drop for RefMut<'_, T> {
1911        fn drop(&mut self) {
1912            self.borrow.set(0);
1913        }
1914    }
1915
1916    fn borrow_fail() -> ! {
1917        super::throw_str(
1918            "recursive use of an object detected which would lead to \
1919             unsafe aliasing in rust",
1920        );
1921    }
1922
1923    /// A type that encapsulates an `Rc<WasmRefCell<T>>` as well as a `Ref`
1924    /// to the contents of that `WasmRefCell`.
1925    ///
1926    /// The `'static` requirement is an unfortunate consequence of how this
1927    /// is implemented.
1928    pub struct RcRef<T: ?Sized + 'static> {
1929        // The 'static is a lie.
1930        //
1931        // We could get away without storing this, since we're in the same module as
1932        // `WasmRefCell` and can directly manipulate its `borrow`, but I'm considering
1933        // turning it into a wrapper around `std`'s `RefCell` to reduce `unsafe` in
1934        // which case that would stop working. This also requires less `unsafe` as is.
1935        //
1936        // It's important that this goes before `Rc` so that it gets dropped first.
1937        ref_: Ref<'static, T>,
1938        _rc: Rc<WasmRefCell<T>>,
1939    }
1940
1941    impl<T: ?Sized> RcRef<T> {
1942        pub fn new(rc: Rc<WasmRefCell<T>>) -> Self {
1943            let ref_ = unsafe { (*Rc::as_ptr(&rc)).borrow() };
1944            Self { _rc: rc, ref_ }
1945        }
1946    }
1947
1948    impl<T: ?Sized> Deref for RcRef<T> {
1949        type Target = T;
1950
1951        #[inline]
1952        fn deref(&self) -> &T {
1953            &self.ref_
1954        }
1955    }
1956
1957    impl<T: ?Sized> Borrow<T> for RcRef<T> {
1958        #[inline]
1959        fn borrow(&self) -> &T {
1960            &self.ref_
1961        }
1962    }
1963
1964    /// A type that encapsulates an `Rc<WasmRefCell<T>>` as well as a
1965    /// `RefMut` to the contents of that `WasmRefCell`.
1966    ///
1967    /// The `'static` requirement is an unfortunate consequence of how this
1968    /// is implemented.
1969    pub struct RcRefMut<T: ?Sized + 'static> {
1970        ref_: RefMut<'static, T>,
1971        _rc: Rc<WasmRefCell<T>>,
1972    }
1973
1974    impl<T: ?Sized> RcRefMut<T> {
1975        pub fn new(rc: Rc<WasmRefCell<T>>) -> Self {
1976            let ref_ = unsafe { (*Rc::as_ptr(&rc)).borrow_mut() };
1977            Self { _rc: rc, ref_ }
1978        }
1979    }
1980
1981    impl<T: ?Sized> Deref for RcRefMut<T> {
1982        type Target = T;
1983
1984        #[inline]
1985        fn deref(&self) -> &T {
1986            &self.ref_
1987        }
1988    }
1989
1990    impl<T: ?Sized> DerefMut for RcRefMut<T> {
1991        #[inline]
1992        fn deref_mut(&mut self) -> &mut T {
1993            &mut self.ref_
1994        }
1995    }
1996
1997    impl<T: ?Sized> Borrow<T> for RcRefMut<T> {
1998        #[inline]
1999        fn borrow(&self) -> &T {
2000            &self.ref_
2001        }
2002    }
2003
2004    impl<T: ?Sized> BorrowMut<T> for RcRefMut<T> {
2005        #[inline]
2006        fn borrow_mut(&mut self) -> &mut T {
2007            &mut self.ref_
2008        }
2009    }
2010
2011    #[no_mangle]
2012    pub extern "C" fn __wbindgen_malloc(size: usize, align: usize) -> *mut u8 {
2013        if let Ok(layout) = Layout::from_size_align(size, align) {
2014            unsafe {
2015                if layout.size() > 0 {
2016                    let ptr = alloc(layout);
2017                    if !ptr.is_null() {
2018                        return ptr;
2019                    }
2020                } else {
2021                    return align as *mut u8;
2022                }
2023            }
2024        }
2025
2026        malloc_failure();
2027    }
2028
2029    #[no_mangle]
2030    pub unsafe extern "C" fn __wbindgen_realloc(
2031        ptr: *mut u8,
2032        old_size: usize,
2033        new_size: usize,
2034        align: usize,
2035    ) -> *mut u8 {
2036        debug_assert!(old_size > 0);
2037        debug_assert!(new_size > 0);
2038        if let Ok(layout) = Layout::from_size_align(old_size, align) {
2039            let ptr = realloc(ptr, layout, new_size);
2040            if !ptr.is_null() {
2041                return ptr;
2042            }
2043        }
2044        malloc_failure();
2045    }
2046
2047    #[cold]
2048    fn malloc_failure() -> ! {
2049        cfg_if::cfg_if! {
2050            if #[cfg(debug_assertions)] {
2051                super::throw_str("invalid malloc request")
2052            } else if #[cfg(feature = "std")] {
2053                std::process::abort();
2054            } else if #[cfg(all(
2055                target_arch = "wasm32",
2056                any(target_os = "unknown", target_os = "none")
2057            ))] {
2058                core::arch::wasm32::unreachable();
2059            } else {
2060                unreachable!()
2061            }
2062        }
2063    }
2064
2065    #[no_mangle]
2066    pub unsafe extern "C" fn __wbindgen_free(ptr: *mut u8, size: usize, align: usize) {
2067        // This happens for zero-length slices, and in that case `ptr` is
2068        // likely bogus so don't actually send this to the system allocator
2069        if size == 0 {
2070            return;
2071        }
2072        let layout = Layout::from_size_align_unchecked(size, align);
2073        dealloc(ptr, layout);
2074    }
2075
2076    /// This is a curious function necessary to get wasm-bindgen working today,
2077    /// and it's a bit of an unfortunate hack.
2078    ///
2079    /// The general problem is that somehow we need the above two symbols to
2080    /// exist in the final output binary (__wbindgen_malloc and
2081    /// __wbindgen_free). These symbols may be called by JS for various
2082    /// bindings, so we for sure need to make sure they're exported.
2083    ///
2084    /// The problem arises, though, when what if no Rust code uses the symbols?
2085    /// For all intents and purposes it looks to LLVM and the linker like the
2086    /// above two symbols are dead code, so they're completely discarded!
2087    ///
2088    /// Specifically what happens is this:
2089    ///
2090    /// * The above two symbols are generated into some object file inside of
2091    ///   libwasm_bindgen.rlib
2092    /// * The linker, LLD, will not load this object file unless *some* symbol
2093    ///   is loaded from the object. In this case, if the Rust code never calls
2094    ///   __wbindgen_malloc or __wbindgen_free then the symbols never get linked
2095    ///   in.
2096    /// * Later when `wasm-bindgen` attempts to use the symbols they don't
2097    ///   exist, causing an error.
2098    ///
2099    /// This function is a weird hack for this problem. We inject a call to this
2100    /// function in all generated code. Usage of this function should then
2101    /// ensure that the above two intrinsics are translated.
2102    ///
2103    /// Due to how rustc creates object files this function (and anything inside
2104    /// it) will be placed into the same object file as the two intrinsics
2105    /// above. That means if this function is called and referenced we'll pull
2106    /// in the object file and link the intrinsics.
2107    ///
2108    /// Ideas for how to improve this are most welcome!
2109    #[cfg_attr(wasm_bindgen_unstable_test_coverage, coverage(off))]
2110    pub fn link_mem_intrinsics() {
2111        crate::link::link_intrinsics();
2112    }
2113
2114    #[cfg(feature = "std")]
2115    std::thread_local! {
2116        static GLOBAL_EXNDATA: Cell<[u32; 2]> = Cell::new([0; 2]);
2117    }
2118    #[cfg(all(not(feature = "std"), not(target_feature = "atomics")))]
2119    static mut GLOBAL_EXNDATA: [u32; 2] = [0; 2];
2120    #[cfg(all(not(feature = "std"), target_feature = "atomics"))]
2121    #[thread_local]
2122    static GLOBAL_EXNDATA: Cell<[u32; 2]> = Cell::new([0; 2]);
2123
2124    struct GlobalExndata;
2125
2126    impl GlobalExndata {
2127        #[cfg(feature = "std")]
2128        fn get() -> [u32; 2] {
2129            GLOBAL_EXNDATA.with(Cell::get)
2130        }
2131
2132        #[cfg(all(not(feature = "std"), not(target_feature = "atomics")))]
2133        fn get() -> [u32; 2] {
2134            unsafe { GLOBAL_EXNDATA }
2135        }
2136
2137        #[cfg(all(not(feature = "std"), target_feature = "atomics"))]
2138        fn get() -> [u32; 2] {
2139            GLOBAL_EXNDATA.get()
2140        }
2141
2142        #[cfg(feature = "std")]
2143        fn set(data: [u32; 2]) {
2144            GLOBAL_EXNDATA.with(|d| d.set(data))
2145        }
2146
2147        #[cfg(all(not(feature = "std"), not(target_feature = "atomics")))]
2148        fn set(data: [u32; 2]) {
2149            unsafe { GLOBAL_EXNDATA = data };
2150        }
2151
2152        #[cfg(all(not(feature = "std"), target_feature = "atomics"))]
2153        fn set(data: [u32; 2]) {
2154            GLOBAL_EXNDATA.set(data);
2155        }
2156    }
2157
2158    #[no_mangle]
2159    pub unsafe extern "C" fn __wbindgen_exn_store(idx: u32) {
2160        debug_assert_eq!(GlobalExndata::get()[0], 0);
2161        GlobalExndata::set([1, idx]);
2162    }
2163
2164    pub fn take_last_exception() -> Result<(), super::JsValue> {
2165        let ret = if GlobalExndata::get()[0] == 1 {
2166            Err(super::JsValue::_new(GlobalExndata::get()[1]))
2167        } else {
2168            Ok(())
2169        };
2170        GlobalExndata::set([0, 0]);
2171        ret
2172    }
2173
2174    /// An internal helper trait for usage in `#[wasm_bindgen]` on `async`
2175    /// functions to convert the return value of the function to
2176    /// `Result<JsValue, JsValue>` which is what we'll return to JS (where an
2177    /// error is a failed future).
2178    pub trait IntoJsResult {
2179        fn into_js_result(self) -> Result<JsValue, JsValue>;
2180    }
2181
2182    impl IntoJsResult for () {
2183        fn into_js_result(self) -> Result<JsValue, JsValue> {
2184            Ok(JsValue::undefined())
2185        }
2186    }
2187
2188    impl<T: Into<JsValue>> IntoJsResult for T {
2189        fn into_js_result(self) -> Result<JsValue, JsValue> {
2190            Ok(self.into())
2191        }
2192    }
2193
2194    impl<T: Into<JsValue>, E: Into<JsValue>> IntoJsResult for Result<T, E> {
2195        fn into_js_result(self) -> Result<JsValue, JsValue> {
2196            match self {
2197                Ok(e) => Ok(e.into()),
2198                Err(e) => Err(e.into()),
2199            }
2200        }
2201    }
2202
2203    impl<E: Into<JsValue>> IntoJsResult for Result<(), E> {
2204        fn into_js_result(self) -> Result<JsValue, JsValue> {
2205            match self {
2206                Ok(()) => Ok(JsValue::undefined()),
2207                Err(e) => Err(e.into()),
2208            }
2209        }
2210    }
2211
2212    /// An internal helper trait for usage in `#[wasm_bindgen(start)]`
2213    /// functions to throw the error (if it is `Err`).
2214    pub trait Start {
2215        fn start(self);
2216    }
2217
2218    impl Start for () {
2219        #[inline]
2220        fn start(self) {}
2221    }
2222
2223    impl<E: Into<JsValue>> Start for Result<(), E> {
2224        #[inline]
2225        fn start(self) {
2226            if let Err(e) = self {
2227                crate::throw_val(e.into());
2228            }
2229        }
2230    }
2231
2232    /// An internal helper struct for usage in `#[wasm_bindgen(main)]`
2233    /// functions to throw the error (if it is `Err`).
2234    pub struct MainWrapper<T>(pub Option<T>);
2235
2236    pub trait Main {
2237        fn __wasm_bindgen_main(&mut self);
2238    }
2239
2240    impl Main for &mut &mut MainWrapper<()> {
2241        #[inline]
2242        fn __wasm_bindgen_main(&mut self) {}
2243    }
2244
2245    impl Main for &mut &mut MainWrapper<Infallible> {
2246        #[inline]
2247        fn __wasm_bindgen_main(&mut self) {}
2248    }
2249
2250    impl<E: Into<JsValue>> Main for &mut &mut MainWrapper<Result<(), E>> {
2251        #[inline]
2252        fn __wasm_bindgen_main(&mut self) {
2253            if let Err(e) = self.0.take().unwrap() {
2254                crate::throw_val(e.into());
2255            }
2256        }
2257    }
2258
2259    impl<E: core::fmt::Debug> Main for &mut MainWrapper<Result<(), E>> {
2260        #[inline]
2261        fn __wasm_bindgen_main(&mut self) {
2262            if let Err(e) = self.0.take().unwrap() {
2263                crate::throw_str(&alloc::format!("{:?}", e));
2264            }
2265        }
2266    }
2267
2268    pub const fn flat_len<T, const SIZE: usize>(slices: [&[T]; SIZE]) -> usize {
2269        let mut len = 0;
2270        let mut i = 0;
2271        while i < slices.len() {
2272            len += slices[i].len();
2273            i += 1;
2274        }
2275        len
2276    }
2277
2278    pub const fn flat_byte_slices<const RESULT_LEN: usize, const SIZE: usize>(
2279        slices: [&[u8]; SIZE],
2280    ) -> [u8; RESULT_LEN] {
2281        let mut result = [0; RESULT_LEN];
2282
2283        let mut slice_index = 0;
2284        let mut result_offset = 0;
2285
2286        while slice_index < slices.len() {
2287            let mut i = 0;
2288            let slice = slices[slice_index];
2289            while i < slice.len() {
2290                result[result_offset] = slice[i];
2291                i += 1;
2292                result_offset += 1;
2293            }
2294            slice_index += 1;
2295        }
2296
2297        result
2298    }
2299
2300    // NOTE: This method is used to encode u32 into a variable-length-integer during the compile-time .
2301    // Generally speaking, the length of the encoded variable-length-integer depends on the size of the integer
2302    // but the maximum capacity can be used here to simplify the amount of code during the compile-time .
2303    pub const fn encode_u32_to_fixed_len_bytes(value: u32) -> [u8; 5] {
2304        let mut result: [u8; 5] = [0; 5];
2305        let mut i = 0;
2306        while i < 4 {
2307            result[i] = ((value >> (7 * i)) | 0x80) as u8;
2308            i += 1;
2309        }
2310        result[4] = (value >> (7 * 4)) as u8;
2311        result
2312    }
2313
2314    /// Trait for element types to implement `Into<JsValue>` for vectors of
2315    /// themselves, which isn't possible directly thanks to the orphan rule.
2316    pub trait VectorIntoJsValue: Sized {
2317        fn vector_into_jsvalue(vector: Box<[Self]>) -> JsValue;
2318    }
2319
2320    impl<T: VectorIntoJsValue> From<Box<[T]>> for JsValue {
2321        fn from(vector: Box<[T]>) -> Self {
2322            T::vector_into_jsvalue(vector)
2323        }
2324    }
2325
2326    pub fn js_value_vector_into_jsvalue<T: Into<JsValue>>(vector: Box<[T]>) -> JsValue {
2327        let result = unsafe { JsValue::_new(super::__wbindgen_array_new()) };
2328        for value in vector.into_vec() {
2329            let js: JsValue = value.into();
2330            unsafe { super::__wbindgen_array_push(result.idx, js.idx) }
2331            // `__wbindgen_array_push` takes ownership over `js` and has already dropped it,
2332            // so don't drop it again.
2333            mem::forget(js);
2334        }
2335        result
2336    }
2337}
2338
2339/// A wrapper type around slices and vectors for binding the `Uint8ClampedArray`
2340/// array in JS.
2341///
2342/// If you need to invoke a JS API which must take `Uint8ClampedArray` array,
2343/// then you can define it as taking one of these types:
2344///
2345/// * `Clamped<&[u8]>`
2346/// * `Clamped<&mut [u8]>`
2347/// * `Clamped<Vec<u8>>`
2348///
2349/// All of these types will show up as `Uint8ClampedArray` in JS and will have
2350/// different forms of ownership in Rust.
2351#[derive(Copy, Clone, PartialEq, Debug, Eq)]
2352pub struct Clamped<T>(pub T);
2353
2354impl<T> Deref for Clamped<T> {
2355    type Target = T;
2356
2357    fn deref(&self) -> &T {
2358        &self.0
2359    }
2360}
2361
2362impl<T> DerefMut for Clamped<T> {
2363    fn deref_mut(&mut self) -> &mut T {
2364        &mut self.0
2365    }
2366}
2367
2368/// Convenience type for use on exported `fn() -> Result<T, JsError>` functions, where you wish to
2369/// throw a JavaScript `Error` object.
2370///
2371/// You can get wasm_bindgen to throw basic errors by simply returning
2372/// `Err(JsError::new("message"))` from such a function.
2373///
2374/// For more complex error handling, `JsError` implements `From<T> where T: std::error::Error` by
2375/// converting it to a string, so you can use it with `?`. Many Rust error types already do this,
2376/// and you can use [`thiserror`](https://crates.io/crates/thiserror) to derive Display
2377/// implementations easily or use any number of boxed error types that implement it already.
2378///
2379///
2380/// To allow JavaScript code to catch only your errors, you may wish to add a subclass of `Error`
2381/// in a JS module, and then implement `Into<JsValue>` directly on a type and instantiate that
2382/// subclass. In that case, you would not need `JsError` at all.
2383///
2384/// ### Basic example
2385///
2386/// ```rust,no_run
2387/// use wasm_bindgen::prelude::*;
2388///
2389/// #[wasm_bindgen]
2390/// pub fn throwing_function() -> Result<(), JsError> {
2391///     Err(JsError::new("message"))
2392/// }
2393/// ```
2394///
2395/// ### Complex Example
2396///
2397/// ```rust,no_run
2398/// use wasm_bindgen::prelude::*;
2399///
2400/// #[derive(Debug, Clone)]
2401/// enum MyErrorType {
2402///     SomeError,
2403/// }
2404///
2405/// use core::fmt;
2406/// impl std::error::Error for MyErrorType {}
2407/// impl fmt::Display for MyErrorType {
2408///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2409///         write!(f, "display implementation becomes the error message")
2410///     }
2411/// }
2412///
2413/// fn internal_api() -> Result<(), MyErrorType> {
2414///     Err(MyErrorType::SomeError)
2415/// }
2416///
2417/// #[wasm_bindgen]
2418/// pub fn throwing_function() -> Result<(), JsError> {
2419///     internal_api()?;
2420///     Ok(())
2421/// }
2422///
2423/// ```
2424#[derive(Clone, Debug)]
2425pub struct JsError {
2426    value: JsValue,
2427}
2428
2429impl JsError {
2430    /// Construct a JavaScript `Error` object with a string message
2431    #[inline]
2432    pub fn new(s: &str) -> JsError {
2433        Self {
2434            value: unsafe { JsValue::_new(crate::__wbindgen_error_new(s.as_ptr(), s.len())) },
2435        }
2436    }
2437}
2438
2439if_std! {
2440    impl<E> From<E> for JsError
2441    where
2442        E: std::error::Error,
2443    {
2444        fn from(error: E) -> Self {
2445            JsError::new(&error.to_string())
2446        }
2447    }
2448}
2449
2450impl From<JsError> for JsValue {
2451    fn from(error: JsError) -> Self {
2452        error.value
2453    }
2454}
2455
2456macro_rules! typed_arrays {
2457        ($($ty:ident $ctor:ident $clamped_ctor:ident,)*) => {
2458            $(
2459                impl From<Box<[$ty]>> for JsValue {
2460                    fn from(mut vector: Box<[$ty]>) -> Self {
2461                        let result = unsafe { JsValue::_new($ctor(vector.as_mut_ptr(), vector.len())) };
2462                        mem::forget(vector);
2463                        result
2464                    }
2465                }
2466
2467                impl From<Clamped<Box<[$ty]>>> for JsValue {
2468                    fn from(mut vector: Clamped<Box<[$ty]>>) -> Self {
2469                        let result = unsafe { JsValue::_new($clamped_ctor(vector.as_mut_ptr(), vector.len())) };
2470                        mem::forget(vector);
2471                        result
2472                    }
2473                }
2474            )*
2475        };
2476    }
2477
2478typed_arrays! {
2479    u8 __wbindgen_uint8_array_new __wbindgen_uint8_clamped_array_new,
2480    u16 __wbindgen_uint16_array_new __wbindgen_uint16_array_new,
2481    u32 __wbindgen_uint32_array_new __wbindgen_uint32_array_new,
2482    u64 __wbindgen_biguint64_array_new __wbindgen_biguint64_array_new,
2483    i8 __wbindgen_int8_array_new __wbindgen_int8_array_new,
2484    i16 __wbindgen_int16_array_new __wbindgen_int16_array_new,
2485    i32 __wbindgen_int32_array_new __wbindgen_int32_array_new,
2486    i64 __wbindgen_bigint64_array_new __wbindgen_bigint64_array_new,
2487    f32 __wbindgen_float32_array_new __wbindgen_float32_array_new,
2488    f64 __wbindgen_float64_array_new __wbindgen_float64_array_new,
2489}
2490
2491impl __rt::VectorIntoJsValue for JsValue {
2492    fn vector_into_jsvalue(vector: Box<[JsValue]>) -> JsValue {
2493        __rt::js_value_vector_into_jsvalue::<JsValue>(vector)
2494    }
2495}
2496
2497impl<T: JsObject> __rt::VectorIntoJsValue for T {
2498    fn vector_into_jsvalue(vector: Box<[T]>) -> JsValue {
2499        __rt::js_value_vector_into_jsvalue::<T>(vector)
2500    }
2501}
2502
2503impl __rt::VectorIntoJsValue for String {
2504    fn vector_into_jsvalue(vector: Box<[String]>) -> JsValue {
2505        __rt::js_value_vector_into_jsvalue::<String>(vector)
2506    }
2507}
2508
2509impl<T> From<Vec<T>> for JsValue
2510where
2511    JsValue: From<Box<[T]>>,
2512{
2513    fn from(vector: Vec<T>) -> Self {
2514        JsValue::from(vector.into_boxed_slice())
2515    }
2516}
2517
2518impl<T> From<Clamped<Vec<T>>> for JsValue
2519where
2520    JsValue: From<Clamped<Box<[T]>>>,
2521{
2522    fn from(vector: Clamped<Vec<T>>) -> Self {
2523        JsValue::from(Clamped(vector.0.into_boxed_slice()))
2524    }
2525}