Skip to content

How to access wasm2js bulk memory #5390

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
willcohen opened this issue Jan 4, 2023 · 5 comments
Closed

How to access wasm2js bulk memory #5390

willcohen opened this issue Jan 4, 2023 · 5 comments

Comments

@willcohen
Copy link
Contributor

willcohen commented Jan 4, 2023

In attempting to load a wasm2js-generated js file on graaljs, I hit the following error:

failed to compile wasm module: TypeError: Cannot read property 'buffer' of undefined
Execution error (PolyglotException) at <js>/asmFunc (src.js:493).
TypeError: Cannot read property 'buffer' of undefined

It's referring to these lines in the transpiled js, implying that the env.memory section is undefined.

function asmFunc(env) {
 var memory = env.memory;
 var buffer = memory.buffer;

This error occurs when using the shell environment, which I suppose graal isn't, but running the transpilation without setting an env fails with Aborted(Assertion failed: shell environment detected but not enabled at build time. Add 'shell' to -sENVIRONMENT to enable.)

Should I be using a different environment, does this mean that the shell environment needs something else to generate a WebAssembly.Memory, or does there need to be an entirely new graal environment?

@willcohen
Copy link
Contributor Author

I should note that graalwasm loads the wasm fine and can handle the bulk memory, but since graalwasm isn't available as a standalone item, being able to run a js file as a fallback still has a use case. The error continues with -s SHARED_MEMORY=1, which I assume is also needed.

@kripken
Copy link
Member

kripken commented Jan 4, 2023

Yes, if graaljs is not close enough to either the node or shell environments in Emscripten, then something will need to be done. One option might be to add some polyfills right before loading the js+wasm, to make it look like either node or a shell. See this related issue:

emscripten-core/emscripten#12203

As mentioned there, web/worker/node/shell used to be enough, but these days there is also deno, bun, and more (like graaljs in fact) so we probably need a more scalable solution. The idea in that issue would make it hopefully simple to add such a "polyfill file" for something like graaljs.

@willcohen
Copy link
Contributor Author

willcohen commented Jan 5, 2023

Excellent, many thanks -- I think this gets me much of the way there. Looks like this may actually be more of an emscripten issue, but before I open another issue there, seeing if I can find the precise issue. The graal stack trace is:

1. Unhandled org.graalvm.polyglot.PolyglotException
   TypeError: Cannot read property 'buffer' of undefined

                    src.js:  411  <js>/asmFunc
                    src.js:873854  <js>/instantiate
                    src.js:  342  <js>/Instance
                    src.js:874495  <js>/instantiateSync
                    src.js:874552  <js>/createWasm
                    src.js:879540  <js>/:program

Tracing through the -O0 file, the failures are as follows:
asmFunc's env doesn't have a memory:
Screenshot 2023-01-05 at 11 05 02 AM

The env is derived from asmLibraryArg:
Screenshot 2023-01-05 at 11 06 10 AM

asmLibraryArg comes from instantiate:
Screenshot 2023-01-05 at 11 07 50 AM

asmLibraryArg's memory comes from wasmMemory:
Screenshot 2023-01-05 at 11 11 51 AM

This requires WebAssembly.Memory:
Screenshot 2023-01-05 at 11 13 02 AM

Implying that something about the creation of the buffer by the emscripten js might be where the failure happens:
Screenshot 2023-01-05 at 11 14 34 AM

I am passing a Graal/native-backed-and-proxied-to js ArrayBuffer via Module['buffer'] as pre-js (as noted here) which should be the graal-friendly way to do this, but it doesn't seem like it's being called or referenced anywhere. I do see the changelog mentioning a while back that Module.buffer was a removed internal detail a while back.

Do you know if there is another preferred way to pass a non-wasm ArrayBuffer?

@willcohen
Copy link
Contributor Author

Using the emcc options at https://github.com/emscripten-core/emscripten/blob/a6e8d85e2a70aac8dfaa9e96e92491d4e350736e/test/test_browser.py#L4582 and adding an INITIAL_MEMORY to the pre-js Module per https://github.com/emscripten-core/emscripten/blob/main/test/test_preallocated_heap_shell.html#L79-L80, the error continues.

That said, given that the functionality seems to be present and actively tested, it's probably just an incantation problem on my end somewhere with the flags or options rather than a emscripten bug.

@willcohen
Copy link
Contributor Author

Closing in favor of emscripten-core/emscripten#18474.

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

No branches or pull requests

2 participants