mirror of
https://github.com/rustwasm/wasm-bindgen.git
synced 2024-11-28 05:52:21 +03:00
Remove temporary object allocation
When returning a ptr/length for allocations and such wasm-bindgen's generated JS would previously return an array with two elements. It turns out this doesn't optimize well in all engines! (See #1031). It looks like we can optimize the array destructuring a bit more, but this is all generated code which doesn't need to be too readable so we can also remove the temporary allocation entirely and just pass the second element of this array through a global instead of the return value. Closes #1031
This commit is contained in:
parent
8520a54f63
commit
c915870526
@ -155,7 +155,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
|
||||
format!("{}({})", func, name)
|
||||
};
|
||||
self.prelude(&format!(
|
||||
"const [ptr{i}, len{i}] = {val};",
|
||||
"const ptr{i} = {val};\nconst len{i} = WASM_VECTOR_LEN;",
|
||||
i = i,
|
||||
val = val,
|
||||
));
|
||||
|
@ -319,8 +319,8 @@ impl<'a> Context<'a> {
|
||||
function(i, len_ptr) {
|
||||
let obj = getObject(i);
|
||||
if (typeof(obj) !== 'string') return 0;
|
||||
const [ptr, len] = passStringToWasm(obj);
|
||||
getUint32Memory()[len_ptr / 4] = len;
|
||||
const ptr = passStringToWasm(obj);
|
||||
getUint32Memory()[len_ptr / 4] = WASM_VECTOR_LEN;
|
||||
return ptr;
|
||||
}
|
||||
",
|
||||
@ -368,9 +368,9 @@ impl<'a> Context<'a> {
|
||||
Ok(String::from(
|
||||
"
|
||||
function(idx, ptrptr) {
|
||||
const [ptr, len] = passStringToWasm(JSON.stringify(getObject(idx)));
|
||||
const ptr = passStringToWasm(JSON.stringify(getObject(idx)));
|
||||
getUint32Memory()[ptrptr / 4] = ptr;
|
||||
return len;
|
||||
return WASM_VECTOR_LEN;
|
||||
}
|
||||
",
|
||||
))
|
||||
@ -994,6 +994,13 @@ impl<'a> Context<'a> {
|
||||
));
|
||||
}
|
||||
|
||||
fn expose_wasm_vector_len(&mut self) {
|
||||
if !self.exposed_globals.insert("wasm_vector_len") {
|
||||
return;
|
||||
}
|
||||
self.global("let WASM_VECTOR_LEN = 0;");
|
||||
}
|
||||
|
||||
fn expose_pass_string_to_wasm(&mut self) -> Result<(), Error> {
|
||||
if !self.exposed_globals.insert("pass_string_to_wasm") {
|
||||
return Ok(());
|
||||
@ -1001,6 +1008,7 @@ impl<'a> Context<'a> {
|
||||
self.require_internal_export("__wbindgen_malloc")?;
|
||||
self.expose_text_encoder();
|
||||
self.expose_uint8_memory();
|
||||
self.expose_wasm_vector_len();
|
||||
let debug = if self.config.debug {
|
||||
"
|
||||
if (typeof(arg) !== 'string') throw new Error('expected a string argument');
|
||||
@ -1015,7 +1023,8 @@ impl<'a> Context<'a> {
|
||||
const buf = cachedTextEncoder.encode(arg);
|
||||
const ptr = wasm.__wbindgen_malloc(buf.length);
|
||||
getUint8Memory().set(buf, ptr);
|
||||
return [ptr, buf.length];
|
||||
WASM_VECTOR_LEN = buf.length;
|
||||
return ptr;
|
||||
}}
|
||||
",
|
||||
debug
|
||||
@ -1068,7 +1077,8 @@ impl<'a> Context<'a> {
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
mem[ptr / 4 + i] = addHeapObject(array[i]);
|
||||
}
|
||||
return [ptr, array.length];
|
||||
WASM_VECTOR_LEN = array.length;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
",
|
||||
@ -1086,12 +1096,14 @@ impl<'a> Context<'a> {
|
||||
return Ok(());
|
||||
}
|
||||
self.require_internal_export("__wbindgen_malloc")?;
|
||||
self.expose_wasm_vector_len();
|
||||
self.global(&format!(
|
||||
"
|
||||
function {}(arg) {{
|
||||
const ptr = wasm.__wbindgen_malloc(arg.length * {size});
|
||||
{}().set(arg, ptr / {size});
|
||||
return [ptr, arg.length];
|
||||
WASM_VECTOR_LEN = arg.length;
|
||||
return ptr;
|
||||
}}
|
||||
",
|
||||
name,
|
||||
|
@ -328,7 +328,8 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
|
||||
self.ret_expr = format!(
|
||||
"\
|
||||
{}
|
||||
const [retptr, retlen] = {};
|
||||
const retptr = {};
|
||||
const retlen = WASM_VECTOR_LEN;
|
||||
const mem = getUint32Memory();
|
||||
mem[ret / 4] = retptr;
|
||||
mem[ret / 4 + 1] = retlen;
|
||||
|
Loading…
Reference in New Issue
Block a user