Skip to content

Commit

Permalink
Use WebAssembly.compileStreaming API if available (#5606)
Browse files Browse the repository at this point in the history
This API is a post-MVP addition
(http://webassembly.org/docs/web/#additional-web-embedding-api) that does
streaming compilation (i.e compiles the wasm binary as it downloads), resulting
in faster instantiation in the non-cached case.
  • Loading branch information
dschuff authored Sep 28, 2017
1 parent 82e9691 commit 24ea1a9
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 7 deletions.
32 changes: 25 additions & 7 deletions src/preamble.js
Original file line number Diff line number Diff line change
Expand Up @@ -2318,19 +2318,37 @@ function integrateWasmJS() {
// later), so we save Module and check it later.
var trueModule = Module;
#endif
getBinaryPromise().then(function(binary) {
return WebAssembly.instantiate(binary, info)
}).then(function(output) {
function receiveInstantiatedSource(output) {
// 'output' is a WebAssemblyInstantiatedSource object which has both the module and instance.
// receiveInstance() will swap in the exports (to Module.asm) so they can be called
#if ASSERTIONS
assert(Module === trueModule, 'the Module object should not be replaced during async compilation - perhaps the order of HTML elements is wrong?');
trueModule = null;
#endif
receiveInstance(output['instance']);
}).catch(function(reason) {
Module['printErr']('failed to asynchronously prepare wasm: ' + reason);
abort(reason);
});
}
function instantiateArrayBuffer(receiver) {
getBinaryPromise().then(function(binary) {
return WebAssembly.instantiate(binary, info);
}).then(receiver).catch(function(reason) {
Module['printErr']('failed to asynchronously prepare wasm: ' + reason);
abort(reason);
});
}
// Prefer streaming instantiation if available.
if (!Module['wasmBinary'] && typeof WebAssembly.instantiateStreaming === 'function') {
WebAssembly.instantiateStreaming(fetch(wasmBinaryFile, { credentials: 'same-origin' }), info)
.then(receiveInstantiatedSource)
.catch(function(reason) {
// We expect the most common failure cause to be a bad MIME type for the binary,
// in which case falling back to ArrayBuffer instantiation should work.
Module['printErr']('wasm streaming compile failed: ' + reason);
Module['printErr']('falling back to ArrayBuffer instantiation');
instantiateArrayBuffer(receiveInstantiatedSource);
});
} else {
instantiateArrayBuffer(receiveInstantiatedSource);
}
return {}; // no exports yet; we'll fill them in later
#else
var instance;
Expand Down
2 changes: 2 additions & 0 deletions tests/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -746,6 +746,8 @@ def do_GET(self):
def log_request(code=0, size=0):
# don't log; too noisy
pass

SimpleHTTPServer.SimpleHTTPRequestHandler.extensions_map['.wasm'] = 'application/wasm'
os.chdir(dir)
httpd = BaseHTTPServer.HTTPServer(('localhost', 8888), TestServerHandler)
httpd.serve_forever() # test runner will kill us
Expand Down

2 comments on commit 24ea1a9

@kripken
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This appears to have broken ./tests/runner.py browser.test_binaryen_async on both firefox and chrome.

Does it still work for you, @dschuff?

@dschuff
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, no it looks broken for me too. I'll look into it.

Please sign in to comment.