Environment
Provide version numbers for the following components (information can be retrieved by running tns info in your project folder or by inspecting the package.json of the project):
Devices:
Describe the bug
I'm not sure why, but I can't get the promise from WebAssembly.compile(...) or WebAssembly.instantiate(...) to resolve without connecting the chrome debugger to my app and stepping through JavaScript.
What makes this really odd, is that it doesn't matter what JS-code I step through.
To Reproduce
tns run androidBut it will resolve if I use the chrome debugger:
Steps to load with the debugger.
tns debug android(function() { debugger; })();
Expected behavior
The promise from WebAssembly.compile(...) or WebAssembly.instantiate(...) to either resolve or reject without the debugger.
Sample project
Demo project here: https://github.com/m-abs/tns-wasm
WASM code is a very simple "Hello World" program.
Additional context
I looked briefly into this. I'm not 100% sure why this issue is occurring with this method of bootstrapping Wasm, but the other common way of bootstrapping Wasm works fine for me.
It might have something to do with the way it loads and converts it into an int8 array. In my test version -- I require the JS file that has the array already defined. So it could be bit different issue causing the issue.
Thank you for responding so fast.
I looked briefly into this. I'm not 100% sure why this issue is occurring with this method of bootstrapping Wasm, but the other common way of bootstrapping Wasm works fine for me.
Which method did you use?
I used this one because {N} doesn't support fetch+arraybuffer and emscripten's loader didn't work either.
It might have something to do with the way it loads and converts it into an int8 array.
I've tried using a hardcoded Uint8Array with the WASM code, unfortunately no change.
The WebAssembly's async compile API registers some ongoing work on one of v8::Platform's background threads, and eventually in the future, a task will be posted to the foreground thread to resolve the promise for the compilation.
Currently the Android runtime doesn't handle this scenario properly. For this to work we need to pump the V8 message loop and run the microtasks:
while (v8::platform::PumpMessageLoop(Runtime::platform, isolate, MessageLoopBehavior::kDoNotWait)) {
isolate->RunMicrotasks();
}
We will investigate what would be the best approach to handle this case in the runtime.
Until then you could use WebAssembly's synchronous API:
let utf8ToString = (h, p) => {
let s = "";
for (let i = p; h[i]; i++) {
s += String.fromCharCode(h[i]);
}
return s;
};
let buffer;
const importObject = {
env: {
puts(index) {
console.log(utf8ToString(buffer, index));
}
}
};
const wasmCode = new Uint8Array([
0, 97, 115, 109, 1, 0, 0, 0, 1, 138, 128, 128, 128, 0, 2, 96, 1,
127, 1, 127, 96, 0, 1, 127, 2, 140, 128, 128, 128, 0, 1, 3, 101,
110, 118, 4, 112, 117, 116, 115, 0, 0, 3, 130, 128, 128, 128, 0,
1, 1, 4, 132, 128, 128, 128, 0, 1, 112, 0, 0, 5, 131, 128, 128,
128, 0, 1, 0, 1, 6, 129, 128, 128, 128, 0, 0, 7, 145, 128, 128,
128, 0, 2, 6, 109, 101, 109, 111, 114, 121, 2, 0, 4, 109, 97, 105,
110, 0, 1, 10, 143, 128, 128, 128, 0, 1, 137, 128, 128, 128, 0, 0,
65, 16, 16, 0, 26, 65, 0, 11, 11, 148, 128, 128, 128, 0, 1, 0, 65,
16, 11, 14, 104, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108,
100, 33, 0
]);
const wasmModule = new WebAssembly.Module(wasmCode);
const moduleInstance = new WebAssembly.Instance(wasmModule, importObject);
buffer = new Uint8Array(moduleInstance.exports.memory.buffer);
let result = moduleInstance.exports.main();
console.log(result);
Most helpful comment
The WebAssembly's async compile API registers some ongoing work on one of
v8::Platform'sbackground threads, and eventually in the future, a task will be posted to the foreground thread to resolve the promise for the compilation.Currently the Android runtime doesn't handle this scenario properly. For this to work we need to pump the V8 message loop and run the microtasks:
We will investigate what would be the best approach to handle this case in the runtime.
Until then you could use WebAssembly's synchronous API: