mirror of
https://github.com/fluencelabs/wasm-bindgen
synced 2025-04-22 04:32:13 +00:00
Merge pull request #1065 from alexcrichton/describe-closures
Move closure shims into the descriptor
This commit is contained in:
commit
91e9495805
@ -501,6 +501,7 @@ impl TryToTokens for ast::Export {
|
|||||||
&export,
|
&export,
|
||||||
quote! {
|
quote! {
|
||||||
inform(FUNCTION);
|
inform(FUNCTION);
|
||||||
|
inform(0);
|
||||||
inform(#nargs);
|
inform(#nargs);
|
||||||
#(<#argtys as WasmDescribe>::describe();)*
|
#(<#argtys as WasmDescribe>::describe();)*
|
||||||
#describe_ret
|
#describe_ret
|
||||||
@ -999,6 +1000,7 @@ impl<'a> ToTokens for DescribeImport<'a> {
|
|||||||
&f.shim,
|
&f.shim,
|
||||||
quote! {
|
quote! {
|
||||||
inform(FUNCTION);
|
inform(FUNCTION);
|
||||||
|
inform(0);
|
||||||
inform(#nargs);
|
inform(#nargs);
|
||||||
#(<#argtys as WasmDescribe>::describe();)*
|
#(<#argtys as WasmDescribe>::describe();)*
|
||||||
#inform_ret
|
#inform_ret
|
||||||
|
@ -70,11 +70,14 @@ pub enum Descriptor {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Function {
|
pub struct Function {
|
||||||
pub arguments: Vec<Descriptor>,
|
pub arguments: Vec<Descriptor>,
|
||||||
|
pub shim_idx: u32,
|
||||||
pub ret: Descriptor,
|
pub ret: Descriptor,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Closure {
|
pub struct Closure {
|
||||||
|
pub shim_idx: u32,
|
||||||
|
pub dtor_idx: u32,
|
||||||
pub function: Function,
|
pub function: Function,
|
||||||
pub mutable: bool,
|
pub mutable: bool,
|
||||||
}
|
}
|
||||||
@ -293,9 +296,13 @@ fn get(a: &mut &[u32]) -> u32 {
|
|||||||
|
|
||||||
impl Closure {
|
impl Closure {
|
||||||
fn decode(data: &mut &[u32]) -> Closure {
|
fn decode(data: &mut &[u32]) -> Closure {
|
||||||
|
let shim_idx = get(data);
|
||||||
|
let dtor_idx = get(data);
|
||||||
let mutable = get(data) == REFMUT;
|
let mutable = get(data) == REFMUT;
|
||||||
assert_eq!(get(data), FUNCTION);
|
assert_eq!(get(data), FUNCTION);
|
||||||
Closure {
|
Closure {
|
||||||
|
shim_idx,
|
||||||
|
dtor_idx,
|
||||||
mutable,
|
mutable,
|
||||||
function: Function::decode(data),
|
function: Function::decode(data),
|
||||||
}
|
}
|
||||||
@ -304,11 +311,13 @@ impl Closure {
|
|||||||
|
|
||||||
impl Function {
|
impl Function {
|
||||||
fn decode(data: &mut &[u32]) -> Function {
|
fn decode(data: &mut &[u32]) -> Function {
|
||||||
|
let shim_idx = get(data);
|
||||||
let arguments = (0..get(data))
|
let arguments = (0..get(data))
|
||||||
.map(|_| Descriptor::_decode(data))
|
.map(|_| Descriptor::_decode(data))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
Function {
|
Function {
|
||||||
arguments,
|
arguments,
|
||||||
|
shim_idx,
|
||||||
ret: Descriptor::_decode(data),
|
ret: Descriptor::_decode(data),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,11 +47,12 @@ pub fn rewrite(input: &mut Context) -> Result<(), Error> {
|
|||||||
// If this was an imported function we didn't reorder those, so nothing
|
// If this was an imported function we didn't reorder those, so nothing
|
||||||
// to do.
|
// to do.
|
||||||
if idx < old_num_imports {
|
if idx < old_num_imports {
|
||||||
return idx
|
idx
|
||||||
}
|
} else {
|
||||||
// ... otherwise we're injecting a number of new imports, so offset
|
// ... otherwise we're injecting a number of new imports, so offset
|
||||||
// everything.
|
// everything.
|
||||||
idx + info.code_idx_to_descriptor.len() as u32
|
idx + info.code_idx_to_descriptor.len() as u32
|
||||||
|
}
|
||||||
}).remap_module(input.module);
|
}).remap_module(input.module);
|
||||||
|
|
||||||
info.delete_function_table_entries(input);
|
info.delete_function_table_entries(input);
|
||||||
@ -252,9 +253,9 @@ impl ClosureDescriptors {
|
|||||||
input.expose_add_heap_object();
|
input.expose_add_heap_object();
|
||||||
input.function_table_needed = true;
|
input.function_table_needed = true;
|
||||||
let body = format!(
|
let body = format!(
|
||||||
"function(a, b, fi, di, _ignored) {{
|
"function(a, b, _ignored) {{
|
||||||
const f = wasm.__wbg_function_table.get(fi);
|
const f = wasm.__wbg_function_table.get({});
|
||||||
const d = wasm.__wbg_function_table.get(di);
|
const d = wasm.__wbg_function_table.get({});
|
||||||
const cb = {};
|
const cb = {};
|
||||||
cb.a = a;
|
cb.a = a;
|
||||||
cb.cnt = 1;
|
cb.cnt = 1;
|
||||||
@ -262,6 +263,8 @@ impl ClosureDescriptors {
|
|||||||
real.original = cb;
|
real.original = cb;
|
||||||
return addHeapObject(real);
|
return addHeapObject(real);
|
||||||
}}",
|
}}",
|
||||||
|
closure.shim_idx,
|
||||||
|
closure.dtor_idx,
|
||||||
js,
|
js,
|
||||||
);
|
);
|
||||||
input.export(&import_name, &body, None);
|
input.export(&import_name, &body, None);
|
||||||
|
@ -256,7 +256,6 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
|
|||||||
self.cx.expose_uint64_cvt_shim()
|
self.cx.expose_uint64_cvt_shim()
|
||||||
};
|
};
|
||||||
self.cx.expose_uint32_memory();
|
self.cx.expose_uint32_memory();
|
||||||
self.cx.expose_global_argument_ptr()?;
|
|
||||||
self.js_arguments.push((name.clone(), "BigInt".to_string()));
|
self.js_arguments.push((name.clone(), "BigInt".to_string()));
|
||||||
self.prelude(&format!(
|
self.prelude(&format!(
|
||||||
"
|
"
|
||||||
@ -374,7 +373,6 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
|
|||||||
self.cx.expose_uint64_cvt_shim()
|
self.cx.expose_uint64_cvt_shim()
|
||||||
};
|
};
|
||||||
self.cx.expose_uint32_memory();
|
self.cx.expose_uint32_memory();
|
||||||
self.cx.expose_global_argument_ptr()?;
|
|
||||||
self.js_arguments.push((name.clone(), "BigInt".to_string()));
|
self.js_arguments.push((name.clone(), "BigInt".to_string()));
|
||||||
self.prelude(&format!(
|
self.prelude(&format!(
|
||||||
"
|
"
|
||||||
|
@ -459,8 +459,10 @@ impl<'a> Context<'a> {
|
|||||||
Ok(String::from("function(idx) { throw takeObject(idx); }"))
|
Ok(String::from("function(idx) { throw takeObject(idx); }"))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
closures::rewrite(self).with_context(|_| {
|
||||||
|
"failed to generate internal closure shims"
|
||||||
|
})?;
|
||||||
self.unexport_unused_internal_exports();
|
self.unexport_unused_internal_exports();
|
||||||
closures::rewrite(self)?;
|
|
||||||
|
|
||||||
// Handle the `start` function, if one was specified. If we're in a
|
// Handle the `start` function, if one was specified. If we're in a
|
||||||
// --test mode (such as wasm-bindgen-test-runner) then we skip this
|
// --test mode (such as wasm-bindgen-test-runner) then we skip this
|
||||||
@ -1682,23 +1684,6 @@ impl<'a> Context<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expose_get_global_argument(&mut self) -> Result<(), Error> {
|
|
||||||
if !self.exposed_globals.insert("get_global_argument") {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
self.expose_uint32_memory();
|
|
||||||
self.expose_global_argument_ptr()?;
|
|
||||||
self.global(
|
|
||||||
"
|
|
||||||
function getGlobalArgument(arg) {
|
|
||||||
const idx = globalArgumentPtr() / 4 + arg;
|
|
||||||
return getUint32Memory()[idx];
|
|
||||||
}
|
|
||||||
",
|
|
||||||
);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn expose_global_argument_ptr(&mut self) -> Result<(), Error> {
|
fn expose_global_argument_ptr(&mut self) -> Result<(), Error> {
|
||||||
if !self.exposed_globals.insert("global_argument_ptr") {
|
if !self.exposed_globals.insert("global_argument_ptr") {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
@ -2337,7 +2322,12 @@ impl<'a, 'b> SubContext<'a, 'b> {
|
|||||||
self.generate_enum(e);
|
self.generate_enum(e);
|
||||||
}
|
}
|
||||||
for s in self.program.structs.iter() {
|
for s in self.program.structs.iter() {
|
||||||
self.generate_struct(s)?;
|
self.generate_struct(s).with_context(|_| {
|
||||||
|
format!(
|
||||||
|
"failed to generate bindings for Rust struct `{}`",
|
||||||
|
s.name,
|
||||||
|
)
|
||||||
|
})?;
|
||||||
}
|
}
|
||||||
for s in self.program.typescript_custom_sections.iter() {
|
for s in self.program.typescript_custom_sections.iter() {
|
||||||
self.cx.typescript.push_str(s);
|
self.cx.typescript.push_str(s);
|
||||||
|
@ -252,6 +252,7 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some((f, mutable)) = arg.stack_closure() {
|
if let Some((f, mutable)) = arg.stack_closure() {
|
||||||
|
let arg2 = self.shim_argument();
|
||||||
let (js, _ts, _js_doc) = {
|
let (js, _ts, _js_doc) = {
|
||||||
let mut builder = Js2Rust::new("", self.cx);
|
let mut builder = Js2Rust::new("", self.cx);
|
||||||
if mutable {
|
if mutable {
|
||||||
@ -268,20 +269,19 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
|
|||||||
.process(f)?
|
.process(f)?
|
||||||
.finish("function", "this.f")
|
.finish("function", "this.f")
|
||||||
};
|
};
|
||||||
self.cx.expose_get_global_argument()?;
|
|
||||||
self.cx.function_table_needed = true;
|
self.cx.function_table_needed = true;
|
||||||
let next_global = self.global_idx();
|
|
||||||
self.global_idx();
|
self.global_idx();
|
||||||
self.prelude(&format!(
|
self.prelude(&format!(
|
||||||
"\
|
"\
|
||||||
let cb{0} = {js};\n\
|
let cb{0} = {js};\n\
|
||||||
cb{0}.f = wasm.__wbg_function_table.get({0});\n\
|
cb{0}.f = wasm.__wbg_function_table.get({idx});\n\
|
||||||
cb{0}.a = getGlobalArgument({next_global});\n\
|
cb{0}.a = {0};\n\
|
||||||
cb{0}.b = getGlobalArgument({next_global} + 1);\n\
|
cb{0}.b = {1};\n\
|
||||||
",
|
",
|
||||||
abi,
|
abi,
|
||||||
|
arg2,
|
||||||
js = js,
|
js = js,
|
||||||
next_global = next_global
|
idx = f.shim_idx,
|
||||||
));
|
));
|
||||||
self.finally(&format!("cb{0}.a = cb{0}.b = 0;", abi));
|
self.finally(&format!("cb{0}.a = cb{0}.b = 0;", abi));
|
||||||
self.js_arguments.push(format!("cb{0}.bind(cb{0})", abi));
|
self.js_arguments.push(format!("cb{0}.bind(cb{0})", abi));
|
||||||
|
@ -353,8 +353,6 @@ impl Interpreter {
|
|||||||
self.descriptor_table_idx = Some(self.stack.pop().unwrap() as u32);
|
self.descriptor_table_idx = Some(self.stack.pop().unwrap() as u32);
|
||||||
self.stack.pop();
|
self.stack.pop();
|
||||||
self.stack.pop();
|
self.stack.pop();
|
||||||
self.stack.pop();
|
|
||||||
self.stack.pop();
|
|
||||||
self.stack.push(0);
|
self.stack.push(0);
|
||||||
} else {
|
} else {
|
||||||
self.call(*idx, sections);
|
self.call(*idx, sections);
|
||||||
|
@ -197,20 +197,16 @@ impl<T> Closure<T>
|
|||||||
unsafe fn breaks_if_inlined<T: WasmClosure + ?Sized>(
|
unsafe fn breaks_if_inlined<T: WasmClosure + ?Sized>(
|
||||||
a: usize,
|
a: usize,
|
||||||
b: usize,
|
b: usize,
|
||||||
invoke: u32,
|
|
||||||
destroy: u32,
|
|
||||||
) -> u32 {
|
) -> u32 {
|
||||||
super::__wbindgen_describe_closure(
|
super::__wbindgen_describe_closure(
|
||||||
a as u32,
|
a as u32,
|
||||||
b as u32,
|
b as u32,
|
||||||
invoke,
|
|
||||||
destroy,
|
|
||||||
describe::<T> as u32,
|
describe::<T> as u32,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
let idx = unsafe {
|
let idx = unsafe {
|
||||||
breaks_if_inlined::<T>(a, b, T::invoke_fn(), T::destroy_fn())
|
breaks_if_inlined::<T>(a, b)
|
||||||
};
|
};
|
||||||
|
|
||||||
Closure {
|
Closure {
|
||||||
@ -294,9 +290,6 @@ impl<T> Drop for Closure<T>
|
|||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub unsafe trait WasmClosure: 'static {
|
pub unsafe trait WasmClosure: 'static {
|
||||||
fn describe();
|
fn describe();
|
||||||
|
|
||||||
fn invoke_fn() -> u32;
|
|
||||||
fn destroy_fn() -> u32;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The memory safety here in these implementations below is a bit tricky. We
|
// The memory safety here in these implementations below is a bit tricky. We
|
||||||
@ -322,11 +315,6 @@ macro_rules! doit {
|
|||||||
R: ReturnWasmAbi + 'static,
|
R: ReturnWasmAbi + 'static,
|
||||||
{
|
{
|
||||||
fn describe() {
|
fn describe() {
|
||||||
<&Self>::describe();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn invoke_fn() -> u32 {
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
unsafe extern "C" fn invoke<$($var: FromWasmAbi,)* R: ReturnWasmAbi>(
|
unsafe extern "C" fn invoke<$($var: FromWasmAbi,)* R: ReturnWasmAbi>(
|
||||||
a: usize,
|
a: usize,
|
||||||
@ -350,12 +338,10 @@ macro_rules! doit {
|
|||||||
};
|
};
|
||||||
ret.return_abi(&mut GlobalStack::new())
|
ret.return_abi(&mut GlobalStack::new())
|
||||||
}
|
}
|
||||||
invoke::<$($var,)* R> as u32
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
inform(invoke::<$($var,)* R> as u32);
|
||||||
fn destroy_fn() -> u32 {
|
|
||||||
unsafe extern "C" fn destroy<$($var: FromWasmAbi,)* R: ReturnWasmAbi>(
|
unsafe extern fn destroy<$($var: FromWasmAbi,)* R: ReturnWasmAbi>(
|
||||||
a: usize,
|
a: usize,
|
||||||
b: usize,
|
b: usize,
|
||||||
) {
|
) {
|
||||||
@ -364,7 +350,9 @@ macro_rules! doit {
|
|||||||
fields: (a, b)
|
fields: (a, b)
|
||||||
}.ptr));
|
}.ptr));
|
||||||
}
|
}
|
||||||
destroy::<$($var,)* R> as u32
|
inform(destroy::<$($var,)* R> as u32);
|
||||||
|
|
||||||
|
<&Self>::describe();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -373,11 +361,6 @@ macro_rules! doit {
|
|||||||
R: ReturnWasmAbi + 'static,
|
R: ReturnWasmAbi + 'static,
|
||||||
{
|
{
|
||||||
fn describe() {
|
fn describe() {
|
||||||
<&mut Self>::describe();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn invoke_fn() -> u32 {
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
unsafe extern "C" fn invoke<$($var: FromWasmAbi,)* R: ReturnWasmAbi>(
|
unsafe extern "C" fn invoke<$($var: FromWasmAbi,)* R: ReturnWasmAbi>(
|
||||||
a: usize,
|
a: usize,
|
||||||
@ -402,12 +385,10 @@ macro_rules! doit {
|
|||||||
};
|
};
|
||||||
ret.return_abi(&mut GlobalStack::new())
|
ret.return_abi(&mut GlobalStack::new())
|
||||||
}
|
}
|
||||||
invoke::<$($var,)* R> as u32
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
inform(invoke::<$($var,)* R> as u32);
|
||||||
fn destroy_fn() -> u32 {
|
|
||||||
unsafe extern "C" fn destroy<$($var: FromWasmAbi,)* R: ReturnWasmAbi>(
|
unsafe extern fn destroy<$($var: FromWasmAbi,)* R: ReturnWasmAbi>(
|
||||||
a: usize,
|
a: usize,
|
||||||
b: usize,
|
b: usize,
|
||||||
) {
|
) {
|
||||||
@ -416,7 +397,9 @@ macro_rules! doit {
|
|||||||
fields: (a, b)
|
fields: (a, b)
|
||||||
}.ptr));
|
}.ptr));
|
||||||
}
|
}
|
||||||
destroy::<$($var,)* R> as u32
|
inform(destroy::<$($var,)* R> as u32);
|
||||||
|
|
||||||
|
<&mut Self>::describe();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)*)
|
)*)
|
||||||
|
@ -1,19 +1,28 @@
|
|||||||
use core::mem;
|
use core::mem;
|
||||||
|
|
||||||
use convert::{FromWasmAbi, GlobalStack, IntoWasmAbi, ReturnWasmAbi, Stack};
|
use convert::{FromWasmAbi, GlobalStack, IntoWasmAbi, ReturnWasmAbi, Stack};
|
||||||
|
use convert::slices::WasmSlice;
|
||||||
|
use describe::{inform, FUNCTION, WasmDescribe};
|
||||||
use throw_str;
|
use throw_str;
|
||||||
|
|
||||||
macro_rules! stack_closures {
|
macro_rules! stack_closures {
|
||||||
($( ($($var:ident)*) )*) => ($(
|
($( ($cnt:tt $invoke:ident $invoke_mut:ident $($var:ident)*) )*) => ($(
|
||||||
impl<'a, 'b, $($var,)* R> IntoWasmAbi for &'a (Fn($($var),*) -> R + 'b)
|
impl<'a, 'b, $($var,)* R> IntoWasmAbi for &'a (Fn($($var),*) -> R + 'b)
|
||||||
where $($var: FromWasmAbi,)*
|
where $($var: FromWasmAbi,)*
|
||||||
R: ReturnWasmAbi
|
R: ReturnWasmAbi
|
||||||
{
|
{
|
||||||
type Abi = u32;
|
type Abi = WasmSlice;
|
||||||
|
|
||||||
|
fn into_abi(self, _extra: &mut Stack) -> WasmSlice {
|
||||||
|
unsafe {
|
||||||
|
let (a, b): (usize, usize) = mem::transmute(self);
|
||||||
|
WasmSlice { ptr: a as u32, len: b as u32 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn into_abi(self, extra: &mut Stack) -> u32 {
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
unsafe extern "C" fn invoke<$($var: FromWasmAbi,)* R: ReturnWasmAbi>(
|
unsafe extern "C" fn $invoke<$($var: FromWasmAbi,)* R: ReturnWasmAbi>(
|
||||||
a: usize,
|
a: usize,
|
||||||
b: usize,
|
b: usize,
|
||||||
$($var: <$var as FromWasmAbi>::Abi),*
|
$($var: <$var as FromWasmAbi>::Abi),*
|
||||||
@ -33,12 +42,17 @@ macro_rules! stack_closures {
|
|||||||
};
|
};
|
||||||
ret.return_abi(&mut GlobalStack::new())
|
ret.return_abi(&mut GlobalStack::new())
|
||||||
}
|
}
|
||||||
unsafe {
|
|
||||||
let (a, b): (usize, usize) = mem::transmute(self);
|
impl<'a, $($var,)* R> WasmDescribe for Fn($($var),*) -> R + 'a
|
||||||
extra.push(a as u32);
|
where $($var: FromWasmAbi,)*
|
||||||
extra.push(b as u32);
|
R: ReturnWasmAbi
|
||||||
invoke::<$($var,)* R> as u32
|
{
|
||||||
}
|
fn describe() {
|
||||||
|
inform(FUNCTION);
|
||||||
|
inform($invoke::<$($var,)* R> as u32);
|
||||||
|
inform($cnt);
|
||||||
|
$(<$var as WasmDescribe>::describe();)*
|
||||||
|
<R as WasmDescribe>::describe();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,11 +60,18 @@ macro_rules! stack_closures {
|
|||||||
where $($var: FromWasmAbi,)*
|
where $($var: FromWasmAbi,)*
|
||||||
R: ReturnWasmAbi
|
R: ReturnWasmAbi
|
||||||
{
|
{
|
||||||
type Abi = u32;
|
type Abi = WasmSlice;
|
||||||
|
|
||||||
|
fn into_abi(self, _extra: &mut Stack) -> WasmSlice {
|
||||||
|
unsafe {
|
||||||
|
let (a, b): (usize, usize) = mem::transmute(self);
|
||||||
|
WasmSlice { ptr: a as u32, len: b as u32 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn into_abi(self, extra: &mut Stack) -> u32 {
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
unsafe extern "C" fn invoke<$($var: FromWasmAbi,)* R: ReturnWasmAbi>(
|
unsafe extern "C" fn $invoke_mut<$($var: FromWasmAbi,)* R: ReturnWasmAbi>(
|
||||||
a: usize,
|
a: usize,
|
||||||
b: usize,
|
b: usize,
|
||||||
$($var: <$var as FromWasmAbi>::Abi),*
|
$($var: <$var as FromWasmAbi>::Abi),*
|
||||||
@ -70,24 +91,29 @@ macro_rules! stack_closures {
|
|||||||
};
|
};
|
||||||
ret.return_abi(&mut GlobalStack::new())
|
ret.return_abi(&mut GlobalStack::new())
|
||||||
}
|
}
|
||||||
unsafe {
|
|
||||||
let (a, b): (usize, usize) = mem::transmute(self);
|
impl<'a, $($var,)* R> WasmDescribe for FnMut($($var),*) -> R + 'a
|
||||||
extra.push(a as u32);
|
where $($var: FromWasmAbi,)*
|
||||||
extra.push(b as u32);
|
R: ReturnWasmAbi
|
||||||
invoke::<$($var,)* R> as u32
|
{
|
||||||
}
|
fn describe() {
|
||||||
|
inform(FUNCTION);
|
||||||
|
inform($invoke_mut::<$($var,)* R> as u32);
|
||||||
|
inform($cnt);
|
||||||
|
$(<$var as WasmDescribe>::describe();)*
|
||||||
|
<R as WasmDescribe>::describe();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)*)
|
)*)
|
||||||
}
|
}
|
||||||
|
|
||||||
stack_closures! {
|
stack_closures! {
|
||||||
()
|
(0 invoke0 invoke0_mut)
|
||||||
(A)
|
(1 invoke1 invoke1_mut A)
|
||||||
(A B)
|
(2 invoke2 invoke2_mut A B)
|
||||||
(A B C)
|
(3 invoke3 invoke3_mut A B C)
|
||||||
(A B C D)
|
(4 invoke4 invoke4_mut A B C D)
|
||||||
(A B C D E)
|
(5 invoke5 invoke5_mut A B C D E)
|
||||||
(A B C D E F)
|
(6 invoke6 invoke6_mut A B C D E F)
|
||||||
(A B C D E F G)
|
(7 invoke7 invoke7_mut A B C D E F G)
|
||||||
}
|
}
|
||||||
|
@ -133,72 +133,6 @@ if_std! {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! cnt {
|
|
||||||
() => {
|
|
||||||
0
|
|
||||||
};
|
|
||||||
(A) => {
|
|
||||||
1
|
|
||||||
};
|
|
||||||
(A B) => {
|
|
||||||
2
|
|
||||||
};
|
|
||||||
(A B C) => {
|
|
||||||
3
|
|
||||||
};
|
|
||||||
(A B C D) => {
|
|
||||||
4
|
|
||||||
};
|
|
||||||
(A B C D E) => {
|
|
||||||
5
|
|
||||||
};
|
|
||||||
(A B C D E F) => {
|
|
||||||
6
|
|
||||||
};
|
|
||||||
(A B C D E F G) => {
|
|
||||||
7
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! doit {
|
|
||||||
($( ($($var:ident)*))*) => ($(
|
|
||||||
impl<'a, $($var,)* R> WasmDescribe for Fn($($var),*) -> R + 'a
|
|
||||||
where $($var: WasmDescribe,)*
|
|
||||||
R: WasmDescribe
|
|
||||||
{
|
|
||||||
fn describe() {
|
|
||||||
inform(FUNCTION);
|
|
||||||
inform(cnt!($($var)*));
|
|
||||||
$(<$var as WasmDescribe>::describe();)*
|
|
||||||
<R as WasmDescribe>::describe();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, $($var,)* R> WasmDescribe for FnMut($($var),*) -> R + 'a
|
|
||||||
where $($var: WasmDescribe,)*
|
|
||||||
R: WasmDescribe
|
|
||||||
{
|
|
||||||
fn describe() {
|
|
||||||
inform(FUNCTION);
|
|
||||||
inform(cnt!($($var)*));
|
|
||||||
$(<$var as WasmDescribe>::describe();)*
|
|
||||||
<R as WasmDescribe>::describe();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)*)
|
|
||||||
}
|
|
||||||
|
|
||||||
doit! {
|
|
||||||
()
|
|
||||||
(A)
|
|
||||||
(A B)
|
|
||||||
(A B C)
|
|
||||||
(A B C D)
|
|
||||||
(A B C D E)
|
|
||||||
(A B C D E F)
|
|
||||||
(A B C D E F G)
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: WasmDescribe> WasmDescribe for Option<T> {
|
impl<T: WasmDescribe> WasmDescribe for Option<T> {
|
||||||
fn describe() {
|
fn describe() {
|
||||||
inform(OPTIONAL);
|
inform(OPTIONAL);
|
||||||
|
@ -483,7 +483,7 @@ externs! {
|
|||||||
fn __wbindgen_cb_forget(idx: u32) -> ();
|
fn __wbindgen_cb_forget(idx: u32) -> ();
|
||||||
|
|
||||||
fn __wbindgen_describe(v: u32) -> ();
|
fn __wbindgen_describe(v: u32) -> ();
|
||||||
fn __wbindgen_describe_closure(a: u32, b: u32, c: u32, d: u32, e: u32) -> u32;
|
fn __wbindgen_describe_closure(a: u32, b: u32, c: u32) -> u32;
|
||||||
|
|
||||||
fn __wbindgen_json_parse(ptr: *const u8, len: usize) -> u32;
|
fn __wbindgen_json_parse(ptr: *const u8, len: usize) -> u32;
|
||||||
fn __wbindgen_json_serialize(idx: u32, ptr: *mut *mut u8) -> usize;
|
fn __wbindgen_json_serialize(idx: u32, ptr: *mut *mut u8) -> usize;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user