Skip to content

[Wasm R2R]: crossgen seems to be missing some thunk signatures #129622

Description

@AndyAyersMS

Summary

Several JIT regression tests crash when run with wasm R2R enabled, but pass when R2R is excluded for the affected assembly via DOTNET_ReadyToRunExcludeList.

The common root cause is that crossgen2 does not emit a WasmR2RToInterpreterThunk (or corresponding WasmDelayLoadHelper) export for every call_indirect signature the R2R'd code uses. At runtime, when the call site dispatches to a method whose actual function has a different declared wasm (type N) than the one declared at the call_indirect, the wasm engine traps with a signature mismatch.

Related: #129337 covers the conv.ovf.i subset of this same family. This issue broadens the scope to MD-array virtual dispatch and ldvirtftn-resolved indirect calls.

Affected tests (in the Pri-0 browser wasm Debug R2R sweep)

Test Wrapper Missing WasmR2RToInterpreterThunk signature Triggering helper/call
address_d.dll (address.il) Methodical_d1 (i32 i32 i32 i32) → i32 (iiTip) MD-array int[10000...10005]::Address(int32) virtual dispatch
address_r.dll Methodical_r1 same same
b14068.il Regression_7 (i32 f64 i32) → i32 CORINFO_HELP_DBL2INT_OVF (conv.ovf.u2 on double)
b28598.il Regression_6 (i32 f64 i32) → i64 CORINFO_HELP_DBL2LNG_OVF (conv.ovf.i8 on float)
DevDiv_406156.il Regression_3 (i32 f64 i32) → i64 similar conv.ovf double helpers
Runtime_45250.il Regression_2 (i32 i32 i32 i32 i32) → i32 (iTiip) CORINFO_HELP_VIRTUAL_FUNC_PTR (ldvirtftn)

In each case, the R2R'd test wasm emits call_indirect (type N) where N is a wasm type that has no matching WasmR2RToInterpreterThunk(...) export in the same wasm module (and System.Private.CoreLib.NotReadyYet.wasm indicates CoreLib R2R is not yet usable, so the calls must dispatch through interp thunks).

Repro (any of the above tests)

# From a wasm browser Debug build with crossgen2-compiled tests:
$cr  = 'C:\repos\runtime6\artifacts\tests\coreclr\browser.wasm.Debug\Tests\Core_Root'
$crU = '/repos/runtime6/artifacts/tests/coreclr/browser.wasm.Debug/Tests/Core_Root'
$dll = '/repos/runtime6/artifacts/tests/coreclr/browser.wasm.Debug/JIT/Regression/Regression_7/b14068.dll'

# R2R: fails silently with exit 1, no stdout/stderr
node --stack-size=8192 "$cr\corerun.js" -c "$crU" "$dll"
# echo $LASTEXITCODE   → 1

# Workaround: skip R2R for this assembly
$env:DOTNET_ReadyToRunExcludeList = 'b14068'
node --stack-size=8192 "$cr\corerun.js" -c "$crU" "$dll"
# echo $LASTEXITCODE   → 100
Remove-Item Env:DOTNET_ReadyToRunExcludeList

To verify the thunk gap, disassemble the test's .wasm with wasm2wat --enable-exceptions and list its (export "WasmR2RToInterpreterThunk(...)") exports — none will declare the type required by the failing call_indirect.

Impact

This is the single largest remaining root cause of pri-0 wasm R2R sweep failures after recent EH fixes (PR #129555). Multiple JIT tests across Methodical_*, Regression_*, Directed_* wrappers crash silently with the same pattern.

Note

This issue was authored with assistance from GitHub Copilot.

Metadata

Metadata

Assignees

Labels

arch-wasmWebAssembly architecturearea-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions