Skip to content

[wasi] Use the <entry>.r2r.wasm composite owner name on WASI - #134874

Merged
lewing merged 1 commit into
mainfrom
lewing-wasi-composite-owner-naming
Oct 1, 2026
Merged

lewing merged 1 commit into
mainfrom
lewing-wasi-composite-owner-naming

Conversation

@lewing

@lewing lewing commented Sep 29, 2026

Copy link
Copy Markdown
Member

Why

CoreCLR WASI composite ReadyToRun currently names the composite owner image composite-r2r.wasm. PrepareForReadyToRunCompilation in Crossgen2Tasks forces that name whenever Crossgen2Tool TargetOS is wasi. The browser composite work in #134618 uses the task's default name instead: <entry>.r2r.wasm, the main assembly name with .r2r.wasm.

This PR drops the TargetOS special case so WASI gets the same owner name as browser. It lands ahead of the dotnet/sdk#56395 port, so that PR doesn't carry the WASI rule into the SDK.

The two delivery models stay different on purpose. Browser instantiates the composite at runtime through the JS loader. WASI composes it offline into the host with wasm-merge/wasm-opt. Only the naming contract changes.

Design

The composite's own file name, as written by crossgen2, is the single authority. It is also the owner name every component stub records.

  • PrepareForReadyToRunCompilation: the wasi branch is removed. A wasm composite owner is now <entry>.r2r.wasm on both targets.
  • WasiApp.CoreCLR.targets: the composite path now comes from the planned composite compilation, @(_ReadyToRunCompileList) with CreateCompositeImage=true, via %(OutputR2RImage). The build errors unless there is exactly one composite compilation. Because the path isn't hardcoded, WASI keeps working with either SDK naming.
  • wasi_r2r_probe.hpp: the host reserves a 256-byte composite name buffer, zero-initialized, and exports its address and capacity (wasi_r2r_composite_name_base, wasi_r2r_composite_name_cap). The probe serves the composite only when the requested name matches the recorded name, and only if that name is non-empty. An uncomposed host therefore serves no composite. There is no wildcard matching and no name compiled into C++.
  • ComposeWasiReadyToRun: the composer reads the two new exports and checks that the name is non-empty, contains no NUL, and fits the buffer. Its shim now imports webcil.memory and includes an active data segment that writes Path.GetFileName(CompositePath), NUL-terminated, into the host buffer. This is the same mechanism that already installs the payload. A prebuilt host, such as the runtime-test corerun, can therefore be composed with a composite of any name.
  • Docs: updated the WASI host composition section of docs/design/mono/webcil.md and docs/workflow/building/coreclr/wasi-r2r.md.

Validation

  • ./build.sh clr+libs+host+packs -os wasi -arch wasm -c Release finished with 0 warnings and 0 errors.
  • ./dotnet.sh publish src/mono/sample/wasi/console/Wasi.Console.Sample.csproj -c Release -p:TargetOS=wasi -p:TargetArchitecture=wasm -p:RuntimeFlavor=CoreCLR -p:PublishReadyToRun=true succeeded. The composer logged composite='Wasi.Console.Sample.r2r.wasm'.
  • The published app ran under wasmtime with DOTNET_ReadyToRunLogFile set. It exited 0, and the log shows Ready to Run initialized successfully for System.Private.CoreLib, Wasi.Console.Sample, System.Runtime, System.Console, System.Threading and System.Runtime.InteropServices.
  • Negative check: I composed the same host with a copy of the composite renamed to Wrong.r2r.wasm. Startup then traps in EEStartup because CoreLib's owner composite isn't served. A name mismatch fails loudly rather than silently interpreting.
  • Non-R2R publish of the same sample: the app runs on the interpreter, and the log shows Ready to Run header not found.
  • Not run: browser ReadyToRunTests. The removed code only executed when TargetOS was wasi, and the browser naming path is unchanged.

Interaction with #134813

This PR merges cleanly with #134813's head (checked with git merge-tree); it doesn't depend on #134813. The runtime-test harness in #134813 passes the same composite-r2r.wasm path to both crossgen2 and WasiR2RComposer.proj. The composer records that name in the shared corerun, so the harness needs no changes. I did not build or run the runtime tests with both PRs merged.

Follow-up in dotnet/sdk#56395

  • Remove the wasi TargetOS block from CreateReadyToRunFileToPublish.
  • Change It_uses_the_fixed_wasm_path_for_a_wasi_composite_owner to expect <entry>.r2r.wasm, the same as browser.

Note

This pull request description was generated with assistance from GitHub Copilot.

Drop the WASI TargetOS special case in PrepareForReadyToRunCompilation so
WASI composite publishing gets the same <entry>.r2r.wasm owner name the
ReadyToRun tasks give browser.

The composite's own file name (the owner every component stub records) is
now the single authority. The WASI targets take the composite path from the
planned composite compilation instead of assuming a name, and the composer
writes that file name into a host-owned buffer through an active data
segment in its shim. The probe answers only to the recorded name, so an
uncomposed host serves no composite and a prebuilt host (such as the
runtime-test corerun) can be composed with a composite of any name.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@azure-pipelines

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

@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @dotnet/crossgen-contrib
See info in area-owners.md if you want to be subscribed.

@lewing

lewing commented Sep 29, 2026

Copy link
Copy Markdown
Member Author

@maraf ptal

@lewing lewing added arch-wasm WebAssembly architecture os-wasi Related to WASI variant of arch-wasm labels Sep 29, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara
See info in area-owners.md if you want to be subscribed.

@lewing
lewing requested a review from pavelsavara September 29, 2026 19:16
@lewing
lewing marked this pull request as draft September 29, 2026 19:17
@lewing
lewing marked this pull request as ready for review September 29, 2026 19:18
@lewing

lewing commented Sep 29, 2026

Copy link
Copy Markdown
Member Author

This is very much open to discussion, I was just looking at doing less special casing in the targets

@maraf

maraf commented Sep 29, 2026

Copy link
Copy Markdown
Member

I'm in favor of naming the binary after the project/application

@lewing
lewing merged commit df0ac02 into main Oct 1, 2026
184 of 186 checks passed
@lewing
lewing deleted the lewing-wasi-composite-owner-naming branch October 1, 2026 13:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

arch-wasm WebAssembly architecture area-ReadyToRun os-wasi Related to WASI variant of arch-wasm

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants