mirror of
https://github.com/fluencelabs/wasm-bindgen
synced 2025-06-16 14:31:22 +00:00
Merge pull request #1065 from alexcrichton/describe-closures
Move closure shims into the descriptor
This commit is contained in:
@ -70,11 +70,14 @@ pub enum Descriptor {
|
||||
#[derive(Debug)]
|
||||
pub struct Function {
|
||||
pub arguments: Vec<Descriptor>,
|
||||
pub shim_idx: u32,
|
||||
pub ret: Descriptor,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Closure {
|
||||
pub shim_idx: u32,
|
||||
pub dtor_idx: u32,
|
||||
pub function: Function,
|
||||
pub mutable: bool,
|
||||
}
|
||||
@ -293,9 +296,13 @@ fn get(a: &mut &[u32]) -> u32 {
|
||||
|
||||
impl Closure {
|
||||
fn decode(data: &mut &[u32]) -> Closure {
|
||||
let shim_idx = get(data);
|
||||
let dtor_idx = get(data);
|
||||
let mutable = get(data) == REFMUT;
|
||||
assert_eq!(get(data), FUNCTION);
|
||||
Closure {
|
||||
shim_idx,
|
||||
dtor_idx,
|
||||
mutable,
|
||||
function: Function::decode(data),
|
||||
}
|
||||
@ -304,11 +311,13 @@ impl Closure {
|
||||
|
||||
impl Function {
|
||||
fn decode(data: &mut &[u32]) -> Function {
|
||||
let shim_idx = get(data);
|
||||
let arguments = (0..get(data))
|
||||
.map(|_| Descriptor::_decode(data))
|
||||
.collect::<Vec<_>>();
|
||||
Function {
|
||||
arguments,
|
||||
shim_idx,
|
||||
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
|
||||
// to do.
|
||||
if idx < old_num_imports {
|
||||
return idx
|
||||
idx
|
||||
} else {
|
||||
// ... otherwise we're injecting a number of new imports, so offset
|
||||
// everything.
|
||||
idx + info.code_idx_to_descriptor.len() as u32
|
||||
}
|
||||
// ... otherwise we're injecting a number of new imports, so offset
|
||||
// everything.
|
||||
idx + info.code_idx_to_descriptor.len() as u32
|
||||
}).remap_module(input.module);
|
||||
|
||||
info.delete_function_table_entries(input);
|
||||
@ -252,9 +253,9 @@ impl ClosureDescriptors {
|
||||
input.expose_add_heap_object();
|
||||
input.function_table_needed = true;
|
||||
let body = format!(
|
||||
"function(a, b, fi, di, _ignored) {{
|
||||
const f = wasm.__wbg_function_table.get(fi);
|
||||
const d = wasm.__wbg_function_table.get(di);
|
||||
"function(a, b, _ignored) {{
|
||||
const f = wasm.__wbg_function_table.get({});
|
||||
const d = wasm.__wbg_function_table.get({});
|
||||
const cb = {};
|
||||
cb.a = a;
|
||||
cb.cnt = 1;
|
||||
@ -262,6 +263,8 @@ impl ClosureDescriptors {
|
||||
real.original = cb;
|
||||
return addHeapObject(real);
|
||||
}}",
|
||||
closure.shim_idx,
|
||||
closure.dtor_idx,
|
||||
js,
|
||||
);
|
||||
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_uint32_memory();
|
||||
self.cx.expose_global_argument_ptr()?;
|
||||
self.js_arguments.push((name.clone(), "BigInt".to_string()));
|
||||
self.prelude(&format!(
|
||||
"
|
||||
@ -374,7 +373,6 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
|
||||
self.cx.expose_uint64_cvt_shim()
|
||||
};
|
||||
self.cx.expose_uint32_memory();
|
||||
self.cx.expose_global_argument_ptr()?;
|
||||
self.js_arguments.push((name.clone(), "BigInt".to_string()));
|
||||
self.prelude(&format!(
|
||||
"
|
||||
|
@ -459,8 +459,10 @@ impl<'a> Context<'a> {
|
||||
Ok(String::from("function(idx) { throw takeObject(idx); }"))
|
||||
})?;
|
||||
|
||||
closures::rewrite(self).with_context(|_| {
|
||||
"failed to generate internal closure shims"
|
||||
})?;
|
||||
self.unexport_unused_internal_exports();
|
||||
closures::rewrite(self)?;
|
||||
|
||||
// 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
|
||||
@ -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> {
|
||||
if !self.exposed_globals.insert("global_argument_ptr") {
|
||||
return Ok(());
|
||||
@ -2337,7 +2322,12 @@ impl<'a, 'b> SubContext<'a, 'b> {
|
||||
self.generate_enum(e);
|
||||
}
|
||||
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() {
|
||||
self.cx.typescript.push_str(s);
|
||||
|
@ -252,6 +252,7 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
|
||||
}
|
||||
|
||||
if let Some((f, mutable)) = arg.stack_closure() {
|
||||
let arg2 = self.shim_argument();
|
||||
let (js, _ts, _js_doc) = {
|
||||
let mut builder = Js2Rust::new("", self.cx);
|
||||
if mutable {
|
||||
@ -268,20 +269,19 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
|
||||
.process(f)?
|
||||
.finish("function", "this.f")
|
||||
};
|
||||
self.cx.expose_get_global_argument()?;
|
||||
self.cx.function_table_needed = true;
|
||||
let next_global = self.global_idx();
|
||||
self.global_idx();
|
||||
self.prelude(&format!(
|
||||
"\
|
||||
let cb{0} = {js};\n\
|
||||
cb{0}.f = wasm.__wbg_function_table.get({0});\n\
|
||||
cb{0}.a = getGlobalArgument({next_global});\n\
|
||||
cb{0}.b = getGlobalArgument({next_global} + 1);\n\
|
||||
cb{0}.f = wasm.__wbg_function_table.get({idx});\n\
|
||||
cb{0}.a = {0};\n\
|
||||
cb{0}.b = {1};\n\
|
||||
",
|
||||
abi,
|
||||
arg2,
|
||||
js = js,
|
||||
next_global = next_global
|
||||
idx = f.shim_idx,
|
||||
));
|
||||
self.finally(&format!("cb{0}.a = cb{0}.b = 0;", abi));
|
||||
self.js_arguments.push(format!("cb{0}.bind(cb{0})", abi));
|
||||
|
Reference in New Issue
Block a user