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