[wasm] Fail hard when the engine rejects a Webcil R2R image - #132870
Merged
Conversation
When a per-assembly R2R .wasm sibling exists but fails to parse as a WebAssembly module (e.g. a function type exceeding the wasm parameter limit), the runtime silently treated this the same as "no R2R image for this assembly" and fell back to fully interpreting the assembly. The only trace was an unrelated-looking "Ready to Run header not found" log line, so a broken R2R image could go completely unnoticed. Since the file exists, this is not the legitimate fallback case - throw instead of returning false so the failure is loud. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7f88abc1-143e-4858-b69f-ce01228a87ad
|
Azure Pipelines: Successfully started running 3 pipeline(s). 13 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
marked this pull request as ready for review
August 28, 2026 01:33
|
Azure Pipelines: Successfully started running 3 pipeline(s). 13 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
Contributor
|
Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara |
The module is well-formed wasm; it's rejected because it exceeds an implementation-defined limit (e.g. the wasm parameter count), not because it's malformed. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7f88abc1-143e-4858-b69f-ce01228a87ad
Contributor
There was a problem hiding this comment.
Pull request overview
This PR changes the CoreCLR-on-wasm corerun host’s Webcil (per-assembly R2R) probe so that a present-but-unloadable sibling .wasm image no longer looks identical to the “no R2R image exists” case, by throwing on WebAssembly.Module(...) construction failure instead of returning false.
Changes:
- Treat
WebAssembly.Module(wasmBytes)failures as fatal by throwing, rather than silently falling back viareturn false. - Update the logged message to reflect that the
.wasmmodule is invalid for a Webcil image.
Contributor
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.
Suppressed comments (1)
src/coreclr/hosts/corerun/wasm/libCorerun.js:200
- The new throw replaces the original exception with a new Error, which drops the original error object/stack. Preserving the original exception as an error cause makes this much easier to diagnose (especially for engine-specific rejection messages).
} catch (e) {
const errorMessage = e instanceof Error ? e.message : String(e);
console.error("Failed to construct WebAssembly module for Webcil image:", { wasmPath, errorMessage });
throw new Error(`Failed to construct WebAssembly module for Webcil image '${wasmPath}': ${errorMessage}`);
}
pavelsavara
approved these changes
Aug 28, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Related to #132865 / #132855.
CoreCLR-on-wasm loads a per-assembly R2R image as a
.wasmfile sitting beside the assembly's.dll(src/coreclr/hosts/corerun/wasm/libCorerun.js,BrowserHost_ExternalAssemblyProbe). If that.wasmfile exists butnew WebAssembly.Module(...)throws - for example because crossgen2 emitted a function type exceeding the wasm engine's parameter-count limit (#132855) - the probe caught the exception and returnedfalse, which is exactly what happens when there's simply no R2R image for that assembly at all.(Note: the emitted wasm is well-formed; it's rejected because it exceeds an implementation-defined engine limit, not because it's malformed.)
The result: the runtime silently falls back to fully interpreting the whole assembly. The app still runs and tests still pass, with the only trace being a generic
Ready to Run header not found: "<assembly>"log line - indistinguishable from the normal "never R2R compiled" case. A rejected R2R image can regress to full interpretation with zero visible signal.Fix
Distinguish the two cases:
.wasmsibling doesn't exist -> legitimate, silent fallback (unchanged)..wasmsibling exists but the engine rejects it duringWebAssembly.Moduleconstruction -> this is not a normal fallback path, so it now throws instead of being swallowed.Verification
Reproduced against an unfixed (pre-#132865) crossgen2 targeting browser-wasm, compiling
System.Text.Json.Tests(which contains the 1003-paramClassWithManyConstructorParameterstype from #132855) and running it under a rebuiltcorerun.js/corerun.wasm:Before this change:
...followed by
Tests run: 346 Passed: 345 Failed: 1- the whole assembly silently ran fully interpreted.After this change:
process exits 1, no tests run at all - the rejection is immediately visible instead of silently degrading.
Note
This PR description and commit were drafted with GitHub Copilot assistance.