Skip to content

[browser] WASM exception handling to use the standardized exnref #129851

Open
pavelsavara wants to merge 3 commits into
dotnet:mainfrom
pavelsavara:emsdk-upgrade-wasm_exceptions2
Open

[browser] WASM exception handling to use the standardized exnref #129851
pavelsavara wants to merge 3 commits into
dotnet:mainfrom
pavelsavara:emsdk-upgrade-wasm_exceptions2

Conversation

@pavelsavara

@pavelsavara pavelsavara commented Jun 25, 2026

Copy link
Copy Markdown
Member

Disables V8 legs until we have image with 15.1.103

Fixes #119961

Summary

This change upgrades the WebAssembly toolchain (emsdk / Emscripten + wasm-opt) and switches the
browser runtime from the legacy WASM exception-handling encoding to the standardized
exnref-based exception-handling proposal (try_table / throw_ref).

Concretely, every place that previously passed WASM_LEGACY_EXCEPTIONS=1 now passes
WASM_LEGACY_EXCEPTIONS=0, the jiterpreter codegen emits try_table instead of the legacy
try/catch opcodes, and feature detection / JS-engine flags are updated to require the final EH
proposal (--experimental-wasm-exnref).

Because the V8 baked into our CI containers (and the jsvu-installed V8 used by perf) does not yet
support --experimental-wasm-exnref, the V8 test legs are temporarily disabled and tracked by
#129849. Build/publish coverage is preserved;
only the V8 execution step is skipped.

Changes

Toolchain flags: legacy EH → standardized EH

  • eng/native/configureplatform.cmake — CoreCLR browser build: WASM_LEGACY_EXCEPTIONS=0 for both
    compile and link, and switch to the EH-specific runtime libraries
    (-lc++-wasmexcept, -lc++abi-wasmexcept, -lunwind-wasmexcept).
  • src/mono/mono/mini/CMakeLists.txtmono-wasm-eh-wasm compile/link flags set
    WASM_LEGACY_EXCEPTIONS=0.
  • src/mono/browser/browser.proj — Mono runtime build flags set WASM_LEGACY_EXCEPTIONS=0.
  • src/mono/browser/build/BrowserWasmApp.targets,
    src/mono/browser/build/BrowserWasmApp.CoreCLR.targets,
    src/mono/wasm/build/WasmApp.Common.targets — app build flags updated; wasm-opt now runs with
    --enable-reference-types (required for exnref) alongside --enable-exception-handling.
  • src/mono/browser/runtime/CMakeLists.txt — Release wasm-opt post-build step adds
    --enable-reference-types.

Jiterpreter codegen: emit try_table / exnref

  • src/mono/browser/runtime/jiterpreter-opcodes.ts — replace the legacy
    try_/catch_/catch_all/throw_/rethrow_ opcodes with throw_ref (0x0a) and
    try_table (0x1f).
  • src/mono/browser/runtime/jiterpreter-support.ts — add tryTable(...) and getTagIndex(...)
    helpers (tags live in a separate index space from types), and rename the enableWasmEh option to
    enableWasmFinalEh (the underlying jiterpreter-wasm-eh-enabled flag name is unchanged).
  • src/mono/browser/runtime/jiterpreter-jit-call.ts — wrap the jit-call body in a
    (block (block (try_table (catch __cpp_exception ...) ...))) structure instead of the legacy
    try/catch block.

Feature detection and startup

  • src/mono/browser/runtime/loader/globals.ts,
    src/mono/browser/runtime/types/internal.ts,
    src/mono/browser/runtime/startup.ts — switch from the exceptions to the exceptionsFinal
    detector of the wasm-feature-detect package; rename featureWasmEhfeatureWasmFinalEh.
  • src/mono/browser/runtime/startup.ts — minor worker-startup reordering (call
    successCallback before preRunWorker).

JS-engine arguments for tests / samples

Add --experimental-wasm-exnref wherever V8 / Node is launched:

  • eng/testing/WasmRunnerTemplate.cmd, eng/testing/WasmRunnerTemplate.sh
  • src/tests/Common/CLRTest.Execute.Bash.targets, src/tests/Common/CLRTest.Execute.Batch.targets
  • src/mono/browser/build/BrowserWasmApp.targets (generated V8 run script)
  • src/mono/sample/wasm/wasm.mk,
    src/mono/sample/wasm/console-node/Wasm.Console.Node.Sample.csproj,
    src/mono/sample/wasm/console-v8/Wasm.Console.V8.Sample.csproj

CI images and versions

  • eng/pipelines/common/templates/pipeline-with-resources.yml — bump the
    azurelinux-3.0-net11.0-webassembly prereqs image (new emsdk) for browser_wasm and wasi_wasm.
  • eng/testing/BrowserVersions.props — bump V8 to 15.1.103 on Linux/macOS/Windows.

Temporarily disable V8 test legs (tracked by #129849)

The CI/perf V8 doesn't support --experimental-wasm-exnref yet, so V8 execution is skipped while
keeping build/publish coverage:

  • eng/pipelines/common/templates/runtimes/build-runtime-tests-and-send-to-helix.yml — add a
    sendToHelix parameter (default true) so callers can build but not send to Helix.
  • eng/pipelines/common/templates/wasm-runtime-tests.yml — pass sendToHelix: false.
  • eng/pipelines/runtime.yml — comment out the WasmTestOnV8 scenario (Firefox still runs).
  • eng/pipelines/performance/runtime-wasm-perf.yml — disable the PR trigger (pr: none).
  • eng/pipelines/runtime-linker-tests.yml + eng/testing/linker/trimmingTests.targets — add
    SkipTrimmingTestsRun=true to publish trimmed browser apps without executing them on V8.

@pavelsavara pavelsavara added this to the 11.0.0 milestone Jun 25, 2026
@pavelsavara pavelsavara self-assigned this Jun 25, 2026
Copilot AI review requested due to automatic review settings June 25, 2026 14:00
@pavelsavara pavelsavara added arch-wasm WebAssembly architecture area-Build-mono os-browser Browser variant of arch-wasm labels Jun 25, 2026
@pavelsavara

Copy link
Copy Markdown
Member Author

/azp run runtime-wasm

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the browser/WASM stack to use standardized exnref-based WebAssembly exception handling (e.g., try_table / throw_ref) instead of the legacy encoding, and wires the necessary toolchain / runtime / test-runner flags across build and CI.

Changes:

  • Switch Emscripten/emsdk builds from WASM_LEGACY_EXCEPTIONS=1 to 0, and ensure post-link wasm-opt enables reference types.
  • Update the browser runtime feature detection and the jiterpreter wasm codegen to use exceptionsFinal + try_table-based EH constructs.
  • Update test/sample runners and CI templates to pass --experimental-wasm-exnref, and temporarily skip V8 execution legs where the engine can’t run the new encoding yet.

Reviewed changes

Copilot reviewed 29 out of 29 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/tests/Common/CLRTest.Execute.Batch.targets Adds --experimental-wasm-exnref to Node invocation when running browser tests via Node on Windows.
src/tests/Common/CLRTest.Execute.Bash.targets Adds --experimental-wasm-exnref to Node invocation when running browser tests via Node on Unix.
src/mono/wasm/build/WasmApp.Common.targets Adds --enable-reference-types to wasm-opt post-link flags.
src/mono/sample/wasm/wasm.mk Adds --experimental-wasm-exnref when running sample apps under V8/Node.
src/mono/sample/wasm/console-v8/Wasm.Console.V8.Sample.csproj Passes --experimental-wasm-exnref via XHarness engine args for V8 sample runs.
src/mono/sample/wasm/console-node/Wasm.Console.Node.Sample.csproj Passes --experimental-wasm-exnref via XHarness engine args for Node sample runs.
src/mono/mono/mini/CMakeLists.txt Switches mono wasm EH library build to -sWASM_LEGACY_EXCEPTIONS=0.
src/mono/browser/runtime/types/internal.ts Renames loader/runtime helper fields to exceptionsFinal / featureWasmFinalEh.
src/mono/browser/runtime/startup.ts Uses exceptionsFinal feature detection; updates worker instantiate ordering.
src/mono/browser/runtime/loader/globals.ts Switches wasm-feature-detect import from exceptions to exceptionsFinal.
src/mono/browser/runtime/jiterpreter-support.ts Introduces tryTable/tag-index helpers and renames option to enableWasmFinalEh.
src/mono/browser/runtime/jiterpreter-opcodes.ts Replaces legacy EH opcodes with standardized throw_ref / try_table opcodes.
src/mono/browser/runtime/jiterpreter-jit-call.ts Updates jit-call wasm wrapper generation to try_table-based EH (standardized proposal).
src/mono/browser/runtime/CMakeLists.txt Adds --enable-reference-types to wasm-opt for Release post-build.
src/mono/browser/build/BrowserWasmApp.targets Switches to WASM_LEGACY_EXCEPTIONS=0; injects --experimental-wasm-exnref in generated V8 run script.
src/mono/browser/build/BrowserWasmApp.CoreCLR.targets Adds -sWASM_LEGACY_EXCEPTIONS=0 to CoreCLR browser-wasm relink flags.
src/mono/browser/browser.proj Switches mono browser runtime build flags to WASM_LEGACY_EXCEPTIONS=0.
eng/testing/WasmRunnerTemplate.sh Adds --experimental-wasm-exnref to default V8 engine args for wasm test runs.
eng/testing/WasmRunnerTemplate.cmd Adds --experimental-wasm-exnref to default V8 engine args for wasm test runs on Windows.
eng/testing/linker/trimmingTests.targets Adds SkipTrimmingTestsRun gate to allow publish-only trimming coverage.
eng/testing/BrowserVersions.props Bumps pinned V8 versions to 15.1.103.
eng/pipelines/runtime.yml Temporarily disables the WasmTestOnV8 scenario in a wasm CoreCLR smoke legs block.
eng/pipelines/runtime-llvm.yml Expands PR path filters to include assembly-load-context.*.
eng/pipelines/runtime-linker-tests.yml Passes SkipTrimmingTestsRun=true to avoid executing trimmed apps on V8 temporarily.
eng/pipelines/performance/runtime-wasm-perf.yml Disables PR trigger for wasm perf pipeline while V8 execution is blocked.
eng/pipelines/common/templates/wasm-runtime-tests.yml Sets sendToHelix: false to build but skip Helix execution for wasm runtime tests.
eng/pipelines/common/templates/runtimes/build-runtime-tests-and-send-to-helix.yml Adds sendToHelix parameter and conditional logic to skip Helix send/execution.
eng/pipelines/common/templates/pipeline-with-resources.yml Updates the pinned webassembly prereqs container digest(s).
eng/native/configureplatform.cmake Switches CoreCLR browser build to WASM_LEGACY_EXCEPTIONS=0 and links EH-specific libc++/unwind libs.

Comment thread src/mono/browser/runtime/jiterpreter-jit-call.ts
Comment thread eng/pipelines/performance/runtime-wasm-perf.yml Outdated
@pavelsavara

Copy link
Copy Markdown
Member Author

/azp run runtime-wasm

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

Comment thread eng/testing/WasmRunnerTemplate.sh
if(CMAKE_BUILD_TYPE STREQUAL "Release")
add_custom_command(TARGET dotnet.native
POST_BUILD COMMAND ${EMSDK_PATH}/bin/wasm-opt --enable-exception-handling --enable-multivalue --enable-simd --enable-bulk-memory --enable-nontrapping-float-to-int ${CONFIGURATION_WASM_OPT_FLAGS} --strip-dwarf ${NATIVE_BIN_DIR}/dotnet.native.wasm -o ${NATIVE_BIN_DIR}/dotnet.native.wasm
POST_BUILD COMMAND ${EMSDK_PATH}/bin/wasm-opt --enable-exception-handling --enable-reference-types --enable-multivalue --enable-simd --enable-bulk-memory --enable-nontrapping-float-to-int ${CONFIGURATION_WASM_OPT_FLAGS} --strip-dwarf ${NATIVE_BIN_DIR}/dotnet.native.wasm -o ${NATIVE_BIN_DIR}/dotnet.native.wasm

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what's the connection between --enable-reference-types and exception handling?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WebAssembly's exception handling final proposal uses an exnref value (a reference to an exception) to carry exception state

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

arch-wasm WebAssembly architecture area-Build-mono os-browser Browser variant of arch-wasm

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[browser] don't use legacy Wasm Exceptions

3 participants