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