Summary
Fix Emscripten builds when WebAssembly reference types are disabled with -mno-reference-types. Fixes #161782.
CPython's optional JSPI syscall wrappers unconditionally use externref types, preventing compilation and WebAssembly instantiation on older browsers such as Chromium 85, even when JSPI is unused.
This change:
- Guards the reference-type-dependent JSPI code with
__wasm_reference_types__.
- Provides a no-op interpreter startup hook when reference types are disabled.
- Preserves synchronous read and poll implementations.
- Leaves existing JSPI functionality unchanged when reference types are enabled.
The change is limited to Python/emscripten_syscalls.c and includes a NEWS fragment.
Motivation
Discovered while bringing up Kodi's WebAssembly build on a 2022 Samsung Q60B TV using Emscripten 7.0.0.
Chromium 85 does not support WebAssembly reference types. Runtime feature detection cannot prevent compilation or instantiation failures caused by unsupported externref types in the module.
This allows CPython to support targets without reference types while retaining JSPI functionality on newer runtimes.
Related downstream fix: xbmc/xbmc#30431
Testing
Validated against CPython main using Emscripten 7.0.0 and Node.js 26:
- Both
-mno-reference-types and -mreference-types compile with warnings treated as errors.
- Eight focused runtime configurations pass, covering interpreter startup, embedded startup, synchronous syscall fallbacks, JSPI read/poll, and error handling.
- Modules built without reference types contain no
externref instructions and pass WebAssembly validation with reference types disabled.
- The reference-types-enabled object is byte-for-byte identical to the original.
- NEWS fragment generation and parsing pass.
git diff --check passes.
A full CPython build and test suite were not run. The upstream change has not yet been tested directly on Samsung Chromium 85.
AI disclosure
Model: GPT-6 Astra
Thinking effort: Extra High