Skip to content

[wasi] Add CoreCLR ReadyToRun library and runtime test CI - #134813

Open
lewing wants to merge 13 commits into
dotnet:mainfrom
lewing:lewing-wasi-r2r-test-standup
Open

lewing wants to merge 13 commits into
dotnet:mainfrom
lewing:lewing-wasi-r2r-test-standup

Conversation

@lewing

@lewing lewing commented Sep 28, 2026 •

Copy link
Copy Markdown
Member

Summary

Adds test coverage and CI for CoreCLR WASI composite ReadyToRun (R2R), now based directly on main after the publishing support merged in #133265. The CI lanes and the test guards they depend on stay together so the coverage is self-contained.

Changes

  • CI lanes:
    • A Checked WASI R2R_CG2 runtime-test job.
    • A LibraryTestsCoreCLR_WASI_R2R job that runs a trimmed composite R2R System.Collections.Tests smoke suite.
    • The existing interpreter jobs are unchanged.
  • Runtime-test harness:
    • Crossgen2 composite compilation of each merged runner.
    • A per-test composed host.
    • APP_ASSEMBLIES=EXTERNAL and TEST_READY_TO_RUN_MODE=1 passed to the guest.
    • Staging of the pinned Binaryen and wasm-tools archives into the Helix correlation payload.
  • Standalone corerun: strong definitions for the aligned R2R image buffer and its capacity, overriding the weak placeholders used by published apps.
  • Windows build hosts:
    • Acquire the Windows Binaryen and wasm-tools archives, including the Windows-specific archive format and executable names.
    • Verify the pinned x64 and arm64 archives with SHA-256 before extraction.
  • Library tests:
    • Test guards changed from IsBrowser to IsWasm where the tracking issue applies to all WebAssembly targets.
    • WASI R2R quarantines under [wasi] Stand up CoreCLR-WASI library tests #130129 where trimmed composite compilation exposes unsupported test assumptions.
    • Browser-only guards (fetch, DOM, VFS, globalization, crypto) are unchanged.

Validation

After rebasing onto main:

  • ./build.sh -s clr+libs+packs -os wasi -arch wasm -c Release: 0 warnings, 0 errors.
  • ./build.sh -s clr+libs+packs -os wasi -arch wasm -c Checked: 0 warnings, 0 errors.
  • Downloaded the exact pinned Binaryen and wasm-tools Windows x64/arm64 archives and verified their SHA-256 values.
  • git diff --check passed.

Functional validation completed before opening this PR:

  • Trimmed composite R2R System.Collections.Tests: 33,958/33,958 passed.
  • Merged JIT runtime-test wrapper: 186 tests passed.
  • The runtime log contained 162 Ready to Run initialized successfully entries, confirming R2R activation rather than interpreter fallback.
  • Helix tool staging passed.

Related: #130129.

Note

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

@azure-pipelines

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

@lewing lewing changed the title Lewing wasi r2r test standup [wasi] Add CoreCLR ReadyToRun library and runtime test CI Sep 28, 2026
@lewing
lewing marked this pull request as draft September 28, 2026 19:57
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

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

@lewing lewing added arch-wasm WebAssembly architecture os-wasi Related to WASI variant of arch-wasm labels Sep 28, 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 added a commit that referenced this pull request Sep 29, 2026
## Summary

Enable composite ReadyToRun (R2R) publishing for CoreCLR on WASI. This
builds on the self-installing WebCIL R2R images from #134312, which is
now in `main`.

Per review feedback, this PR covers publishing and composition only. The
WASI R2R runtime-test and trimmed library-test CI lanes, their test
harness plumbing, and the related library test quarantines are in
#134813, which is stacked on this PR.

## Implementation

- The WASI app builder compiles the app and framework closure into a
composite R2R image plus per-assembly forwarding stubs using Crossgen2.
The per-app WASI host (`wasihost`) reserves an image buffer and
function-table slice sized to that composite, and exports the symbols
the composite imports.
- A C# `ComposeWasiReadyToRun` WasmAppBuilder task composes the
self-installing composite into the linked host component. It reuses the
WebCIL reader infrastructure, and uses `wasm-tools` and Binaryen for the
post-link merge and global folding. Crossgen2's finished R2R Wasm is not
a relocatable `wasm-ld` input, so this step cannot move into the native
link. Before merging, the task checks the image buffer size and the
table reservation against the host's exported values.
- The `wasihost` external assembly probe serves the embedded composite
and the per-assembly WebCIL stubs that are extracted at build time.
- In-tree publishing acquires pinned `wasm-tools`/Binaryen versions into
the shared wasm tool cache (`eng/AcquireWasiR2RTools.targets`).
- Docs: `docs/workflow/building/coreclr/wasi-r2r.md` and a WASI host
composition section in `docs/design/mono/webcil.md`.

## Validation

- `./build.sh -s clr+libs+packs -os wasi -arch wasm -c Release`: 0
warnings, 0 errors.
- Clean `PublishTrimmed` + `PublishReadyToRun=true` publish of
`src/mono/sample/wasi/console` with an empty tool cache. The pinned
tools were acquired, composition succeeded, and the app ran under
wasmtime. `DOTNET_ReadyToRunLogFile` showed `Ready to Run initialized
successfully` for all six loaded assemblies (CoreLib, the app,
System.Runtime, System.Console, System.Threading,
System.Runtime.InteropServices).
- A non-R2R CoreCLR WASI publish of the same sample still links against
the weak placeholder buffer and runs.

Related: #130129. Follow-up: #134813.

> [!NOTE]
> This pull request description was prepared with assistance from GitHub
Copilot.

---------

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 919fdde7-f547-4bfb-86ad-7ac02c626980
@lewing
lewing marked this pull request as ready for review September 29, 2026 01:06
lewing and others added 2 commits September 28, 2026 20:18
Restore trimmed WASI CoreCLR library smoke and Checked runtime-test coverage, including standalone corerun composition and Helix tool staging.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…ion on Windows hosts

- eng/AcquireWasiR2RTools.targets: add a windows host mapping, use Binaryen's
  'arm64' (rather than 'aarch64') Windows/macOS archive naming, acquire
  wasm-tools' Windows .zip release instead of .tar.gz, and account for the
  '.exe' suffix on acquired tool executables.
- src/mono/wasi/build/WasiApp.CoreCLR.targets: pass the '.exe'-suffixed tool
  paths to ComposeWasiReadyToRun on Windows hosts.

Verified by acquiring and running wasm-tools.exe, wasm-merge.exe, and
wasm-opt.exe end-to-end on a Windows host.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Helix does not set __TestDotNetCmd, so the WASI R2R composer attempted to execute an empty command after Crossgen2 succeeded. Reuse the existing dotnet fallback selected for R2RDump when invoking the composer.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
lewing and others added 5 commits September 29, 2026 18:19
The WASI ReadyToRun runtime-test wrapper invokes the composer through dotnet msbuild. Provision the repo-pinned host SDK for this lane and propagate the CLI settings to scenario projects, preserving runtime-only payloads for non-R2R WASI jobs.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
- Restore IsBrowser on Mono-only (IsMonoAOT) ActiveIssues; Mono WASI lanes are not being stood up.
- Remove the umbrella dotnet#130129 quarantines so each failure class can be bucketed from fresh evidence.
- FileProviders: WASI forces polling like Browser/iOS/tvOS, so add TestPlatforms.Wasi to the existing watcher SkipOnPlatform attributes.
- Options: gate TestGeneratedRangeAttributeThreadSafety on IsMultithreadingSupported.
- MetadataLoadContext: apply the browser publish-dir and trimming-root settings to WASI too.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Mirror the browser CoreCLR layout: the interpreter lane in runtime.yml runs the full
suite, and a full trimmed ReadyToRun lane runs in runtime-extra-platforms and
runtime-wasm-libtests. For bring-up the runtime.yml R2R lane is temporarily a full run
too; restore smoke-only before merging.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
WASI CoreCLR stages System.Private.CoreLib.dll into managed/ from the runtime
pack rather than the publish directory, so the browser publish-dir items and
CoreLib trimming root break the WASI library test build.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The SDK's KnownFrameworkReference for Microsoft.NETCore.App does not list
wasi-wasm, so CoreCLR WASI apps resolved no runtime pack and the framework
was copied into the bundle after publish. ILLink then saw the framework only
as references, where no framework type is instantiated, and its unused type
check optimization folded checks such as 'isinst System.Type' and
'isinst Task' to null. That disabled ConditionalFact conditions and made
xunit treat async tests as synchronous, so their failures were reported as
passes.

Add wasi-wasm to the local KnownFrameworkReference so the runtime pack flows
through the publish list, and drop the post-publish framework copy.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
FileSystemWatcher is not supported on WASI, so add Wasi to the remaining
FileSystemWatcher SkipOnPlatform attributes.

Wildcard polling hashes with SHA256, which is not supported on WASI yet.
Quarantine the PollingWildCardChangeToken tests and the wildcard rows of the
polling watcher tests against dotnet#99126,
splitting the UsePollingFileWatcher theories so the non-wildcard rows keep
running.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
lewing and others added 4 commits September 30, 2026 00:02
Core_Root copied WasmAppBuilder from WasmAppBuilder/$(HostConfiguration),
but tasks build with TasksConfiguration, so Checked test lanes found nothing
there and every Helix work item failed to load ComposeWasiReadyToRun. Use
WasmAppBuilderDir like the browser staging does, and fail the build when the
task assembly is missing.

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

The test deploys an assembly under another file name, which the per-app
call-helper generator rejects. Tracked by
dotnet#134915.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
crossgen2 lowers ClassWithManyConstructorParameters' constructor to a wasm
function type with more than 1000 parameters, which every engine rejects, so
the System.Text.Json.Tests ReadyToRun composite fails to build. Define
WASM_READYTORUN for wasm CoreCLR ReadyToRun test builds and exclude the type
and its test there until
dotnet#132855 is fixed.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
System.Text.Json seeds Marvin with RandomNumberGenerator, which throws on WASI
because System.Security.Cryptography has no WASI implementation. Quarantine
the duplicate property and structural classifier tests that reach it against
dotnet#99126.

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

This branch has not been deployed

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

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant