From a5e3454d8abcb72c50b8b9e6ecda4fb870e86dba Mon Sep 17 00:00:00 2001 From: Pauan Date: Mon, 10 Feb 2020 07:29:44 +0100 Subject: [PATCH 1/2] Improving wasm loading logic --- crates/cli-support/src/js/mod.rs | 96 +++++++++++++++++--------------- 1 file changed, 50 insertions(+), 46 deletions(-) diff --git a/crates/cli-support/src/js/mod.rs b/crates/cli-support/src/js/mod.rs index a42424380f7..de06ffa7d22 100644 --- a/crates/cli-support/src/js/mod.rs +++ b/crates/cli-support/src/js/mod.rs @@ -433,20 +433,20 @@ impl<'a> Context<'a> { let default_module_path = match self.config.mode { OutputMode::Web => { "\ - if (typeof module === 'undefined') { - module = import.meta.url.replace(/\\.js$/, '_bg.wasm'); + if (typeof input === 'undefined') { + input = import.meta.url.replace(/\\.js$/, '_bg.wasm'); }" } OutputMode::NoModules { .. } => { "\ - if (typeof module === 'undefined') { + if (typeof input === 'undefined') { let src; if (self.document === undefined) { src = self.location.href; } else { src = self.document.currentScript.src; } - module = src.replace(/\\.js$/, '_bg.wasm'); + input = src.replace(/\\.js$/, '_bg.wasm'); }" } _ => "", @@ -503,54 +503,58 @@ impl<'a> Context<'a> { let js = format!( "\ - function init(module{init_memory_arg}) {{ - {default_module_path} - let result; - const imports = {{}}; - {imports_init} - if ((typeof URL === 'function' && module instanceof URL) || typeof module === 'string' || (typeof Request === 'function' && module instanceof Request)) {{ + async function load(module, imports) {{ + if (typeof Response === 'function' && module instanceof Response) {{ {init_memory2} - const response = fetch(module); if (typeof WebAssembly.instantiateStreaming === 'function') {{ - result = WebAssembly.instantiateStreaming(response, imports) - .catch(e => {{ - return response - .then(r => {{ - if (r.headers.get('Content-Type') != 'application/wasm') {{ - console.warn(\"`WebAssembly.instantiateStreaming` failed \ - because your server does not serve wasm with \ - `application/wasm` MIME type. Falling back to \ - `WebAssembly.instantiate` which is slower. Original \ - error:\\n\", e); - return r.arrayBuffer(); - }} else {{ - throw e; - }} - }}) - .then(bytes => WebAssembly.instantiate(bytes, imports)); - }}); - }} else {{ - result = response - .then(r => r.arrayBuffer()) - .then(bytes => WebAssembly.instantiate(bytes, imports)); + try {{ + return await WebAssembly.instantiateStreaming(module, imports); + + }} catch (e) {{ + if (module.headers.get('Content-Type') != 'application/wasm') {{ + console.warn(\"`WebAssembly.instantiateStreaming` failed \ + because your server does not serve wasm with \ + `application/wasm` MIME type. Falling back to \ + `WebAssembly.instantiate` which is slower. Original \ + error:\\n\", e); + + }} else {{ + throw e; + }} + }} }} + + const bytes = await module.arrayBuffer(); + return await WebAssembly.instantiate(bytes, imports); + }} else {{ {init_memory1} - result = WebAssembly.instantiate(module, imports) - .then(result => {{ - if (result instanceof WebAssembly.Instance) {{ - return {{ instance: result, module }}; - }} else {{ - return result; - }} - }}); + const instance = await WebAssembly.instantiate(module, imports); + + if (instance instanceof WebAssembly.Instance) {{ + return {{ instance, module }}; + + }} else {{ + return instance; + }} }} - return result.then(({{instance, module}}) => {{ - wasm = instance.exports; - init.__wbindgen_wasm_module = module; - {start} - return wasm; - }}); + }} + + async function init(input{init_memory_arg}) {{ + {default_module_path} + const imports = {{}}; + {imports_init} + + if (typeof input === 'string' || (typeof Request === 'function' && input instanceof Request) || (typeof URL === 'function' && input instanceof URL)) {{ + input = fetch(input); + }} + + const {{ instance, module }} = await load(await input, imports); + + wasm = instance.exports; + init.__wbindgen_wasm_module = module; + {start} + return wasm; }} ", init_memory_arg = init_memory_arg, From b11130520097ce85683ba530216baab345f80423 Mon Sep 17 00:00:00 2001 From: Pauan Date: Tue, 11 Feb 2020 11:55:52 +0100 Subject: [PATCH 2/2] Adding in note to the book about the new loading functionality --- examples/without-a-bundler/index.html | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/examples/without-a-bundler/index.html b/examples/without-a-bundler/index.html index 94efda916a2..7296030f5c5 100644 --- a/examples/without-a-bundler/index.html +++ b/examples/without-a-bundler/index.html @@ -19,12 +19,25 @@ // default export to inform it where the wasm file is located on the // server, and then we wait on the returned promise to wait for the // wasm to be loaded. + // // It may look like this: `await init('./pkg/without_a_bundler_bg.wasm');`, // but there is also a handy default inside `init` function, which uses - // `import.meta` to locate the wasm file relatively to js file + // `import.meta` to locate the wasm file relatively to js file. + // + // Note that instead of a string you can also pass in any of the + // following things: + // + // * `WebAssembly.Module` + // + // * `ArrayBuffer` + // + // * `Response` + // + // * `Promise` which returns any of the above, e.g. `fetch("./path/to/wasm")` + // + // This gives you complete control over how the module is loaded + // and compiled. // - // Note that instead of a string here you can also pass in an instance - // of `WebAssembly.Module` which allows you to compile your own module. // Also note that the promise, when resolved, yields the wasm module's // exports which is the same as importing the `*_bg` module in other // modes