mirror of
https://github.com/fluencelabs/wasm-bindgen
synced 2025-04-28 23:22:16 +00:00
Currently closure shims are communicated to JS at runtime, although at runtime the same constant value is always passed to JS! More pressing, however, work in #1002 requires knowledge of closure descriptor indices at `wasm-bindgen` time which is not currently known. Since the closure descriptor shims and such are already constant values, this commit moves the descriptor function indices into the *descriptor* for a closure/function pointer. This way we can learn about these values at `wasm-bindgen` time instead of only knowing them at runtime. This should have no semantic change on users of `wasm-bindgen`, although some closure invocations may be slightly speedier because there's less arguments being transferred over the boundary. Overall though this will help #1002 as the closure shims that the Rust compiler generates may not be the exact ones we hand out to JS, but rather wrappers around them which do `anyref` business things.
163 lines
2.8 KiB
Rust
163 lines
2.8 KiB
Rust
//! This is an internal module, no stability guarantees are provided. Use at
|
|
//! your own risk.
|
|
|
|
#![doc(hidden)]
|
|
|
|
use {Clamped, JsValue};
|
|
|
|
macro_rules! tys {
|
|
($($a:ident)*) => (tys! { @ ($($a)*) 0 });
|
|
(@ () $v:expr) => {};
|
|
(@ ($a:ident $($b:ident)*) $v:expr) => {
|
|
pub const $a: u32 = $v;
|
|
tys!(@ ($($b)*) $v+1);
|
|
}
|
|
}
|
|
|
|
// NB: this list must be kept in sync with `crates/cli-support/src/descriptor.rs`
|
|
tys! {
|
|
I8
|
|
U8
|
|
I16
|
|
U16
|
|
I32
|
|
U32
|
|
I64
|
|
U64
|
|
F32
|
|
F64
|
|
BOOLEAN
|
|
FUNCTION
|
|
CLOSURE
|
|
STRING
|
|
REF
|
|
REFMUT
|
|
SLICE
|
|
VECTOR
|
|
ANYREF
|
|
ENUM
|
|
RUST_STRUCT
|
|
CHAR
|
|
OPTIONAL
|
|
UNIT
|
|
CLAMPED
|
|
}
|
|
|
|
#[inline(always)] // see `interpret.rs` in the the cli-support crate
|
|
pub fn inform(a: u32) {
|
|
unsafe { super::__wbindgen_describe(a) }
|
|
}
|
|
|
|
pub trait WasmDescribe {
|
|
fn describe();
|
|
}
|
|
|
|
macro_rules! simple {
|
|
($($t:ident => $d:ident)*) => ($(
|
|
impl WasmDescribe for $t {
|
|
fn describe() { inform($d) }
|
|
}
|
|
)*)
|
|
}
|
|
|
|
simple! {
|
|
i8 => I8
|
|
u8 => U8
|
|
i16 => I16
|
|
u16 => U16
|
|
i32 => I32
|
|
u32 => U32
|
|
i64 => I64
|
|
u64 => U64
|
|
isize => I32
|
|
usize => U32
|
|
f32 => F32
|
|
f64 => F64
|
|
bool => BOOLEAN
|
|
char => CHAR
|
|
str => STRING
|
|
JsValue => ANYREF
|
|
}
|
|
|
|
impl<T> WasmDescribe for *const T {
|
|
fn describe() {
|
|
inform(I32)
|
|
}
|
|
}
|
|
|
|
impl<T> WasmDescribe for *mut T {
|
|
fn describe() {
|
|
inform(I32)
|
|
}
|
|
}
|
|
|
|
impl<T: WasmDescribe> WasmDescribe for [T] {
|
|
fn describe() {
|
|
inform(SLICE);
|
|
T::describe();
|
|
}
|
|
}
|
|
|
|
impl<'a, T: WasmDescribe + ?Sized> WasmDescribe for &'a T {
|
|
fn describe() {
|
|
inform(REF);
|
|
T::describe();
|
|
}
|
|
}
|
|
|
|
impl<'a, T: WasmDescribe + ?Sized> WasmDescribe for &'a mut T {
|
|
fn describe() {
|
|
inform(REFMUT);
|
|
T::describe();
|
|
}
|
|
}
|
|
|
|
if_std! {
|
|
use std::prelude::v1::*;
|
|
|
|
impl WasmDescribe for String {
|
|
fn describe() { inform(STRING) }
|
|
}
|
|
|
|
impl<T: WasmDescribe> WasmDescribe for Box<[T]> {
|
|
fn describe() {
|
|
inform(VECTOR);
|
|
T::describe();
|
|
}
|
|
}
|
|
|
|
impl<T> WasmDescribe for Vec<T> where Box<[T]>: WasmDescribe {
|
|
fn describe() {
|
|
<Box<[T]>>::describe();
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<T: WasmDescribe> WasmDescribe for Option<T> {
|
|
fn describe() {
|
|
inform(OPTIONAL);
|
|
T::describe();
|
|
}
|
|
}
|
|
|
|
impl WasmDescribe for () {
|
|
fn describe() {
|
|
inform(UNIT)
|
|
}
|
|
}
|
|
|
|
// Note that this is only for `ReturnWasmAbi for Result<T, JsValue>`, which
|
|
// throws the result, so we only need to inform about the `T`.
|
|
impl<T: WasmDescribe> WasmDescribe for Result<T, JsValue> {
|
|
fn describe() {
|
|
T::describe()
|
|
}
|
|
}
|
|
|
|
impl<T: WasmDescribe> WasmDescribe for Clamped<T> {
|
|
fn describe() {
|
|
inform(CLAMPED);
|
|
T::describe();
|
|
}
|
|
}
|