diff --git a/crates/cli-support/src/js/mod.rs b/crates/cli-support/src/js/mod.rs index 2c9cddadbf9..303c18546f8 100644 --- a/crates/cli-support/src/js/mod.rs +++ b/crates/cli-support/src/js/mod.rs @@ -12,7 +12,7 @@ use std::fmt; use std::fmt::Write; use std::fs; use std::path::{Path, PathBuf}; -use walrus::{ExportItem, FunctionId, ImportId, MemoryId, Module, TableId, ValType}; +use walrus::{FunctionId, ImportId, MemoryId, Module, TableId, ValType}; mod binding; @@ -403,8 +403,6 @@ impl<'a> Context<'a> { ))), ); - footer.push_str(&self.post_instantiate()); - if needs_manual_start { footer.push_str("\nwasm.__wbindgen_start();\n"); } @@ -418,7 +416,6 @@ impl<'a> Context<'a> { footer.push_str(&self.generate_deno_wasm_loading(module_name)); footer.push_str("\n\n"); - footer.push_str(&self.post_instantiate()); if needs_manual_start { footer.push_str("\nwasm.__wbindgen_start();\n"); @@ -454,9 +451,6 @@ impl<'a> Context<'a> { } } - footer.push('\n'); - footer.push_str(&self.post_instantiate()); - if needs_manual_start { start = Some("\nwasm.__wbindgen_start();\n".to_string()); } @@ -587,37 +581,6 @@ impl<'a> Context<'a> { Ok(imports) } - /// Returns JS to be run immediately after the wasm module is instantiated, - /// before the start function is called. - fn post_instantiate(&self) -> String { - let mut out = String::new(); - // Initialise all the memory views. - for (&mem_id, &(num, ref views)) in &self.memories { - // We can't just use `export_name_of` because it takes `&mut self` and we've already borrowed `views`. - let mem = match self - .module - .exports - .iter() - .find(|export| matches!(export.item, ExportItem::Memory(id) if id == mem_id)) - { - Some(export) => &export.name, - None => continue, - }; - - for kind in views { - writeln!( - out, - "cached{kind}Memory{num} = new {kind}Array(wasm.{mem}.buffer);", - kind = kind, - num = num, - mem = mem, - ) - .unwrap() - } - } - out - } - fn ts_for_init_fn( &self, has_memory: bool, @@ -797,6 +760,22 @@ impl<'a> Context<'a> { imports_init.push_str(&format!("imports['{}'] = __wbg_star{};\n", extra, i)); } + let mut init_memviews = String::new(); + for &(num, ref views) in self.memories.values() { + for kind in views { + writeln!( + init_memviews, + // Reset the memory views to empty in case `init` gets called multiple times. + // Without this, the `length = 0` check would never detect that the view was + // outdated. + "cached{kind}Memory{num} = new {kind}Array();", + kind = kind, + num = num, + ) + .unwrap() + } + } + let js = format!( "\ async function load(module, imports) {{ @@ -847,7 +826,7 @@ impl<'a> Context<'a> { function finalizeInit(instance, module) {{ wasm = instance.exports; init.__wbindgen_wasm_module = module; - {post_instantiate} + {init_memviews} {start} return wasm; }} @@ -881,7 +860,7 @@ impl<'a> Context<'a> { init_memory_arg = init_memory_arg, default_module_path = default_module_path, init_memory = init_memory, - post_instantiate = self.post_instantiate(), + init_memviews = init_memviews, start = if needs_manual_start { "wasm.__wbindgen_start();" } else { @@ -1749,9 +1728,12 @@ impl<'a> Context<'a> { format!("{cache}.byteLength === 0", cache = cache) }; + // Initialize the cache to an empty array, which will trigger the resized check + // on the first call and initialise the view. + self.global(&format!("let {cache} = new {kind}Array();\n")); + self.global(&format!( " - let {cache}; function {name}() {{ if ({resized_check}) {{ {cache} = new {kind}Array(wasm.{mem}.buffer); diff --git a/crates/cli/tests/reference/anyref-import-catch.js b/crates/cli/tests/reference/anyref-import-catch.js index c4eb9714c06..6d5394d788a 100644 --- a/crates/cli/tests/reference/anyref-import-catch.js +++ b/crates/cli/tests/reference/anyref-import-catch.js @@ -6,7 +6,8 @@ let cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true cachedTextDecoder.decode(); -let cachedUint8Memory0; +let cachedUint8Memory0 = new Uint8Array(); + function getUint8Memory0() { if (cachedUint8Memory0.byteLength === 0) { cachedUint8Memory0 = new Uint8Array(wasm.memory.buffer); @@ -33,7 +34,8 @@ function handleError(f, args) { } } -let cachedInt32Memory0; +let cachedInt32Memory0 = new Int32Array(); + function getInt32Memory0() { if (cachedInt32Memory0.byteLength === 0) { cachedInt32Memory0 = new Int32Array(wasm.memory.buffer); @@ -81,6 +83,3 @@ export function __wbindgen_init_externref_table() { ; }; -cachedInt32Memory0 = new Int32Array(wasm.memory.buffer); -cachedUint8Memory0 = new Uint8Array(wasm.memory.buffer); - diff --git a/crates/cli/tests/reference/import-catch.js b/crates/cli/tests/reference/import-catch.js index d7a7bf837f3..6f9a1bc1578 100644 --- a/crates/cli/tests/reference/import-catch.js +++ b/crates/cli/tests/reference/import-catch.js @@ -23,7 +23,8 @@ function handleError(f, args) { } } -let cachedInt32Memory0; +let cachedInt32Memory0 = new Int32Array(); + function getInt32Memory0() { if (cachedInt32Memory0.byteLength === 0) { cachedInt32Memory0 = new Int32Array(wasm.memory.buffer); @@ -64,5 +65,3 @@ export function __wbg_foo_8d66ddef0ff279d6() { return handleError(function () { foo(); }, arguments) }; -cachedInt32Memory0 = new Int32Array(wasm.memory.buffer); - diff --git a/crates/cli/tests/reference/result-string.js b/crates/cli/tests/reference/result-string.js index 708880bb8b8..a9d60cc3cb0 100644 --- a/crates/cli/tests/reference/result-string.js +++ b/crates/cli/tests/reference/result-string.js @@ -15,7 +15,8 @@ function addHeapObject(obj) { return idx; } -let cachedInt32Memory0; +let cachedInt32Memory0 = new Int32Array(); + function getInt32Memory0() { if (cachedInt32Memory0.byteLength === 0) { cachedInt32Memory0 = new Int32Array(wasm.memory.buffer); @@ -43,7 +44,8 @@ let cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true cachedTextDecoder.decode(); -let cachedUint8Memory0; +let cachedUint8Memory0 = new Uint8Array(); + function getUint8Memory0() { if (cachedUint8Memory0.byteLength === 0) { cachedUint8Memory0 = new Uint8Array(wasm.memory.buffer); @@ -83,6 +85,3 @@ export function __wbindgen_number_new(arg0) { return addHeapObject(ret); }; -cachedInt32Memory0 = new Int32Array(wasm.memory.buffer); -cachedUint8Memory0 = new Uint8Array(wasm.memory.buffer); - diff --git a/crates/cli/tests/reference/string-arg.js b/crates/cli/tests/reference/string-arg.js index 9c93a69b759..deba025f926 100644 --- a/crates/cli/tests/reference/string-arg.js +++ b/crates/cli/tests/reference/string-arg.js @@ -6,7 +6,8 @@ let cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true cachedTextDecoder.decode(); -let cachedUint8Memory0; +let cachedUint8Memory0 = new Uint8Array(); + function getUint8Memory0() { if (cachedUint8Memory0.byteLength === 0) { cachedUint8Memory0 = new Uint8Array(wasm.memory.buffer); @@ -87,5 +88,3 @@ export function __wbindgen_throw(arg0, arg1) { throw new Error(getStringFromWasm0(arg0, arg1)); }; -cachedUint8Memory0 = new Uint8Array(wasm.memory.buffer); -