Admin message

Due to a large amount of spam we do not allow new users to create repositories, they are "external" users. If you are a new user and want to create a repository, for example for forking GHC, open a new issue on ghc/ghc using the "get-verified" issue template

wasm backend: ghc_wasm_jsffi.js uses top-level await, cannot be loaded from a module ServiceWorker
## Summary `utils/jsffi/prelude.mjs` initializes `setImmediate` with a top-level `await` on an async IIFE (lines 42–91), so every `ghc_wasm_jsffi.js` emitted by `post-link.mjs` is an async ESM module. This blocks module ServiceWorkers, which spec-reject registration of async modules — see [w3c/ServiceWorker#1407](https://github.com/w3c/ServiceWorker/issues/1407) (closed by [PR #1444](https://github.com/w3c/ServiceWorker/pull/1444), which adds a `TypeError`-throwing branch for async module scripts in the Update algorithm). The `await` exists only for the Deno branch (`await import("node:timers")`, line 51); the four other branches are sync. Two possible fixes that keep behavior identical and remove the TLA: - Replace the dynamic `import()` with `createRequire(import.meta.url)("node:timers")`, which is sync; or - Drop the Deno branch entirely — Deno ≥ 2.4 exposes `globalThis.setImmediate` unconditionally (earlier 2.x needed `--unstable-node-globals`), so the first sync branch already covers it. Source: <https://gitlab.haskell.org/ghc/ghc/-/blob/master/utils/jsffi/prelude.mjs> ## Steps to reproduce 1. Build a minimal reactor module and post-link it: ```sh cat > Main.hs <<'EOF' module Main where import GHC.Wasm.Prim main :: IO () main = pure () foreign export javascript "setup" setup :: IO () setup :: IO () setup = pure () EOF wasm32-wasi-ghc -no-hs-main \ -optl-Wl,--export=setup \ -optl-mexec-model=reactor \ -o Main.wasm Main.hs "$(wasm32-wasi-ghc --print-libdir)/post-link.mjs" \ -i Main.wasm -o ghc_wasm_jsffi.js ``` 2. Inspect `ghc_wasm_jsffi.js` — `setImmediate` is initialized via `await (async () => { ... })()` at module top level. 3. Try to load it (directly or transitively) from a module ServiceWorker. Minimal `sw.js`: ```js // sw.js import "./ghc_wasm_jsffi.js"; // install/activate handlers omitted — registration rejects // before they fire. ``` Page-side: ```js await navigator.serviceWorker.register("./sw.js", { type: "module" }); ``` Observed (Chrome v148): ``` installHook.js:1 SW registration error: TypeError: Failed to register a ServiceWorker for scope ('http://localhost:8000/') with script ('http://localhost:8000/sw.js'): ServiceWorker cannot be started overrideMethod @ installHook.js:1 ``` Registration rejects because the SW module graph contains TLA. ## Expected behavior `ghc_wasm_jsffi.js` should be a synchronous ESM module so it can be imported from a module ServiceWorker (and from any other consumer that can't host TLA). ## Environment * GHC version used: 9.14.1.20260330 (`ghc-wasm-meta` master nightly) Optional: * Operating System: macOS * System Architecture: x86_64 --- _Drafted with help from Claude; please flag any factual errors._
issue