Skip to content

WebAssembly won't initialize without the debugger #1558

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
m-abs opened this issue Dec 23, 2019 · 3 comments
Closed

WebAssembly won't initialize without the debugger #1558

m-abs opened this issue Dec 23, 2019 · 3 comments
Assignees
Milestone

Comments

@m-abs
Copy link

m-abs commented Dec 23, 2019

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):

  • CLI: 6.3.0
  • Cross-platform modules: 6.3.1
  • Android Runtime: 6.3.0
  • iOS Runtime (if applicable): Not Applicable
  • Plugin(s): None

Devices:

  • Oneplus 7T Pro McLaren - Android 10
  • Emulator - Android 9/SDK 29.

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

  1. Start the app normally with tns run android
  2. Attempt to initialize the WASM code.
  3. The promise is never resolved or rejected.

But it will resolve if I use the chrome debugger:
Steps to load with the debugger.

  1. Start the app with tns debug android
  2. Attempt to initialize the WASM code.
  3. Connect the chrome-debugger via devtools://devtools/bundled/inspector.html?experiments=true&ws=localhost:40000
  4. Enter and run this code
(function() { debugger; })();
  1. Step to next line a few time and let it continue.
  2. If the promise wasn't resolved, press arrow-up to go back in the console.

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

@NathanaelA

This comment was marked as abuse.

@m-abs
Copy link
Author

m-abs commented Dec 24, 2019

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.

@darind darind added the bug label Jan 15, 2020
@darind
Copy link
Collaborator

darind commented Jan 15, 2020

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);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants