Skip to content

[wasm] JIT should validate that modeled helper-call return arity matches the real helper signature #131379

Closed

Description

@lewing

Description

We have now hit the same bug three times, each found only by a runtime trap in a browser/WASI R2R run:

The root cause is structural. On wasm, CodeGen::genCallInstruction derives the emitted call_indirect / call signature from the JIT-modeled node type:

const var_types callRetType = call->IsFastTailCall() ? (var_types)call->gtReturnType : genActualType(call);
if (call->ShouldHaveRetBufArg() || (callRetType == TYP_VOID)) { typeStack.Push(CORINFO_WASM_TYPE_VOID); }

but nothing validates that the modeled type matches the helper's real signature. On register machines a "model a value-returning helper as void because the result is unused" shortcut is harmless, so these shortcuts are scattered through the JIT (importer.cpp, morph.cpp, objectalloc.cpp, ...) and are individually invisible until wasm traps at runtime — typically deep in a cold path, with a bare function signature mismatch and no attribution to the JIT site that caused it.

There is also no central table of helper return types in the JIT. HelperCallProperties (src/coreclr/jit/utils.cpp) tracks purity, allocation, no-GC, throw behavior — but not return arity. jithelpers.h knows the backing METHOD__* for DYNAMICJITHELPER entries, and corelib.h knows their signatures, but the JIT never cross-checks.

Proposal

Add a debug-only verification so these mismatches fail at JIT time with a clear message rather than as a wasm engine trap:

  1. In a Checked/Debug wasm JIT, when building the call signature in genCallInstruction (or earlier, in gtNewHelperCallNode and after any gtCallMethHnd retarget), resolve the helper's real signature via eeGetMethodSig(eeFindHelper(helper)) and assert that the modeled return arity (void vs. non-void) matches.
  2. Emit the helper name and the two conflicting types in the assert message so the failing site is immediately identifiable.

Optionally, a static table of expected return types per CorInfoHelpFunc (analogous to HelperCallProperties) would let this be checked on all targets and would make the intent explicit at each call site.

Given there is currently no wasm-R2R CI leg, an assert like this is the cheapest way to stop this class of bug from being found one production trap at a time.

Related: #129622, #130634, #130813, #131377, #131378

Note

This issue was created with assistance from GitHub Copilot (AI).

Activity

  1. added
    arch-wasmWebAssembly architecture
    area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI
    on Jul 26, 2026
  2. dotnet-policy-service commented on Jul 26, 2026

    @dotnet-policy-service
    Contributor

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

  3. dotnet-policy-service commented on Jul 26, 2026

    @dotnet-policy-service
    Contributor

    Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch
    See info in area-owners.md if you want to be subscribed.

  4. removed
    untriagedNew issue has not been triaged by the area owner
    on Jul 27, 2026
  5. added this to the 11.0.0 milestone on Jul 27, 2026
  6. JulieLeeMSFT commented on Jul 27, 2026

    @JulieLeeMSFT
    Member
  7. adamperlin commented on Jul 29, 2026

    @adamperlin
    Contributor

    I'm not sure if this is worth doing or not. Once we stand up R2R testing, I imagine we will hit nearly all of the remaining paths here and fix them, at which point bring-up will be mostly finished and we probably won't need these sorts of debug checks any more (since we likely won't be tweaking helper signatures all that much).

  8. JulieLeeMSFT commented on Jul 30, 2026

    @JulieLeeMSFT
    Member

    Closing as this is a temporary issue until we are done with implementation/integration.

  9. locked and limited conversation to collaborators on Aug 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Priority:3Work that is nice to havearch-wasmWebAssembly architecturearea-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions