Skip to content

Emscripten: Use wasm-gc for call trampolines instead of JS type reflection #128627

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
hoodmane opened this issue Jan 8, 2025 · 1 comment
Closed
Labels
interpreter-core (Objects, Python, Grammar, and Parser dirs) OS-emscripten type-feature A feature request or enhancement

Comments

@hoodmane
Copy link
Contributor

hoodmane commented Jan 8, 2025

Followup to: #121698. WebAssembly in the browser is soon gaining stack switching support, but we're not allowed to stack switch through JS frames. The stack switching support used to require the wasm-js-type-reflection proposal, so in #121698 I updated the call trampoline to use js type reflection if it's present to avoid the JS frame and so the problem was fixed. However, the stack switching proposal has since been updated not to depend on type reflection, and it is going to be shipped while type reflection is still waiting for further refinement. This change means I need a different solution. Fortunately, wasm-gc is in stage 4 (shipped everywhere) and adds a webassembly instruction to query the type of a function. Unfortunately, toolchain support for wasm-gc is poor. Not even my favored assembler supports it.

Another problem is that the existing code is incompatible with memory snapshots since it calls JS initialization code that needs to happen even if restoring a memory snapshot from C code that is skipped when restoring a memory snapshot. I'll fix this at the same time.

Linked PRs

hoodmane added a commit to hoodmane/cpython that referenced this issue Jan 8, 2025
Part of the ongoing quest to support JSPI. The JSPI spec removed its dependence on
JS type reflection, and now the plan is for runtimes to ship JSPI while keeping
type reflection in stage 3. So we need an alternative way to count the number of
parameters of a function. It is possible to count them by repeatedly trying to
instantiate a webassembly module with the function as an import of a different type
signature. But this is pretty inefficient.

Since WebAssembly gc is now stage 4, there is a new option. WebAssembly gc added the
`ref.test` instruction which can ask if a funcref has a given type. It's a bit difficult
to apply because even our usual assembler the wasm binary toolkit doesn't support this
instruction yet. But all JS engines that support JSPI support it. We just have to do some
manual work to produce the binary.

This code also has to be written carefully to interact properly with memory snapshots.
Importantly, no JS initialization code can be called from the C initialization code.
For this reason, we make a C function pointer to fill from JS and fill it in a preRun
function.
freakboy3742 pushed a commit that referenced this issue Jan 12, 2025
…128628)

Replaces the trampoline mechanism in Emscripten with an implementation that uses a
recently added feature of wasm-gc instead of JS type reflection, when that feature is
available.
hoodmane added a commit to hoodmane/cpython that referenced this issue Jan 13, 2025
…poline

We need to divide the entire memory address by 4, not just the base address.
@picnixz picnixz added interpreter-core (Objects, Python, Grammar, and Parser dirs) type-feature A feature request or enhancement labels Jan 13, 2025
freakboy3742 pushed a commit that referenced this issue Jan 23, 2025
…#128782)

Modifies the memory calculation to divide the entire memory address by 4, not just the base address.
ambv added a commit to ambv/cpython that referenced this issue Feb 21, 2025
As of iOS 18.3.1, enabling wasm-gc is making the interpreter fail to load.
Downstream pyodide issue: pyodide/pyodide#5428.

macOS Safari 18.3 does not surface the issue.

Confirmed on device that disabling this restores interpreter function.
freakboy3742 pushed a commit that referenced this issue Feb 23, 2025
As of iOS 18.3.1, enabling wasm-gc breaks the interpreter. This disables the wasm-gc
trampoline on iOS.

Co-authored-by: Hood Chatham <roberthoodchatham@gmail.com>
@hoodmane
Copy link
Contributor Author

This is now broken in Emscripten 4.0.3 because of:
emscripten-core/emscripten#23875

seehwan pushed a commit to seehwan/cpython that referenced this issue Apr 16, 2025
…#130418)

As of iOS 18.3.1, enabling wasm-gc breaks the interpreter. This disables the wasm-gc
trampoline on iOS.

Co-authored-by: Hood Chatham <roberthoodchatham@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
interpreter-core (Objects, Python, Grammar, and Parser dirs) OS-emscripten type-feature A feature request or enhancement
Projects
None yet
Development

No branches or pull requests

3 participants