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