Skip to content

[wasm] Support browser-wasm/wasi-wasm ReadyToRun in ResolveReadyToRunCompilers - #55785

Open
pavelsavara wants to merge 3 commits into
dotnet:mainfrom
pavelsavara:wasm-r2r-crossgen-resolve
Open

[wasm] Support browser-wasm/wasi-wasm ReadyToRun in ResolveReadyToRunCompilers#55785
pavelsavara wants to merge 3 commits into
dotnet:mainfrom
pavelsavara:wasm-r2r-crossgen-resolve

Conversation

@pavelsavara

@pavelsavara pavelsavara commented Aug 14, 2026

Copy link
Copy Markdown
Member

Summary

crossgen2 can already target WebAssembly (--obj-format:wasm), but the SDK's ResolveReadyToRunCompilers task rejected browser-wasm / wasi-wasm target RIDs, so PublishReadyToRun failed with ReadyToRunTargetNotSupportedError before crossgen2 was ever invoked.

Two gaps in the task:

  • ExtractTargetPlatformAndArchitecture had no wasm architecture case → returned false.
  • GetCrossgen2TargetOS did not include browser / wasi in the runtime-graph match list or the OS switch → returned null.

Related dotnet/runtime#132339

Change

  • Add case "wasm" → Architecture.Wasm (guarded by #if !NETFRAMEWORK, since Architecture.Wasm is .NET 5+, matching the existing RiscV64/LoongArch64 handling).
  • Add Architecture.Wasm => "wasm" in ArchitectureToString.
  • Add browser and wasi to the GetCrossgen2TargetOS candidate list and switch.
  • Gate WebAssembly R2R on the .NET 11+ crossgen2 pack (crossgen2PackVersion.Major >= 11): the wasm cross-JIT ships only in the .NET 11+ crossgen2 pack, so for older packs browser/wasi targets fall back to the existing ReadyToRunTargetNotSupportedError rather than resolving and then failing to load the JIT.

No JitPath plumbing is needed: for crossgen2 v6+ the task sets no jit path, and crossgen2 auto-loads the wasm cross-JIT (clrjit_universal_wasm_<hostArch>) from its own tools/ directory.

Merge ordering

This can merge independently of the dotnet/runtime side. The change is inert for every existing scenario:

  • Non-wasm targets are unaffected (the previously-default → false cases now match, but only for wasm/browser/wasi).
  • For wasm targets it only advertises support when a .NET 11+ crossgen2 pack is resolved, and the actual wasm cross-JIT + the targets that turn PublishReadyToRun on live in dotnet/runtime. Until those ship, nothing in the shipped SDK reaches this path by default (browser/wasi CoreCLR R2R is experimental and not enabled by default).

Context

Unblocks ReadyToRun for the experimental CoreCLR-on-WebAssembly target. The consuming runtime-pack / SDK targets work (per-assembly R2R webcil-in-wasm) lives in dotnet/runtime and is validated end-to-end there. The runtime repo currently masks this task gap with an in-tree ResolveReadyToRunCompilers target override that is not shipped; this PR removes the need for that override in the shipped SDK.

Validation

Verified in dotnet/runtime by forcing the SDK-native task path (bypassing the in-tree override): the task resolves arch = Wasm, os = browser, and — given the standard crossgen2 pack tools/ layout — locates crossgen2, runs it, and the published assemblies are byte-identical to the crossgen R2R output. Compiles clean; no new strings/localization.

Note

This PR description and change were drafted with GitHub Copilot.

…Compilers

crossgen2 can target WebAssembly (--obj-format:wasm), but ResolveReadyToRunCompilers rejected browser-wasm/wasi-wasm target RIDs: ExtractTargetPlatformAndArchitecture had no 'wasm' architecture case and GetCrossgen2TargetOS did not map the 'browser'/'wasi' OS, so PublishReadyToRun failed with ReadyToRunTargetNotSupportedError.

Add the wasm architecture and browser/wasi target OS. The wasm cross-JIT (clrjit_universal_wasm_<host>) is auto-loaded by crossgen2 from its tools/ dir, so no JitPath change is needed for crossgen2 v6+.
@pavelsavara pavelsavara self-assigned this Aug 14, 2026
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).
2 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

The wasm cross-JIT ships only in the .NET 11+ crossgen2 pack, so older packs would resolve as supported and then fail to load the JIT. Require crossgen2 pack major >= 11 for browser/wasi targets.
The wasm container format wraps a per-assembly ECMA manifest, so it does not require composite compilation. Forcing --composite for any non-PE container produced a composite-of-one image whose only metadata was the R2R manifest (no assembly manifest), causing CoreCLR-on-wasm to fail loading with COR_E_BADIMAGEFORMAT (module expected to contain an assembly manifest).

Assisted-by: GitHub Copilot
@pavelsavara
pavelsavara marked this pull request as ready for review August 14, 2026 19:26
@pavelsavara
pavelsavara requested a review from a team as a code owner August 14, 2026 19:26
Copilot AI lite review requested due to automatic review settings August 14, 2026 19:26
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).
2 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

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 enables PublishReadyToRun for WebAssembly RIDs (browser-wasm / wasi-wasm) by teaching the SDK’s ReadyToRun tool resolution logic to recognize the wasm architecture and map browser/wasi as valid crossgen2 target OS values. It also adjusts crossgen2 argument generation so the wasm container format doesn’t incorrectly force composite compilation, and gates wasm R2R support to .NET 11+ crossgen2 packs (where the wasm cross-JIT is available).

Changes:

  • Extend RID parsing and architecture string mapping to support wasm (Architecture.Wasm) in ResolveReadyToRunCompilers.
  • Recognize browser and wasi as valid --targetos values and gate wasm R2R to crossgen2 pack version 11+.
  • Avoid forcing --composite purely due to --obj-format:wasm in RunReadyToRunCompiler.

Reviewed changes

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

File Description
src/Tasks/Microsoft.NET.Build.Tasks/RunReadyToRunCompiler.cs Prevents --obj-format:wasm from implicitly forcing --composite during response-file generation.
src/Tasks/Microsoft.NET.Build.Tasks/ResolveReadyToRunCompilers.cs Adds wasm RID support (arch + OS mapping) and gates wasm R2R to .NET 11+ crossgen2 packs.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants