Created
December 31, 2017 01:09
-
-
Save cdetrio/7f5486004b0054b5c08e0496cf3ab21f to your computer and use it in GitHub Desktop.
async wasm imports don't work
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<title>Async wasm doesnt work</title> | |
</head> | |
<script> | |
/* | |
// wasm code: | |
(module | |
(func $some_i32 (import "env" "some_func") (result i32)) | |
(func $some_async_i32 (import "env" "some_func_doing_async") (result i32)) | |
(func $test (param $p1 i32) (result i32) | |
(get_local $p1) | |
(if (result i32) | |
;; pass 55 as the $p1 param to $test to call import function $some_i32 | |
;; pass anything else to call the import function $some_async_i32 | |
(i32.ne (i32.const 55)) | |
(then | |
;; call the imported function $some_async_i32 to get a number | |
;; whatever $some_async_i32 returns is left on the stack, | |
;; and is then returned as the result of $test | |
(call $some_async_i32) | |
) | |
(else | |
(call $some_i32) | |
;; (i32.const 88))) return a constant | |
) | |
) | |
) | |
(export "testFunc" (func $test)) | |
) | |
*/ | |
/* | |
// **** paste wasm and js code into wat2wasm: | |
https://cdn.rawgit.com/WebAssembly/wabt/aae5a4b7/demo/wat2wasm/ | |
const importFunctions = { | |
env: { | |
some_func: function() { return 88; }, | |
some_func_doing_async: function() { return Promise.resolve(99); } | |
} | |
}; | |
const wasmInstance = new WebAssembly.Instance(wasmModule, importFunctions); | |
const { testFunc } = wasmInstance.exports; | |
console.log(testFunc(55)); // call some_func import | |
console.log(testFunc(3)); // call async import | |
*/ | |
async function foo() { | |
// some function that does async work to get a result | |
return 99; | |
} | |
const importFunctions = { | |
env: { | |
some_func: function() { return 88; }, // synchronous return works | |
some_func_doing_async: function() { return foo(); }, // async return doesnt work | |
// some_func_doing_async: function() { return Promise.resolve(99); }, // promise doesnt work | |
} | |
}; | |
fetch('asyncexample.wasm').then(response => | |
response.arrayBuffer() | |
).then(bytes => | |
WebAssembly.instantiate(bytes, importFunctions) | |
).then(w => { | |
console.log('synchronous wasm import returns:', w.instance.exports.testFunc(55)); // prints 88 | |
console.log('async wasm import returned:', w.instance.exports.testFunc(3)); // prints value returned by some_func_doing_async | |
}); | |
</script> | |
<body> | |
</body> | |
</html> |
Update: This doesn't work in browser (when using browserify)
Tried this quick work-around, wasm blocks on calling the async function (via deasync), and then returns the correct result. Meanwhile, node can process other events (as shown by the setTimeout
at the end):
const fs = require('fs')
const deasync = require('deasync')
const buf = fs.readFileSync('./esimple.wasm')
const myAsync = (cb) => {
setTimeout(() => cb(null, 99), 1000)
}
const myDeasynced = deasync(myAsync)
const importFunctions = {
env: {
some_func: function() { return 88 },
some_func_doing_async: function() {
return myDeasynced()
}
}
}
WebAssembly.instantiate(buf, importFunctions).then((result) => {
const { testFunc } = result.instance.exports
console.log(testFunc(55)) // call some_func import
console.log(testFunc(3)) // call async import
})
setTimeout(() => console.log('other event'), 300)
This logs:
88
other event
99
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
See related issue WebAssembly/design#720