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