cloudflare / workerd

The JavaScript / Wasm runtime that powers Cloudflare Workers

Home Page:https://blog.cloudflare.com/workerd-open-source-workers-runtime/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

πŸ› BUG: Uncaught error when initializing two top level WASM modules

pi0 opened this issue Β· comments

Which Cloudflare product(s) does this pertain to?

Miniflare

What version(s) of the tool(s) are you using?

3.20231218.0

What version of Node are you using?

v20.10.0

What operating system are you using?

Mac

Describe the Bug

When using dynamic imports to load two wasm modules in parallel using top-level await, any second await attempt failed with an uncaught error.

Minimal Reproduction: https://github.com/pi0/miniflare-reproduction

mode-a.mjs and mode-b.mjs:

const mod = (await import("./sum.wasm")).default;
const instance = await WebAssembly.instantiate(mod);

export const sum = instance.exports.sum;

worker.mjs:

let [a, b] = ["-", "-"];

// Only works if one await happens!
a = await import("./mod-a.mjs").then((r) => r.sum(1, 2));
b = await import("./mod-b.mjs").then((r) => r.sum(3, 4));

export default {
  async fetch(request, env, ctx) {
    // This works (also in parallel)
    // a = await import("./mod-a.mjs").then((r) => r.sum(1, 2));
    // b = await import("./mod-b.mjs").then((r) => r.sum(3, 4));

    return new Response(JSON.stringify([a, b], null, 2), {
      headers: { "content-type": "application/json" },
    });
  },
};

Note: Importing alone works, but any attempt to access or call exports fails with error:

Stack trace: (attached)

(minfilare config uses modules: true + moduleRules for CompiledWasm)


Context: Discovered in tests while working on unjs/unwasm#11 (unwasm will be used as the default WASM handler for Nuxt and Nitro projects and also for CF deployments πŸ”₯ )
the

Please provide a link to a minimal reproduction

https://github.com/pi0/miniflare-reproduction

Please provide any relevant error logs

workerd/jsg/modules.c++:336: error: Async module was not immediately resolved.
service core:user:: Uncaught ReferenceError: Cannot access 'sum' before initialization
  at src/worker.mjs:5:47
/Users/pooya/tmp/miniflare-reproduction/node_modules/miniflare/dist/src/index.js:8890
      throw new MiniflareCoreError(
            ^

MiniflareCoreError [ERR_RUNTIME_FAILURE]: The Workers runtime failed to start. There is likely additional logging output above.
    at #assembleAndUpdateConfig (/Users/pooya/tmp/miniflare-reproduction/node_modules/miniflare/dist/src/index.js:8890:13)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async Mutex.runWith (/Users/pooya/tmp/miniflare-reproduction/node_modules/miniflare/dist/src/index.js:3861:16)
    at async #waitForReady (/Users/pooya/tmp/miniflare-reproduction/node_modules/miniflare/dist/src/index.js:8940:5)
    at async Miniflare.dispatchFetch (/Users/pooya/tmp/miniflare-reproduction/node_modules/miniflare/dist/src/index.js:9004:5)

Fantastic minimal reproduction! Thank you @pi0
I suspect this is an issue with workerd itself rather than Miniflare...

Ideally we need a reproduction that only uses workerd, then I can transfer this over to https://github.com/cloudflare/workerd

I just tried deploying the worker and it actually seems to be working fine in workerd πŸ˜• : https://wasm-bug-worker.dario-piotrowicz.workers.dev/

Could this be related to how Miniflare imports such modules rather than there being something wrong in workerd itself?

I managed to reproduce this just with workerd: https://github.com/petebacondarwin/toplevel-async-wasm-workerd-repro

So I propose we transfer this issue there...

Interestingly @pi0 - the issue can be avoided if you do not use the async WebAssembly.instantiate() call but instead use the sync new WebAssembly.Instance() constructor.