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