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