Skip to main content

wasm_bindgen/
describe.rs

1//! This is an internal module, no stability guarantees are provided. Use at
2//! your own risk.
3
4#![doc(hidden)]
5
6use alloc::boxed::Box;
7use alloc::string::String;
8use alloc::vec::Vec;
9use core::panic::AssertUnwindSafe;
10use core::{mem::MaybeUninit, ptr::NonNull};
11
12use crate::{__rt::marker::ErasableGeneric, Clamped, JsError, JsValue};
13use cfg_if::cfg_if;
14
15pub use wasm_bindgen_shared::tys::*;
16
17#[inline(always)] // see the wasm-interpreter module
18#[cfg_attr(wasm_bindgen_unstable_test_coverage, coverage(off))]
19pub fn inform(a: u32) {
20    unsafe { super::__wbindgen_describe(a) }
21}
22
23pub trait WasmDescribe {
24    fn describe();
25}
26
27/// Trait for element types to implement WasmDescribe for vectors of
28/// themselves.
29pub trait WasmDescribeVector {
30    fn describe_vector();
31}
32
33macro_rules! simple {
34    ($($t:ident => $d:ident)*) => ($(
35        impl WasmDescribe for $t {
36            #[cfg_attr(wasm_bindgen_unstable_test_coverage, coverage(off))]
37            fn describe() { inform($d) }
38        }
39    )*)
40}
41
42simple! {
43    i8 => I8
44    u8 => U8
45    i16 => I16
46    u16 => U16
47    i32 => I32
48    u32 => U32
49    i64 => I64
50    u64 => U64
51    i128 => I128
52    u128 => U128
53    f32 => F32
54    f64 => F64
55    bool => BOOLEAN
56    char => CHAR
57    JsValue => EXTERNREF
58}
59
60// isize/usize map to I32/U32 on wasm32 and direct *_AS_F64 descriptors on wasm64
61cfg_if! {
62    if #[cfg(target_arch = "wasm64")] {
63        simple! {
64            isize => I64_AS_F64
65            usize => U64_AS_F64
66        }
67    } else {
68        simple! {
69            isize => I32
70            usize => U32
71        }
72    }
73}
74
75cfg_if! {
76    if #[cfg(feature = "enable-interning")] {
77        simple! {
78            str => CACHED_STRING
79        }
80
81    } else {
82        simple! {
83            str => STRING
84        }
85    }
86}
87
88impl<T> WasmDescribe for *const T {
89    #[cfg_attr(wasm_bindgen_unstable_test_coverage, coverage(off))]
90    fn describe() {
91        inform(RAW_POINTER)
92    }
93}
94
95impl<T> WasmDescribe for *mut T {
96    #[cfg_attr(wasm_bindgen_unstable_test_coverage, coverage(off))]
97    fn describe() {
98        inform(RAW_POINTER)
99    }
100}
101
102impl<T> WasmDescribe for NonNull<T> {
103    #[cfg_attr(wasm_bindgen_unstable_test_coverage, coverage(off))]
104    fn describe() {
105        inform(NONNULL)
106    }
107}
108
109impl<T: WasmDescribe> WasmDescribe for [T] {
110    #[cfg_attr(wasm_bindgen_unstable_test_coverage, coverage(off))]
111    fn describe() {
112        inform(SLICE);
113        T::describe();
114    }
115}
116
117impl<T: WasmDescribe + ?Sized> WasmDescribe for &T {
118    #[cfg_attr(wasm_bindgen_unstable_test_coverage, coverage(off))]
119    fn describe() {
120        inform(REF);
121        T::describe();
122    }
123}
124
125impl<T: WasmDescribe + ?Sized> WasmDescribe for &mut T {
126    #[cfg_attr(wasm_bindgen_unstable_test_coverage, coverage(off))]
127    fn describe() {
128        inform(REFMUT);
129        T::describe();
130    }
131}
132
133cfg_if! {
134    if #[cfg(feature = "enable-interning")] {
135        simple! {
136            String => CACHED_STRING
137        }
138
139    } else {
140        simple! {
141            String => STRING
142        }
143    }
144}
145
146impl<T: ErasableGeneric<Repr = JsValue> + WasmDescribe> WasmDescribeVector for T {
147    #[cfg_attr(wasm_bindgen_unstable_test_coverage, coverage(off))]
148    fn describe_vector() {
149        inform(VECTOR);
150        T::describe();
151    }
152}
153
154impl<T: WasmDescribeVector> WasmDescribe for Box<[T]> {
155    #[cfg_attr(wasm_bindgen_unstable_test_coverage, coverage(off))]
156    fn describe() {
157        T::describe_vector();
158    }
159}
160
161impl<T> WasmDescribe for Vec<T>
162where
163    Box<[T]>: WasmDescribe,
164{
165    #[cfg_attr(wasm_bindgen_unstable_test_coverage, coverage(off))]
166    fn describe() {
167        <Box<[T]>>::describe();
168    }
169}
170
171impl<T: WasmDescribe> WasmDescribe for Option<T> {
172    #[cfg_attr(wasm_bindgen_unstable_test_coverage, coverage(off))]
173    fn describe() {
174        inform(OPTIONAL);
175        T::describe();
176    }
177}
178
179impl WasmDescribe for () {
180    #[cfg_attr(wasm_bindgen_unstable_test_coverage, coverage(off))]
181    fn describe() {
182        inform(UNIT)
183    }
184}
185
186impl<T: WasmDescribe, E: Into<JsValue>> WasmDescribe for Result<T, E> {
187    #[cfg_attr(wasm_bindgen_unstable_test_coverage, coverage(off))]
188    fn describe() {
189        inform(RESULT);
190        T::describe();
191    }
192}
193
194impl<T: WasmDescribe> WasmDescribe for MaybeUninit<T> {
195    #[cfg_attr(wasm_bindgen_unstable_test_coverage, coverage(off))]
196    fn describe() {
197        T::describe();
198    }
199}
200
201impl<T: WasmDescribe> WasmDescribe for Clamped<T> {
202    #[cfg_attr(wasm_bindgen_unstable_test_coverage, coverage(off))]
203    fn describe() {
204        inform(CLAMPED);
205        T::describe();
206    }
207}
208
209impl WasmDescribe for JsError {
210    #[cfg_attr(wasm_bindgen_unstable_test_coverage, coverage(off))]
211    fn describe() {
212        JsValue::describe();
213    }
214}
215
216impl<T> WasmDescribe for AssertUnwindSafe<T>
217where
218    T: WasmDescribe,
219{
220    fn describe() {
221        T::describe();
222    }
223}