From 34b75c35b22984828c58e69b866fb65eba2b9bda Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 16 Oct 2018 10:48:07 -0700 Subject: [PATCH] Allow passing a `WebAssembly.Module` in `--no-modules` I've noticed this in a few cases where it's sometimes easy to have a `WebAssembly.Module` on-hand for the `--no-modules` mode where you don't want to necessarily `fetch`. This commit changes the exported initialization function in `--no-modules` mode to support both! --- crates/cli-support/src/js/mod.rs | 47 ++++++++++++++++++-------------- guide/src/reference/no-esm.md | 12 ++++---- 2 files changed, 32 insertions(+), 27 deletions(-) diff --git a/crates/cli-support/src/js/mod.rs b/crates/cli-support/src/js/mod.rs index f2a31793c..8d6d28457 100644 --- a/crates/cli-support/src/js/mod.rs +++ b/crates/cli-support/src/js/mod.rs @@ -418,27 +418,32 @@ impl<'a> Context<'a> { let mut js = if self.config.no_modules { format!( "\ - (function() {{ - var wasm; - const __exports = {{}}; - {globals} - function init(wasm_path) {{ - const fetchPromise = fetch(wasm_path); - let resultPromise; - if (typeof WebAssembly.instantiateStreaming === 'function') {{ - resultPromise = WebAssembly.instantiateStreaming(fetchPromise, {{ './{module}': __exports }}); - }} else {{ - resultPromise = fetchPromise - .then(response => response.arrayBuffer()) - .then(buffer => WebAssembly.instantiate(buffer, {{ './{module}': __exports }})); - }} - return resultPromise.then(({{instance}}) => {{ - wasm = init.wasm = instance.exports; - return; - }}); - }}; - self.{global_name} = Object.assign(init, __exports); - }})();", +(function() {{ + var wasm; + const __exports = {{}}; + {globals} + function init(path_or_module) {{ + let instantiation; + const imports = {{ './{module}': __exports }}; + if (path_or_module instanceof WebAssembly.Module) {{ + instantiation = WebAssembly.instantiate(path_or_module, imports); + }} else {{ + const data = fetch(path_or_module); + if (typeof WebAssembly.instantiateStreaming === 'function') {{ + instantiation = WebAssembly.instantiateStreaming(data, imports); + }} else {{ + instantiation = data + .then(response => response.arrayBuffer()) + .then(buffer => WebAssembly.instantiate(buffer, imports)); + }} + }} + return instantiation.then(({{instance}}) => {{ + wasm = init.wasm = instance.exports; + return; + }}); + }}; + self.{global_name} = Object.assign(init, __exports); +}})();", globals = self.globals, module = module_name, global_name = self.config.no_modules_global diff --git a/guide/src/reference/no-esm.md b/guide/src/reference/no-esm.md index 25465de54..79db840ce 100644 --- a/guide/src/reference/no-esm.md +++ b/guide/src/reference/no-esm.md @@ -59,14 +59,14 @@ for the wasm-module-to-be. The page is configured with one exported global, in this case `wasm_bindgen`. The name of this global can be configured with the `--no-modules-global` option. -The global `wasm_bindgen` is a function that takes one argument, the path to the -wasm file. When invoked `wasm_bindgen` will return a promise for when the wasm -file is ready-to-go. After that all exported functionality on -`wasm_bindgen` will be functional. +The global `wasm_bindgen` is a function that takes one argument: either the path +to the wasm file to fetch or a `WebAssembly.Module`. When invoked `wasm_bindgen` +will return a promise for when the wasm module is ready-to-go. After that all +exported functionality on `wasm_bindgen` will be functional. In the example above, after calling `wasm_bindgen('./hello_bg.wasm')` we wait -for the wasm module to be compiled, and afterwards we're invoking our `greet` -export. +for the wasm module to be fetched and compiled, and afterwards we're invoking +our `greet` export. Note that exports are available for binding before the wasm module has been instantiated, for example this would have also worked: