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 #![allow(coherence_leak_check)]
10 #![doc(html_root_url = "https://docs.rs/wasm-bindgen/0.2")]
11 #![cfg_attr(feature = "nightly", feature(unsize))]
12 
13 use core::convert::TryFrom;
14 use core::fmt;
15 use core::marker;
16 use core::mem;
17 use core::ops::{
18     Add, BitAnd, BitOr, BitXor, Deref, DerefMut, Div, Mul, Neg, Not, Rem, Shl, Shr, Sub,
19 };
20 use core::u32;
21 
22 use crate::convert::{FromWasmAbi, WasmOptionalF64, WasmSlice};
23 
24 macro_rules! if_std {
25     ($($i:item)*) => ($(
26         #[cfg(feature = "std")] $i
27     )*)
28 }
29 
30 macro_rules! externs {
31     ($(#[$attr:meta])* extern "C" { $(fn $name:ident($($args:tt)*) -> $ret:ty;)* }) => (
32         #[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))]
33         $(#[$attr])*
34         extern "C" {
35             $(fn $name($($args)*) -> $ret;)*
36         }
37 
38         $(
39             #[cfg(not(all(target_arch = "wasm32", not(target_os = "emscripten"))))]
40             #[allow(unused_variables)]
41             unsafe extern fn $name($($args)*) -> $ret {
42                 panic!("function not implemented on non-wasm32 targets")
43             }
44         )*
45     )
46 }
47 
48 /// A module which is typically glob imported from:
49 ///
50 /// ```
51 /// use wasm_bindgen::prelude::*;
52 /// ```
53 pub mod prelude {
54     pub use crate::JsValue;
55     pub use crate::UnwrapThrowExt;
56     #[doc(hidden)]
57     pub use wasm_bindgen_macro::__wasm_bindgen_class_marker;
58     pub use wasm_bindgen_macro::wasm_bindgen;
59 
60     if_std! {
61         pub use crate::closure::Closure;
62     }
63 }
64 
65 pub mod convert;
66 pub mod describe;
67 
68 mod cast;
69 pub use crate::cast::{JsCast, JsObject};
70 
71 if_std! {
72     extern crate std;
73     use std::prelude::v1::*;
74     pub mod closure;
75     mod externref;
76 
77     mod cache;
78     pub use cache::intern::{intern, unintern};
79 }
80 
81 /// Representation of an object owned by JS.
82 ///
83 /// A `JsValue` doesn't actually live in Rust right now but actually in a table
84 /// owned by the `wasm-bindgen` generated JS glue code. Eventually the ownership
85 /// will transfer into wasm directly and this will likely become more efficient,
86 /// but for now it may be slightly slow.
87 pub struct JsValue {
88     idx: u32,
89     _marker: marker::PhantomData<*mut u8>, // not at all threadsafe
90 }
91 
92 const JSIDX_OFFSET: u32 = 32; // keep in sync with js/mod.rs
93 const JSIDX_UNDEFINED: u32 = JSIDX_OFFSET + 0;
94 const JSIDX_NULL: u32 = JSIDX_OFFSET + 1;
95 const JSIDX_TRUE: u32 = JSIDX_OFFSET + 2;
96 const JSIDX_FALSE: u32 = JSIDX_OFFSET + 3;
97 const JSIDX_RESERVED: u32 = JSIDX_OFFSET + 4;
98 
99 impl JsValue {
100     /// The `null` JS value constant.
101     pub const NULL: JsValue = JsValue {
102         idx: JSIDX_NULL,
103         _marker: marker::PhantomData,
104     };
105 
106     /// The `undefined` JS value constant.
107     pub const UNDEFINED: JsValue = JsValue {
108         idx: JSIDX_UNDEFINED,
109         _marker: marker::PhantomData,
110     };
111 
112     /// The `true` JS value constant.
113     pub const TRUE: JsValue = JsValue {
114         idx: JSIDX_TRUE,
115         _marker: marker::PhantomData,
116     };
117 
118     /// The `false` JS value constant.
119     pub const FALSE: JsValue = JsValue {
120         idx: JSIDX_FALSE,
121         _marker: marker::PhantomData,
122     };
123 
124     #[inline]
_new(idx: u32) -> JsValue125     fn _new(idx: u32) -> JsValue {
126         JsValue {
127             idx,
128             _marker: marker::PhantomData,
129         }
130     }
131 
132     /// Creates a new JS value which is a string.
133     ///
134     /// The utf-8 string provided is copied to the JS heap and the string will
135     /// be owned by the JS garbage collector.
136     #[inline]
from_str(s: &str) -> JsValue137     pub fn from_str(s: &str) -> JsValue {
138         unsafe { JsValue::_new(__wbindgen_string_new(s.as_ptr(), s.len())) }
139     }
140 
141     /// Creates a new JS value which is a number.
142     ///
143     /// This function creates a JS value representing a number (a heap
144     /// allocated number) and returns a handle to the JS version of it.
145     #[inline]
from_f64(n: f64) -> JsValue146     pub fn from_f64(n: f64) -> JsValue {
147         unsafe { JsValue::_new(__wbindgen_number_new(n)) }
148     }
149 
150     /// Creates a new JS value which is a bigint from a string representing a number.
151     ///
152     /// This function creates a JS value representing a bigint (a heap
153     /// allocated large integer) and returns a handle to the JS version of it.
154     #[inline]
bigint_from_str(s: &str) -> JsValue155     pub fn bigint_from_str(s: &str) -> JsValue {
156         unsafe { JsValue::_new(__wbindgen_bigint_new(s.as_ptr(), s.len())) }
157     }
158 
159     /// Creates a new JS value which is a boolean.
160     ///
161     /// This function creates a JS object representing a boolean (a heap
162     /// allocated boolean) and returns a handle to the JS version of it.
163     #[inline]
from_bool(b: bool) -> JsValue164     pub fn from_bool(b: bool) -> JsValue {
165         if b {
166             JsValue::TRUE
167         } else {
168             JsValue::FALSE
169         }
170     }
171 
172     /// Creates a new JS value representing `undefined`.
173     #[inline]
undefined() -> JsValue174     pub fn undefined() -> JsValue {
175         JsValue::UNDEFINED
176     }
177 
178     /// Creates a new JS value representing `null`.
179     #[inline]
null() -> JsValue180     pub fn null() -> JsValue {
181         JsValue::NULL
182     }
183 
184     /// Creates a new JS symbol with the optional description specified.
185     ///
186     /// This function will invoke the `Symbol` constructor in JS and return the
187     /// JS object corresponding to the symbol created.
symbol(description: Option<&str>) -> JsValue188     pub fn symbol(description: Option<&str>) -> JsValue {
189         unsafe {
190             match description {
191                 Some(description) => JsValue::_new(__wbindgen_symbol_named_new(
192                     description.as_ptr(),
193                     description.len(),
194                 )),
195                 None => JsValue::_new(__wbindgen_symbol_anonymous_new()),
196             }
197         }
198     }
199 
200     /// Creates a new `JsValue` from the JSON serialization of the object `t`
201     /// provided.
202     ///
203     /// This function will serialize the provided value `t` to a JSON string,
204     /// send the JSON string to JS, parse it into a JS object, and then return
205     /// a handle to the JS object. This is unlikely to be super speedy so it's
206     /// not recommended for large payloads, but it's a nice to have in some
207     /// situations!
208     ///
209     /// Usage of this API requires activating the `serde-serialize` feature of
210     /// the `wasm-bindgen` crate.
211     ///
212     /// # Errors
213     ///
214     /// Returns any error encountered when serializing `T` into JSON.
215     #[cfg(feature = "serde-serialize")]
from_serde<T>(t: &T) -> serde_json::Result<JsValue> where T: serde::ser::Serialize + ?Sized,216     pub fn from_serde<T>(t: &T) -> serde_json::Result<JsValue>
217     where
218         T: serde::ser::Serialize + ?Sized,
219     {
220         let s = serde_json::to_string(t)?;
221         unsafe { Ok(JsValue::_new(__wbindgen_json_parse(s.as_ptr(), s.len()))) }
222     }
223 
224     /// Invokes `JSON.stringify` on this value and then parses the resulting
225     /// JSON into an arbitrary Rust value.
226     ///
227     /// This function will first call `JSON.stringify` on the `JsValue` itself.
228     /// The resulting string is then passed into Rust which then parses it as
229     /// JSON into the resulting value.
230     ///
231     /// Usage of this API requires activating the `serde-serialize` feature of
232     /// the `wasm-bindgen` crate.
233     ///
234     /// # Errors
235     ///
236     /// Returns any error encountered when parsing the JSON into a `T`.
237     #[cfg(feature = "serde-serialize")]
into_serde<T>(&self) -> serde_json::Result<T> where T: for<'a> serde::de::Deserialize<'a>,238     pub fn into_serde<T>(&self) -> serde_json::Result<T>
239     where
240         T: for<'a> serde::de::Deserialize<'a>,
241     {
242         unsafe {
243             let ret = __wbindgen_json_serialize(self.idx);
244             let s = String::from_abi(ret);
245             serde_json::from_str(&s)
246         }
247     }
248 
249     /// Returns the `f64` value of this JS value if it's an instance of a
250     /// number.
251     ///
252     /// If this JS value is not an instance of a number then this returns
253     /// `None`.
254     #[inline]
as_f64(&self) -> Option<f64>255     pub fn as_f64(&self) -> Option<f64> {
256         unsafe { FromWasmAbi::from_abi(__wbindgen_number_get(self.idx)) }
257     }
258 
259     /// Tests whether this JS value is a JS string.
260     #[inline]
is_string(&self) -> bool261     pub fn is_string(&self) -> bool {
262         unsafe { __wbindgen_is_string(self.idx) == 1 }
263     }
264 
265     /// If this JS value is a string value, this function copies the JS string
266     /// value into wasm linear memory, encoded as UTF-8, and returns it as a
267     /// Rust `String`.
268     ///
269     /// To avoid the copying and re-encoding, consider the
270     /// `JsString::try_from()` function from [js-sys](https://docs.rs/js-sys)
271     /// instead.
272     ///
273     /// If this JS value is not an instance of a string or if it's not valid
274     /// utf-8 then this returns `None`.
275     ///
276     /// # UTF-16 vs UTF-8
277     ///
278     /// JavaScript strings in general are encoded as UTF-16, but Rust strings
279     /// are encoded as UTF-8. This can cause the Rust string to look a bit
280     /// different than the JS string sometimes. For more details see the
281     /// [documentation about the `str` type][caveats] which contains a few
282     /// caveats about the encodings.
283     ///
284     /// [caveats]: https://rustwasm.github.io/docs/wasm-bindgen/reference/types/str.html
285     #[cfg(feature = "std")]
286     #[inline]
as_string(&self) -> Option<String>287     pub fn as_string(&self) -> Option<String> {
288         unsafe { FromWasmAbi::from_abi(__wbindgen_string_get(self.idx)) }
289     }
290 
291     /// Returns the `bool` value of this JS value if it's an instance of a
292     /// boolean.
293     ///
294     /// If this JS value is not an instance of a boolean then this returns
295     /// `None`.
296     #[inline]
as_bool(&self) -> Option<bool>297     pub fn as_bool(&self) -> Option<bool> {
298         unsafe {
299             match __wbindgen_boolean_get(self.idx) {
300                 0 => Some(false),
301                 1 => Some(true),
302                 _ => None,
303             }
304         }
305     }
306 
307     /// Tests whether this JS value is `null`
308     #[inline]
is_null(&self) -> bool309     pub fn is_null(&self) -> bool {
310         unsafe { __wbindgen_is_null(self.idx) == 1 }
311     }
312 
313     /// Tests whether this JS value is `undefined`
314     #[inline]
is_undefined(&self) -> bool315     pub fn is_undefined(&self) -> bool {
316         unsafe { __wbindgen_is_undefined(self.idx) == 1 }
317     }
318 
319     /// Tests whether the type of this JS value is `symbol`
320     #[inline]
is_symbol(&self) -> bool321     pub fn is_symbol(&self) -> bool {
322         unsafe { __wbindgen_is_symbol(self.idx) == 1 }
323     }
324 
325     /// Tests whether `typeof self == "object" && self !== null`.
326     #[inline]
is_object(&self) -> bool327     pub fn is_object(&self) -> bool {
328         unsafe { __wbindgen_is_object(self.idx) == 1 }
329     }
330 
331     /// Tests whether the type of this JS value is `function`.
332     #[inline]
is_function(&self) -> bool333     pub fn is_function(&self) -> bool {
334         unsafe { __wbindgen_is_function(self.idx) == 1 }
335     }
336 
337     /// Tests whether the type of this JS value is `function`.
338     #[inline]
is_bigint(&self) -> bool339     pub fn is_bigint(&self) -> bool {
340         unsafe { __wbindgen_is_bigint(self.idx) == 1 }
341     }
342 
343     /// Applies the unary `typeof` JS operator on a `JsValue`.
344     ///
345     /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof)
346     #[inline]
js_typeof(&self) -> JsValue347     pub fn js_typeof(&self) -> JsValue {
348         unsafe { JsValue::_new(__wbindgen_typeof(self.idx)) }
349     }
350 
351     /// Applies the binary `in` JS operator on the two `JsValue`s.
352     ///
353     /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof)
354     #[inline]
js_in(&self, obj: &JsValue) -> bool355     pub fn js_in(&self, obj: &JsValue) -> bool {
356         unsafe { __wbindgen_in(self.idx, obj.idx) == 1 }
357     }
358 
359     /// Tests whether the value is ["truthy"].
360     ///
361     /// ["truthy"]: https://developer.mozilla.org/en-US/docs/Glossary/Truthy
362     #[inline]
is_truthy(&self) -> bool363     pub fn is_truthy(&self) -> bool {
364         !self.is_falsy()
365     }
366 
367     /// Tests whether the value is ["falsy"].
368     ///
369     /// ["falsy"]: https://developer.mozilla.org/en-US/docs/Glossary/Falsy
370     #[inline]
is_falsy(&self) -> bool371     pub fn is_falsy(&self) -> bool {
372         unsafe { __wbindgen_is_falsy(self.idx) == 1 }
373     }
374 
375     /// Get a string representation of the JavaScript object for debugging.
376     #[cfg(feature = "std")]
as_debug_string(&self) -> String377     fn as_debug_string(&self) -> String {
378         unsafe {
379             let mut ret = [0; 2];
380             __wbindgen_debug_string(&mut ret, self.idx);
381             let data = Vec::from_raw_parts(ret[0] as *mut u8, ret[1], ret[1]);
382             String::from_utf8_unchecked(data)
383         }
384     }
385 
386     /// Compare two `JsValue`s for equality, using the `==` operator in JS.
387     ///
388     /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Equality)
389     #[inline]
loose_eq(&self, other: &Self) -> bool390     pub fn loose_eq(&self, other: &Self) -> bool {
391         unsafe { __wbindgen_jsval_loose_eq(self.idx, other.idx) != 0 }
392     }
393 
394     /// Applies the unary `~` JS operator on a `JsValue`.
395     ///
396     /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_NOT)
397     #[inline]
bit_not(&self) -> JsValue398     pub fn bit_not(&self) -> JsValue {
399         unsafe { JsValue::_new(__wbindgen_bit_not(self.idx)) }
400     }
401 
402     /// Applies the binary `>>>` JS operator on the two `JsValue`s.
403     ///
404     /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Unsigned_right_shift)
405     #[inline]
unsigned_shr(&self, rhs: &Self) -> u32406     pub fn unsigned_shr(&self, rhs: &Self) -> u32 {
407         unsafe { __wbindgen_unsigned_shr(self.idx, rhs.idx) }
408     }
409 
410     /// Applies the binary `/` JS operator on two `JsValue`s, catching and returning any `RangeError` thrown.
411     ///
412     /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Division)
413     #[inline]
checked_div(&self, rhs: &Self) -> Self414     pub fn checked_div(&self, rhs: &Self) -> Self {
415         unsafe { JsValue::_new(__wbindgen_checked_div(self.idx, rhs.idx)) }
416     }
417 
418     /// Applies the binary `**` JS operator on the two `JsValue`s.
419     ///
420     /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Exponentiation)
421     #[inline]
pow(&self, rhs: &Self) -> Self422     pub fn pow(&self, rhs: &Self) -> Self {
423         unsafe { JsValue::_new(__wbindgen_pow(self.idx, rhs.idx)) }
424     }
425 
426     /// Applies the binary `<` JS operator on the two `JsValue`s.
427     ///
428     /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Less_than)
429     #[inline]
lt(&self, other: &Self) -> bool430     pub fn lt(&self, other: &Self) -> bool {
431         unsafe { __wbindgen_lt(self.idx, other.idx) == 1 }
432     }
433 
434     /// Applies the binary `<=` JS operator on the two `JsValue`s.
435     ///
436     /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Less_than_or_equal)
437     #[inline]
le(&self, other: &Self) -> bool438     pub fn le(&self, other: &Self) -> bool {
439         unsafe { __wbindgen_le(self.idx, other.idx) == 1 }
440     }
441 
442     /// Applies the binary `>=` JS operator on the two `JsValue`s.
443     ///
444     /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Greater_than_or_equal)
445     #[inline]
ge(&self, other: &Self) -> bool446     pub fn ge(&self, other: &Self) -> bool {
447         unsafe { __wbindgen_ge(self.idx, other.idx) == 1 }
448     }
449 
450     /// Applies the binary `>` JS operator on the two `JsValue`s.
451     ///
452     /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Greater_than)
453     #[inline]
gt(&self, other: &Self) -> bool454     pub fn gt(&self, other: &Self) -> bool {
455         unsafe { __wbindgen_gt(self.idx, other.idx) == 1 }
456     }
457 
458     /// Applies the unary `+` JS operator on a `JsValue`. Can throw.
459     ///
460     /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Unary_plus)
461     #[inline]
unchecked_into_f64(&self) -> f64462     pub fn unchecked_into_f64(&self) -> f64 {
463         unsafe { __wbindgen_as_number(self.idx) }
464     }
465 }
466 
467 impl PartialEq for JsValue {
468     /// Compares two `JsValue`s for equality, using the `===` operator in JS.
469     ///
470     /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Strict_equality)
471     #[inline]
eq(&self, other: &Self) -> bool472     fn eq(&self, other: &Self) -> bool {
473         unsafe { __wbindgen_jsval_eq(self.idx, other.idx) != 0 }
474     }
475 }
476 
477 impl PartialEq<bool> for JsValue {
478     #[inline]
eq(&self, other: &bool) -> bool479     fn eq(&self, other: &bool) -> bool {
480         self.as_bool() == Some(*other)
481     }
482 }
483 
484 impl PartialEq<str> for JsValue {
485     #[inline]
eq(&self, other: &str) -> bool486     fn eq(&self, other: &str) -> bool {
487         *self == JsValue::from_str(other)
488     }
489 }
490 
491 impl<'a> PartialEq<&'a str> for JsValue {
492     #[inline]
eq(&self, other: &&'a str) -> bool493     fn eq(&self, other: &&'a str) -> bool {
494         <JsValue as PartialEq<str>>::eq(self, other)
495     }
496 }
497 
498 if_std! {
499     impl PartialEq<String> for JsValue {
500         #[inline]
501         fn eq(&self, other: &String) -> bool {
502             <JsValue as PartialEq<str>>::eq(self, other)
503         }
504     }
505     impl<'a> PartialEq<&'a String> for JsValue {
506         #[inline]
507         fn eq(&self, other: &&'a String) -> bool {
508             <JsValue as PartialEq<str>>::eq(self, other)
509         }
510     }
511 }
512 
513 macro_rules! forward_deref_unop {
514     (impl $imp:ident, $method:ident for $t:ty) => {
515         impl $imp for $t {
516             type Output = <&'static $t as $imp>::Output;
517 
518             #[inline]
519             fn $method(self) -> <&'static $t as $imp>::Output {
520                 $imp::$method(&self)
521             }
522         }
523     };
524 }
525 
526 macro_rules! forward_deref_binop {
527     (impl $imp:ident, $method:ident for $t:ty) => {
528         impl<'a> $imp<$t> for &'a $t {
529             type Output = <&'static $t as $imp<&'static $t>>::Output;
530 
531             #[inline]
532             fn $method(self, other: $t) -> <&'static $t as $imp<&'static $t>>::Output {
533                 $imp::$method(self, &other)
534             }
535         }
536 
537         impl $imp<&$t> for $t {
538             type Output = <&'static $t as $imp<&'static $t>>::Output;
539 
540             #[inline]
541             fn $method(self, other: &$t) -> <&'static $t as $imp<&'static $t>>::Output {
542                 $imp::$method(&self, other)
543             }
544         }
545 
546         impl $imp<$t> for $t {
547             type Output = <&'static $t as $imp<&'static $t>>::Output;
548 
549             #[inline]
550             fn $method(self, other: $t) -> <&'static $t as $imp<&'static $t>>::Output {
551                 $imp::$method(&self, &other)
552             }
553         }
554     };
555 }
556 
557 impl Not for &JsValue {
558     type Output = bool;
559 
560     /// Applies the `!` JS operator on a `JsValue`.
561     ///
562     /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_NOT)
563     #[inline]
not(self) -> Self::Output564     fn not(self) -> Self::Output {
565         JsValue::is_falsy(self)
566     }
567 }
568 
569 forward_deref_unop!(impl Not, not for JsValue);
570 
571 impl TryFrom<JsValue> for f64 {
572     type Error = JsValue;
573 
574     /// Applies the unary `+` JS operator on a `JsValue`.
575     /// Returns the numeric result on success, or the JS error value on error.
576     ///
577     /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Unary_plus)
578     #[inline]
try_from(val: JsValue) -> Result<Self, Self::Error>579     fn try_from(val: JsValue) -> Result<Self, Self::Error> {
580         f64::try_from(&val)
581     }
582 }
583 
584 impl TryFrom<&JsValue> for f64 {
585     type Error = JsValue;
586 
587     /// Applies the unary `+` JS operator on a `JsValue`.
588     /// Returns the numeric result on success, or the JS error value on error.
589     ///
590     /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Unary_plus)
591     #[inline]
try_from(val: &JsValue) -> Result<Self, Self::Error>592     fn try_from(val: &JsValue) -> Result<Self, Self::Error> {
593         let jsval = unsafe { JsValue::_new(__wbindgen_try_into_number(val.idx)) };
594         return match jsval.as_f64() {
595             Some(num) => Ok(num),
596             None => Err(jsval),
597         };
598     }
599 }
600 
601 impl Neg for &JsValue {
602     type Output = JsValue;
603 
604     /// Applies the unary `-` JS operator on a `JsValue`.
605     ///
606     /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Unary_negation)
607     #[inline]
neg(self) -> Self::Output608     fn neg(self) -> Self::Output {
609         unsafe { JsValue::_new(__wbindgen_neg(self.idx)) }
610     }
611 }
612 
613 forward_deref_unop!(impl Neg, neg for JsValue);
614 
615 impl BitAnd for &JsValue {
616     type Output = JsValue;
617 
618     /// Applies the binary `&` JS operator on two `JsValue`s.
619     ///
620     /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_AND)
621     #[inline]
bitand(self, rhs: Self) -> Self::Output622     fn bitand(self, rhs: Self) -> Self::Output {
623         unsafe { JsValue::_new(__wbindgen_bit_and(self.idx, rhs.idx)) }
624     }
625 }
626 
627 forward_deref_binop!(impl BitAnd, bitand for JsValue);
628 
629 impl BitOr for &JsValue {
630     type Output = JsValue;
631 
632     /// Applies the binary `|` JS operator on two `JsValue`s.
633     ///
634     /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_OR)
635     #[inline]
bitor(self, rhs: Self) -> Self::Output636     fn bitor(self, rhs: Self) -> Self::Output {
637         unsafe { JsValue::_new(__wbindgen_bit_or(self.idx, rhs.idx)) }
638     }
639 }
640 
641 forward_deref_binop!(impl BitOr, bitor for JsValue);
642 
643 impl BitXor for &JsValue {
644     type Output = JsValue;
645 
646     /// Applies the binary `^` JS operator on two `JsValue`s.
647     ///
648     /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_XOR)
649     #[inline]
bitxor(self, rhs: Self) -> Self::Output650     fn bitxor(self, rhs: Self) -> Self::Output {
651         unsafe { JsValue::_new(__wbindgen_bit_xor(self.idx, rhs.idx)) }
652     }
653 }
654 
655 forward_deref_binop!(impl BitXor, bitxor for JsValue);
656 
657 impl Shl for &JsValue {
658     type Output = JsValue;
659 
660     /// Applies the binary `<<` JS operator on two `JsValue`s.
661     ///
662     /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Left_shift)
663     #[inline]
shl(self, rhs: Self) -> Self::Output664     fn shl(self, rhs: Self) -> Self::Output {
665         unsafe { JsValue::_new(__wbindgen_shl(self.idx, rhs.idx)) }
666     }
667 }
668 
669 forward_deref_binop!(impl Shl, shl for JsValue);
670 
671 impl Shr for &JsValue {
672     type Output = JsValue;
673 
674     /// Applies the binary `>>` JS operator on two `JsValue`s.
675     ///
676     /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Right_shift)
677     #[inline]
shr(self, rhs: Self) -> Self::Output678     fn shr(self, rhs: Self) -> Self::Output {
679         unsafe { JsValue::_new(__wbindgen_shr(self.idx, rhs.idx)) }
680     }
681 }
682 
683 forward_deref_binop!(impl Shr, shr for JsValue);
684 
685 impl Add for &JsValue {
686     type Output = JsValue;
687 
688     /// Applies the binary `+` JS operator on two `JsValue`s.
689     ///
690     /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Addition)
691     #[inline]
add(self, rhs: Self) -> Self::Output692     fn add(self, rhs: Self) -> Self::Output {
693         unsafe { JsValue::_new(__wbindgen_add(self.idx, rhs.idx)) }
694     }
695 }
696 
697 forward_deref_binop!(impl Add, add for JsValue);
698 
699 impl Sub for &JsValue {
700     type Output = JsValue;
701 
702     /// Applies the binary `-` JS operator on two `JsValue`s.
703     ///
704     /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Subtraction)
705     #[inline]
sub(self, rhs: Self) -> Self::Output706     fn sub(self, rhs: Self) -> Self::Output {
707         unsafe { JsValue::_new(__wbindgen_sub(self.idx, rhs.idx)) }
708     }
709 }
710 
711 forward_deref_binop!(impl Sub, sub for JsValue);
712 
713 impl Div for &JsValue {
714     type Output = JsValue;
715 
716     /// Applies the binary `/` JS operator on two `JsValue`s.
717     ///
718     /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Division)
719     #[inline]
div(self, rhs: Self) -> Self::Output720     fn div(self, rhs: Self) -> Self::Output {
721         unsafe { JsValue::_new(__wbindgen_div(self.idx, rhs.idx)) }
722     }
723 }
724 
725 forward_deref_binop!(impl Div, div for JsValue);
726 
727 impl Mul for &JsValue {
728     type Output = JsValue;
729 
730     /// Applies the binary `*` JS operator on two `JsValue`s.
731     ///
732     /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Multiplication)
733     #[inline]
mul(self, rhs: Self) -> Self::Output734     fn mul(self, rhs: Self) -> Self::Output {
735         unsafe { JsValue::_new(__wbindgen_mul(self.idx, rhs.idx)) }
736     }
737 }
738 
739 forward_deref_binop!(impl Mul, mul for JsValue);
740 
741 impl Rem for &JsValue {
742     type Output = JsValue;
743 
744     /// Applies the binary `%` JS operator on two `JsValue`s.
745     ///
746     /// [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Remainder)
747     #[inline]
rem(self, rhs: Self) -> Self::Output748     fn rem(self, rhs: Self) -> Self::Output {
749         unsafe { JsValue::_new(__wbindgen_rem(self.idx, rhs.idx)) }
750     }
751 }
752 
753 forward_deref_binop!(impl Rem, rem for JsValue);
754 
755 impl<'a> From<&'a str> for JsValue {
756     #[inline]
from(s: &'a str) -> JsValue757     fn from(s: &'a str) -> JsValue {
758         JsValue::from_str(s)
759     }
760 }
761 
762 if_std! {
763     impl<'a> From<&'a String> for JsValue {
764         #[inline]
765         fn from(s: &'a String) -> JsValue {
766             JsValue::from_str(s)
767         }
768     }
769 
770     impl From<String> for JsValue {
771         #[inline]
772         fn from(s: String) -> JsValue {
773             JsValue::from_str(&s)
774         }
775     }
776 }
777 
778 impl From<bool> for JsValue {
779     #[inline]
from(s: bool) -> JsValue780     fn from(s: bool) -> JsValue {
781         JsValue::from_bool(s)
782     }
783 }
784 
785 impl<'a, T> From<&'a T> for JsValue
786 where
787     T: JsCast,
788 {
789     #[inline]
from(s: &'a T) -> JsValue790     fn from(s: &'a T) -> JsValue {
791         s.as_ref().clone()
792     }
793 }
794 
795 impl<T> From<Option<T>> for JsValue
796 where
797     JsValue: From<T>,
798 {
799     #[inline]
from(s: Option<T>) -> JsValue800     fn from(s: Option<T>) -> JsValue {
801         match s {
802             Some(s) => s.into(),
803             None => JsValue::undefined(),
804         }
805     }
806 }
807 
808 impl JsCast for JsValue {
809     // everything is a `JsValue`!
810     #[inline]
instanceof(_val: &JsValue) -> bool811     fn instanceof(_val: &JsValue) -> bool {
812         true
813     }
814     #[inline]
unchecked_from_js(val: JsValue) -> Self815     fn unchecked_from_js(val: JsValue) -> Self {
816         val
817     }
818     #[inline]
unchecked_from_js_ref(val: &JsValue) -> &Self819     fn unchecked_from_js_ref(val: &JsValue) -> &Self {
820         val
821     }
822 }
823 
824 impl AsRef<JsValue> for JsValue {
825     #[inline]
as_ref(&self) -> &JsValue826     fn as_ref(&self) -> &JsValue {
827         self
828     }
829 }
830 
831 macro_rules! numbers {
832     ($($n:ident)*) => ($(
833         impl PartialEq<$n> for JsValue {
834             #[inline]
835             fn eq(&self, other: &$n) -> bool {
836                 self.as_f64() == Some(f64::from(*other))
837             }
838         }
839 
840         impl From<$n> for JsValue {
841             #[inline]
842             fn from(n: $n) -> JsValue {
843                 JsValue::from_f64(n.into())
844             }
845         }
846     )*)
847 }
848 
849 numbers! { i8 u8 i16 u16 i32 u32 f32 f64 }
850 
851 macro_rules! big_numbers {
852     ($($n:ident)*) => ($(
853         impl PartialEq<$n> for JsValue {
854             #[inline]
855             fn eq(&self, other: &$n) -> bool {
856                 self == &JsValue::from(*other)
857             }
858         }
859 
860         impl From<$n> for JsValue {
861             #[inline]
862             fn from(n: $n) -> JsValue {
863                 JsValue::bigint_from_str(&n.to_string())
864             }
865         }
866     )*)
867 }
868 
869 big_numbers! { i64 u64 i128 u128 isize usize }
870 
871 externs! {
872     #[link(wasm_import_module = "__wbindgen_placeholder__")]
873     extern "C" {
874         fn __wbindgen_object_clone_ref(idx: u32) -> u32;
875         fn __wbindgen_object_drop_ref(idx: u32) -> ();
876 
877         fn __wbindgen_string_new(ptr: *const u8, len: usize) -> u32;
878         fn __wbindgen_number_new(f: f64) -> u32;
879         fn __wbindgen_bigint_new(ptr: *const u8, len: usize) -> u32;
880         fn __wbindgen_symbol_named_new(ptr: *const u8, len: usize) -> u32;
881         fn __wbindgen_symbol_anonymous_new() -> u32;
882 
883         fn __wbindgen_externref_heap_live_count() -> u32;
884 
885         fn __wbindgen_is_null(idx: u32) -> u32;
886         fn __wbindgen_is_undefined(idx: u32) -> u32;
887         fn __wbindgen_is_symbol(idx: u32) -> u32;
888         fn __wbindgen_is_object(idx: u32) -> u32;
889         fn __wbindgen_is_function(idx: u32) -> u32;
890         fn __wbindgen_is_string(idx: u32) -> u32;
891         fn __wbindgen_is_bigint(idx: u32) -> u32;
892         fn __wbindgen_typeof(idx: u32) -> u32;
893 
894         fn __wbindgen_in(prop: u32, obj: u32) -> u32;
895 
896         fn __wbindgen_is_falsy(idx: u32) -> u32;
897         fn __wbindgen_as_number(idx: u32) -> f64;
898         fn __wbindgen_try_into_number(idx: u32) -> u32;
899         fn __wbindgen_neg(idx: u32) -> u32;
900         fn __wbindgen_bit_and(a: u32, b: u32) -> u32;
901         fn __wbindgen_bit_or(a: u32, b: u32) -> u32;
902         fn __wbindgen_bit_xor(a: u32, b: u32) -> u32;
903         fn __wbindgen_bit_not(idx: u32) -> u32;
904         fn __wbindgen_shl(a: u32, b: u32) -> u32;
905         fn __wbindgen_shr(a: u32, b: u32) -> u32;
906         fn __wbindgen_unsigned_shr(a: u32, b: u32) -> u32;
907         fn __wbindgen_add(a: u32, b: u32) -> u32;
908         fn __wbindgen_sub(a: u32, b: u32) -> u32;
909         fn __wbindgen_div(a: u32, b: u32) -> u32;
910         fn __wbindgen_checked_div(a: u32, b: u32) -> u32;
911         fn __wbindgen_mul(a: u32, b: u32) -> u32;
912         fn __wbindgen_rem(a: u32, b: u32) -> u32;
913         fn __wbindgen_pow(a: u32, b: u32) -> u32;
914         fn __wbindgen_lt(a: u32, b: u32) -> u32;
915         fn __wbindgen_le(a: u32, b: u32) -> u32;
916         fn __wbindgen_ge(a: u32, b: u32) -> u32;
917         fn __wbindgen_gt(a: u32, b: u32) -> u32;
918 
919         fn __wbindgen_number_get(idx: u32) -> WasmOptionalF64;
920         fn __wbindgen_boolean_get(idx: u32) -> u32;
921         fn __wbindgen_string_get(idx: u32) -> WasmSlice;
922 
923         fn __wbindgen_debug_string(ret: *mut [usize; 2], idx: u32) -> ();
924 
925         fn __wbindgen_throw(a: *const u8, b: usize) -> !;
926         fn __wbindgen_rethrow(a: u32) -> !;
927 
928         fn __wbindgen_cb_drop(idx: u32) -> u32;
929 
930         fn __wbindgen_describe(v: u32) -> ();
931         fn __wbindgen_describe_closure(a: u32, b: u32, c: u32) -> u32;
932 
933         fn __wbindgen_json_parse(ptr: *const u8, len: usize) -> u32;
934         fn __wbindgen_json_serialize(idx: u32) -> WasmSlice;
935         fn __wbindgen_jsval_eq(a: u32, b: u32) -> u32;
936         fn __wbindgen_jsval_loose_eq(a: u32, b: u32) -> u32;
937 
938         fn __wbindgen_not(idx: u32) -> u32;
939 
940         fn __wbindgen_memory() -> u32;
941         fn __wbindgen_module() -> u32;
942         fn __wbindgen_function_table() -> u32;
943     }
944 }
945 
946 impl Clone for JsValue {
947     #[inline]
clone(&self) -> JsValue948     fn clone(&self) -> JsValue {
949         unsafe {
950             let idx = __wbindgen_object_clone_ref(self.idx);
951             JsValue::_new(idx)
952         }
953     }
954 }
955 
956 #[cfg(feature = "std")]
957 impl fmt::Debug for JsValue {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result958     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
959         write!(f, "JsValue({})", self.as_debug_string())
960     }
961 }
962 
963 #[cfg(not(feature = "std"))]
964 impl fmt::Debug for JsValue {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result965     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
966         f.write_str("JsValue")
967     }
968 }
969 
970 impl Drop for JsValue {
971     #[inline]
drop(&mut self)972     fn drop(&mut self) {
973         unsafe {
974             // We definitely should never drop anything in the stack area
975             debug_assert!(self.idx >= JSIDX_OFFSET, "free of stack slot {}", self.idx);
976 
977             // Otherwise if we're not dropping one of our reserved values,
978             // actually call the intrinsic. See #1054 for eventually removing
979             // this branch.
980             if self.idx >= JSIDX_RESERVED {
981                 __wbindgen_object_drop_ref(self.idx);
982             }
983         }
984     }
985 }
986 
987 impl Default for JsValue {
default() -> Self988     fn default() -> Self {
989         Self::UNDEFINED
990     }
991 }
992 
993 /// Wrapper type for imported statics.
994 ///
995 /// This type is used whenever a `static` is imported from a JS module, for
996 /// example this import:
997 ///
998 /// ```ignore
999 /// #[wasm_bindgen]
1000 /// extern "C" {
1001 ///     static console: JsValue;
1002 /// }
1003 /// ```
1004 ///
1005 /// will generate in Rust a value that looks like:
1006 ///
1007 /// ```ignore
1008 /// static console: JsStatic<JsValue> = ...;
1009 /// ```
1010 ///
1011 /// This type implements `Deref` to the inner type so it's typically used as if
1012 /// it were `&T`.
1013 #[cfg(feature = "std")]
1014 pub struct JsStatic<T: 'static> {
1015     #[doc(hidden)]
1016     pub __inner: &'static std::thread::LocalKey<T>,
1017 }
1018 
1019 #[cfg(feature = "std")]
1020 impl<T: FromWasmAbi + 'static> Deref for JsStatic<T> {
1021     type Target = T;
deref(&self) -> &T1022     fn deref(&self) -> &T {
1023         // We know that our tls key is never overwritten after initialization,
1024         // so it should be safe (on that axis at least) to hand out a reference
1025         // that lives longer than the closure below.
1026         //
1027         // FIXME: this is not sound if we ever implement thread exit hooks on
1028         // wasm, as the pointer will eventually be invalidated but you can get
1029         // `&'static T` from this interface. We... probably need to deprecate
1030         // and/or remove this interface nowadays.
1031         unsafe { self.__inner.with(|ptr| &*(ptr as *const T)) }
1032     }
1033 }
1034 
1035 #[cold]
1036 #[inline(never)]
1037 #[deprecated(note = "renamed to `throw_str`")]
1038 #[doc(hidden)]
throw(s: &str) -> !1039 pub fn throw(s: &str) -> ! {
1040     throw_str(s)
1041 }
1042 
1043 /// Throws a JS exception.
1044 ///
1045 /// This function will throw a JS exception with the message provided. The
1046 /// function will not return as the wasm stack will be popped when the exception
1047 /// is thrown.
1048 ///
1049 /// Note that it is very easy to leak memory with this function because this
1050 /// function, unlike `panic!` on other platforms, **will not run destructors**.
1051 /// It's recommended to return a `Result` where possible to avoid the worry of
1052 /// leaks.
1053 #[cold]
1054 #[inline(never)]
throw_str(s: &str) -> !1055 pub fn throw_str(s: &str) -> ! {
1056     unsafe {
1057         __wbindgen_throw(s.as_ptr(), s.len());
1058     }
1059 }
1060 
1061 /// Rethrow a JS exception
1062 ///
1063 /// This function will throw a JS exception with the JS value provided. This
1064 /// function will not return and the wasm stack will be popped until the point
1065 /// of entry of wasm itself.
1066 ///
1067 /// Note that it is very easy to leak memory with this function because this
1068 /// function, unlike `panic!` on other platforms, **will not run destructors**.
1069 /// It's recommended to return a `Result` where possible to avoid the worry of
1070 /// leaks.
1071 #[cold]
1072 #[inline(never)]
throw_val(s: JsValue) -> !1073 pub fn throw_val(s: JsValue) -> ! {
1074     unsafe {
1075         let idx = s.idx;
1076         mem::forget(s);
1077         __wbindgen_rethrow(idx);
1078     }
1079 }
1080 
1081 /// Get the count of live `externref`s / `JsValue`s in `wasm-bindgen`'s heap.
1082 ///
1083 /// ## Usage
1084 ///
1085 /// This is intended for debugging and writing tests.
1086 ///
1087 /// To write a test that asserts against unnecessarily keeping `anref`s /
1088 /// `JsValue`s alive:
1089 ///
1090 /// * get an initial live count,
1091 ///
1092 /// * perform some series of operations or function calls that should clean up
1093 ///   after themselves, and should not keep holding onto `externref`s / `JsValue`s
1094 ///   after completion,
1095 ///
1096 /// * get the final live count,
1097 ///
1098 /// * and assert that the initial and final counts are the same.
1099 ///
1100 /// ## What is Counted
1101 ///
1102 /// Note that this only counts the *owned* `externref`s / `JsValue`s that end up in
1103 /// `wasm-bindgen`'s heap. It does not count borrowed `externref`s / `JsValue`s
1104 /// that are on its stack.
1105 ///
1106 /// For example, these `JsValue`s are accounted for:
1107 ///
1108 /// ```ignore
1109 /// #[wasm_bindgen]
1110 /// pub fn my_function(this_is_counted: JsValue) {
1111 ///     let also_counted = JsValue::from_str("hi");
1112 ///     assert!(wasm_bindgen::externref_heap_live_count() >= 2);
1113 /// }
1114 /// ```
1115 ///
1116 /// While this borrowed `JsValue` ends up on the stack, not the heap, and
1117 /// therefore is not accounted for:
1118 ///
1119 /// ```ignore
1120 /// #[wasm_bindgen]
1121 /// pub fn my_other_function(this_is_not_counted: &JsValue) {
1122 ///     // ...
1123 /// }
1124 /// ```
externref_heap_live_count() -> u321125 pub fn externref_heap_live_count() -> u32 {
1126     unsafe { __wbindgen_externref_heap_live_count() }
1127 }
1128 
1129 #[doc(hidden)]
anyref_heap_live_count() -> u321130 pub fn anyref_heap_live_count() -> u32 {
1131     externref_heap_live_count()
1132 }
1133 
1134 /// An extension trait for `Option<T>` and `Result<T, E>` for unwraping the `T`
1135 /// value, or throwing a JS error if it is not available.
1136 ///
1137 /// These methods should have a smaller code size footprint than the normal
1138 /// `Option::unwrap` and `Option::expect` methods, but they are specific to
1139 /// working with wasm and JS.
1140 ///
1141 /// On non-wasm32 targets, defaults to the normal unwrap/expect calls.
1142 ///
1143 /// # Example
1144 ///
1145 /// ```
1146 /// use wasm_bindgen::prelude::*;
1147 ///
1148 /// // If the value is `Option::Some` or `Result::Ok`, then we just get the
1149 /// // contained `T` value.
1150 /// let x = Some(42);
1151 /// assert_eq!(x.unwrap_throw(), 42);
1152 ///
1153 /// let y: Option<i32> = None;
1154 ///
1155 /// // This call would throw an error to JS!
1156 /// //
1157 /// //     y.unwrap_throw()
1158 /// //
1159 /// // And this call would throw an error to JS with a custom error message!
1160 /// //
1161 /// //     y.expect_throw("woopsie daisy!")
1162 /// ```
1163 pub trait UnwrapThrowExt<T>: Sized {
1164     /// Unwrap this `Option` or `Result`, but instead of panicking on failure,
1165     /// throw an exception to JavaScript.
unwrap_throw(self) -> T1166     fn unwrap_throw(self) -> T {
1167         self.expect_throw("`unwrap_throw` failed")
1168     }
1169 
1170     /// Unwrap this container's `T` value, or throw an error to JS with the
1171     /// given message if the `T` value is unavailable (e.g. an `Option<T>` is
1172     /// `None`).
expect_throw(self, message: &str) -> T1173     fn expect_throw(self, message: &str) -> T;
1174 }
1175 
1176 impl<T> UnwrapThrowExt<T> for Option<T> {
expect_throw(self, message: &str) -> T1177     fn expect_throw(self, message: &str) -> T {
1178         if cfg!(all(target_arch = "wasm32", not(target_os = "emscripten"))) {
1179             match self {
1180                 Some(val) => val,
1181                 None => throw_str(message),
1182             }
1183         } else {
1184             self.expect(message)
1185         }
1186     }
1187 }
1188 
1189 impl<T, E> UnwrapThrowExt<T> for Result<T, E>
1190 where
1191     E: core::fmt::Debug,
1192 {
expect_throw(self, message: &str) -> T1193     fn expect_throw(self, message: &str) -> T {
1194         if cfg!(all(target_arch = "wasm32", not(target_os = "emscripten"))) {
1195             match self {
1196                 Ok(val) => val,
1197                 Err(_) => throw_str(message),
1198             }
1199         } else {
1200             self.expect(message)
1201         }
1202     }
1203 }
1204 
1205 /// Returns a handle to this wasm instance's `WebAssembly.Module`
1206 ///
1207 /// Note that this is only available when the final wasm app is built with
1208 /// `--target no-modules`, it's not recommended to rely on this API yet! This is
1209 /// largely just an experimental addition to enable threading demos. Using this
1210 /// may prevent your wasm module from building down the road.
1211 #[doc(hidden)]
module() -> JsValue1212 pub fn module() -> JsValue {
1213     unsafe { JsValue::_new(__wbindgen_module()) }
1214 }
1215 
1216 /// Returns a handle to this wasm instance's `WebAssembly.Memory`
memory() -> JsValue1217 pub fn memory() -> JsValue {
1218     unsafe { JsValue::_new(__wbindgen_memory()) }
1219 }
1220 
1221 /// Returns a handle to this wasm instance's `WebAssembly.Table` which is the
1222 /// indirect function table used by Rust
function_table() -> JsValue1223 pub fn function_table() -> JsValue {
1224     unsafe { JsValue::_new(__wbindgen_function_table()) }
1225 }
1226 
1227 #[doc(hidden)]
1228 pub mod __rt {
1229     use crate::JsValue;
1230     use core::cell::{Cell, UnsafeCell};
1231     use core::ops::{Deref, DerefMut};
1232 
1233     pub extern crate core;
1234     #[cfg(feature = "std")]
1235     pub extern crate std;
1236 
1237     #[macro_export]
1238     #[doc(hidden)]
1239     #[cfg(feature = "std")]
1240     macro_rules! __wbindgen_if_not_std {
1241         ($($i:item)*) => {};
1242     }
1243 
1244     #[macro_export]
1245     #[doc(hidden)]
1246     #[cfg(not(feature = "std"))]
1247     macro_rules! __wbindgen_if_not_std {
1248         ($($i:item)*) => ($($i)*)
1249     }
1250 
1251     #[inline]
assert_not_null<T>(s: *mut T)1252     pub fn assert_not_null<T>(s: *mut T) {
1253         if s.is_null() {
1254             throw_null();
1255         }
1256     }
1257 
1258     #[cold]
1259     #[inline(never)]
throw_null() -> !1260     fn throw_null() -> ! {
1261         super::throw_str("null pointer passed to rust");
1262     }
1263 
1264     /// A vendored version of `RefCell` from the standard library.
1265     ///
1266     /// Now why, you may ask, would we do that? Surely `RefCell` in libstd is
1267     /// quite good. And you're right, it is indeed quite good! Functionally
1268     /// nothing more is needed from `RefCell` in the standard library but for
1269     /// now this crate is also sort of optimizing for compiled code size.
1270     ///
1271     /// One major factor to larger binaries in Rust is when a panic happens.
1272     /// Panicking in the standard library involves a fair bit of machinery
1273     /// (formatting, panic hooks, synchronization, etc). It's all worthwhile if
1274     /// you need it but for something like `WasmRefCell` here we don't actually
1275     /// need all that!
1276     ///
1277     /// This is just a wrapper around all Rust objects passed to JS intended to
1278     /// guard accidental reentrancy, so this vendored version is intended solely
1279     /// to not panic in libstd. Instead when it "panics" it calls our `throw`
1280     /// function in this crate which raises an error in JS.
1281     pub struct WasmRefCell<T: ?Sized> {
1282         borrow: Cell<usize>,
1283         value: UnsafeCell<T>,
1284     }
1285 
1286     impl<T: ?Sized> WasmRefCell<T> {
new(value: T) -> WasmRefCell<T> where T: Sized,1287         pub fn new(value: T) -> WasmRefCell<T>
1288         where
1289             T: Sized,
1290         {
1291             WasmRefCell {
1292                 value: UnsafeCell::new(value),
1293                 borrow: Cell::new(0),
1294             }
1295         }
1296 
get_mut(&mut self) -> &mut T1297         pub fn get_mut(&mut self) -> &mut T {
1298             unsafe { &mut *self.value.get() }
1299         }
1300 
borrow(&self) -> Ref<T>1301         pub fn borrow(&self) -> Ref<T> {
1302             unsafe {
1303                 if self.borrow.get() == usize::max_value() {
1304                     borrow_fail();
1305                 }
1306                 self.borrow.set(self.borrow.get() + 1);
1307                 Ref {
1308                     value: &*self.value.get(),
1309                     borrow: &self.borrow,
1310                 }
1311             }
1312         }
1313 
borrow_mut(&self) -> RefMut<T>1314         pub fn borrow_mut(&self) -> RefMut<T> {
1315             unsafe {
1316                 if self.borrow.get() != 0 {
1317                     borrow_fail();
1318                 }
1319                 self.borrow.set(usize::max_value());
1320                 RefMut {
1321                     value: &mut *self.value.get(),
1322                     borrow: &self.borrow,
1323                 }
1324             }
1325         }
1326 
into_inner(self) -> T where T: Sized,1327         pub fn into_inner(self) -> T
1328         where
1329             T: Sized,
1330         {
1331             self.value.into_inner()
1332         }
1333     }
1334 
1335     pub struct Ref<'b, T: ?Sized + 'b> {
1336         value: &'b T,
1337         borrow: &'b Cell<usize>,
1338     }
1339 
1340     impl<'b, T: ?Sized> Deref for Ref<'b, T> {
1341         type Target = T;
1342 
1343         #[inline]
deref(&self) -> &T1344         fn deref(&self) -> &T {
1345             self.value
1346         }
1347     }
1348 
1349     impl<'b, T: ?Sized> Drop for Ref<'b, T> {
drop(&mut self)1350         fn drop(&mut self) {
1351             self.borrow.set(self.borrow.get() - 1);
1352         }
1353     }
1354 
1355     pub struct RefMut<'b, T: ?Sized + 'b> {
1356         value: &'b mut T,
1357         borrow: &'b Cell<usize>,
1358     }
1359 
1360     impl<'b, T: ?Sized> Deref for RefMut<'b, T> {
1361         type Target = T;
1362 
1363         #[inline]
deref(&self) -> &T1364         fn deref(&self) -> &T {
1365             self.value
1366         }
1367     }
1368 
1369     impl<'b, T: ?Sized> DerefMut for RefMut<'b, T> {
1370         #[inline]
deref_mut(&mut self) -> &mut T1371         fn deref_mut(&mut self) -> &mut T {
1372             self.value
1373         }
1374     }
1375 
1376     impl<'b, T: ?Sized> Drop for RefMut<'b, T> {
drop(&mut self)1377         fn drop(&mut self) {
1378             self.borrow.set(0);
1379         }
1380     }
1381 
borrow_fail() -> !1382     fn borrow_fail() -> ! {
1383         super::throw_str(
1384             "recursive use of an object detected which would lead to \
1385              unsafe aliasing in rust",
1386         );
1387     }
1388 
1389     if_std! {
1390         use std::alloc::{alloc, dealloc, realloc, Layout};
1391         use std::mem;
1392 
1393         #[no_mangle]
1394         pub extern "C" fn __wbindgen_malloc(size: usize) -> *mut u8 {
1395             let align = mem::align_of::<usize>();
1396             if let Ok(layout) = Layout::from_size_align(size, align) {
1397                 unsafe {
1398                     if layout.size() > 0 {
1399                         let ptr = alloc(layout);
1400                         if !ptr.is_null() {
1401                             return ptr
1402                         }
1403                     } else {
1404                         return align as *mut u8
1405                     }
1406                 }
1407             }
1408 
1409             malloc_failure();
1410         }
1411 
1412         #[no_mangle]
1413         pub unsafe extern "C" fn __wbindgen_realloc(ptr: *mut u8, old_size: usize, new_size: usize) -> *mut u8 {
1414             let align = mem::align_of::<usize>();
1415             debug_assert!(old_size > 0);
1416             debug_assert!(new_size > 0);
1417             if let Ok(layout) = Layout::from_size_align(old_size, align) {
1418                 let ptr = realloc(ptr, layout, new_size);
1419                 if !ptr.is_null() {
1420                     return ptr
1421                 }
1422             }
1423             malloc_failure();
1424         }
1425 
1426         #[cold]
1427         fn malloc_failure() -> ! {
1428             if cfg!(debug_assertions) {
1429                 super::throw_str("invalid malloc request")
1430             } else {
1431                 std::process::abort();
1432             }
1433         }
1434 
1435         #[no_mangle]
1436         pub unsafe extern "C" fn __wbindgen_free(ptr: *mut u8, size: usize) {
1437             // This happens for zero-length slices, and in that case `ptr` is
1438             // likely bogus so don't actually send this to the system allocator
1439             if size == 0 {
1440                 return
1441             }
1442             let align = mem::align_of::<usize>();
1443             let layout = Layout::from_size_align_unchecked(size, align);
1444             dealloc(ptr, layout);
1445         }
1446     }
1447 
1448     /// This is a curious function necessary to get wasm-bindgen working today,
1449     /// and it's a bit of an unfortunate hack.
1450     ///
1451     /// The general problem is that somehow we need the above two symbols to
1452     /// exist in the final output binary (__wbindgen_malloc and
1453     /// __wbindgen_free). These symbols may be called by JS for various
1454     /// bindings, so we for sure need to make sure they're exported.
1455     ///
1456     /// The problem arises, though, when what if no Rust code uses the symbols?
1457     /// For all intents and purposes it looks to LLVM and the linker like the
1458     /// above two symbols are dead code, so they're completely discarded!
1459     ///
1460     /// Specifically what happens is this:
1461     ///
1462     /// * The above two symbols are generated into some object file inside of
1463     ///   libwasm_bindgen.rlib
1464     /// * The linker, LLD, will not load this object file unless *some* symbol
1465     ///   is loaded from the object. In this case, if the Rust code never calls
1466     ///   __wbindgen_malloc or __wbindgen_free then the symbols never get linked
1467     ///   in.
1468     /// * Later when `wasm-bindgen` attempts to use the symbols they don't
1469     ///   exist, causing an error.
1470     ///
1471     /// This function is a weird hack for this problem. We inject a call to this
1472     /// function in all generated code. Usage of this function should then
1473     /// ensure that the above two intrinsics are translated.
1474     ///
1475     /// Due to how rustc creates object files this function (and anything inside
1476     /// it) will be placed into the same object file as the two intrinsics
1477     /// above. That means if this function is called and referenced we'll pull
1478     /// in the object file and link the intrinsics.
1479     ///
1480     /// Ideas for how to improve this are most welcome!
link_mem_intrinsics()1481     pub fn link_mem_intrinsics() {
1482         crate::externref::link_intrinsics();
1483     }
1484 
1485     static mut GLOBAL_EXNDATA: [u32; 2] = [0; 2];
1486 
1487     #[no_mangle]
__wbindgen_exn_store(idx: u32)1488     pub unsafe extern "C" fn __wbindgen_exn_store(idx: u32) {
1489         debug_assert_eq!(GLOBAL_EXNDATA[0], 0);
1490         GLOBAL_EXNDATA[0] = 1;
1491         GLOBAL_EXNDATA[1] = idx;
1492     }
1493 
take_last_exception() -> Result<(), super::JsValue>1494     pub fn take_last_exception() -> Result<(), super::JsValue> {
1495         unsafe {
1496             let ret = if GLOBAL_EXNDATA[0] == 1 {
1497                 Err(super::JsValue::_new(GLOBAL_EXNDATA[1]))
1498             } else {
1499                 Ok(())
1500             };
1501             GLOBAL_EXNDATA[0] = 0;
1502             GLOBAL_EXNDATA[1] = 0;
1503             return ret;
1504         }
1505     }
1506 
1507     /// An internal helper trait for usage in `#[wasm_bindgen]` on `async`
1508     /// functions to convert the return value of the function to
1509     /// `Result<JsValue, JsValue>` which is what we'll return to JS (where an
1510     /// error is a failed future).
1511     pub trait IntoJsResult {
into_js_result(self) -> Result<JsValue, JsValue>1512         fn into_js_result(self) -> Result<JsValue, JsValue>;
1513     }
1514 
1515     impl IntoJsResult for () {
into_js_result(self) -> Result<JsValue, JsValue>1516         fn into_js_result(self) -> Result<JsValue, JsValue> {
1517             Ok(JsValue::undefined())
1518         }
1519     }
1520 
1521     impl<T: Into<JsValue>> IntoJsResult for T {
into_js_result(self) -> Result<JsValue, JsValue>1522         fn into_js_result(self) -> Result<JsValue, JsValue> {
1523             Ok(self.into())
1524         }
1525     }
1526 
1527     impl<T: Into<JsValue>, E: Into<JsValue>> IntoJsResult for Result<T, E> {
into_js_result(self) -> Result<JsValue, JsValue>1528         fn into_js_result(self) -> Result<JsValue, JsValue> {
1529             match self {
1530                 Ok(e) => Ok(e.into()),
1531                 Err(e) => Err(e.into()),
1532             }
1533         }
1534     }
1535 
1536     impl<E: Into<JsValue>> IntoJsResult for Result<(), E> {
into_js_result(self) -> Result<JsValue, JsValue>1537         fn into_js_result(self) -> Result<JsValue, JsValue> {
1538             match self {
1539                 Ok(()) => Ok(JsValue::undefined()),
1540                 Err(e) => Err(e.into()),
1541             }
1542         }
1543     }
1544 
1545     /// An internal helper trait for usage in `#[wasm_bindgen(start)]`
1546     /// functions to throw the error (if it is `Err`).
1547     pub trait Start {
start(self)1548         fn start(self);
1549     }
1550 
1551     impl Start for () {
1552         #[inline]
start(self)1553         fn start(self) {}
1554     }
1555 
1556     impl<E: Into<JsValue>> Start for Result<(), E> {
1557         #[inline]
start(self)1558         fn start(self) {
1559             if let Err(e) = self {
1560                 crate::throw_val(e.into());
1561             }
1562         }
1563     }
1564 }
1565 
1566 /// A wrapper type around slices and vectors for binding the `Uint8ClampedArray`
1567 /// array in JS.
1568 ///
1569 /// If you need to invoke a JS API which must take `Uint8ClampedArray` array,
1570 /// then you can define it as taking one of these types:
1571 ///
1572 /// * `Clamped<&[u8]>`
1573 /// * `Clamped<&mut [u8]>`
1574 /// * `Clamped<Vec<u8>>`
1575 ///
1576 /// All of these types will show up as `Uint8ClampedArray` in JS and will have
1577 /// different forms of ownership in Rust.
1578 #[derive(Copy, Clone, PartialEq, Debug, Eq)]
1579 pub struct Clamped<T>(pub T);
1580 
1581 impl<T> Deref for Clamped<T> {
1582     type Target = T;
1583 
deref(&self) -> &T1584     fn deref(&self) -> &T {
1585         &self.0
1586     }
1587 }
1588 
1589 impl<T> DerefMut for Clamped<T> {
deref_mut(&mut self) -> &mut T1590     fn deref_mut(&mut self) -> &mut T {
1591         &mut self.0
1592     }
1593 }
1594