Skip to content

[Wasm RyuJIT] Call signatures#125153

Draft
kg wants to merge 4 commits intodotnet:mainfrom
kg:wasm-callsigs-1
Draft

[Wasm RyuJIT] Call signatures#125153
kg wants to merge 4 commits intodotnet:mainfrom
kg:wasm-callsigs-1

Conversation

@kg
Copy link
Member

@kg kg commented Mar 3, 2026

No description provided.

Copilot AI review requested due to automatic review settings March 3, 2026 23:12
@kg kg added arch-wasm WebAssembly architecture area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI labels Mar 3, 2026
@dotnet-policy-service
Copy link
Contributor

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

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the WASM RyuJIT emitter to provide real call-indirect signatures by deriving argument lowering from method handles and by hard-coding signatures for certain runtime helpers, then passing those signatures to the JIT↔EE getWasmTypeSymbol API.

Changes:

  • Build a CorInfoWasmType signature array for emitIns_Call when params.methHnd is available.
  • Special-case a set of helper calls (detected via eeGetHelperNum) with hard-coded signatures.
  • Use the computed signature to obtain a CORINFO_WASM_TYPE_SYMBOL_HANDLE for call_indirect.

Copilot AI review requested due to automatic review settings March 4, 2026 22:12
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 5 comments.

Comment on lines +2266 to +2267
CorInfoWasmType *types = nullptr;
size_t typeCount = 0;
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

types and typeCount are initialized to nullptr and 0, but if the switch falls through to the default case with NYI_WASM (which may not abort in all build configurations), getWasmTypeSymbol at line 2304 would be called with a null pointer and zero count. However, a more immediate concern is that in non-debug/non-fatal NYI_WASM configurations, the unreached() after the NYI_WASM may also be compiled out, leading to undefined behavior. Consider initializing types and typeCount to safe defaults or restructuring so that the default case cannot fall through to the getWasmTypeSymbol call.

Copilot uses AI. Check for mistakes.
Comment on lines +2269 to +2276
#define _SIG(helper_id, ...) \
case helper_id: \
{ \
static CorInfoWasmType helper_id ## _types[] = {__VA_ARGS__}; \
types = helper_id ## _types; \
typeCount = sizeof(helper_id ## _types) / sizeof(CorInfoWasmType); \
break; \
}
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The _SIG macro with token pasting creates static local arrays inside case blocks. While functional, this macro is fragile (e.g., it won't compose well if a helper ID contains special characters) and uses sizeof/sizeof instead of a safer ArrLen or std::size pattern that's used elsewhere in the codebase (see ArrLen(typecode_mapping) in emitwasm.cpp). Consider using ArrLen for consistency, or refactoring to a data-driven table lookup instead of a macro-based switch.

Copilot uses AI. Check for mistakes.
_SIG(CORINFO_HELP_BULK_WRITEBARRIER, CORINFO_WASM_TYPE_VOID /* retval */, CORINFO_WASM_TYPE_I32, CORINFO_WASM_TYPE_I32, CORINFO_WASM_TYPE_I32);

default:
printf("Helper %d (%s) has no hard-coded signature\n", helper, GetCompiler()->eeGetMethodFullName(params.methHnd));
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using raw printf for diagnostic output is inconsistent with the rest of the JIT, which typically uses JITDUMP or other compiler-provided logging macros that respect debug/verbosity settings. This printf will unconditionally write to stdout in release builds. Consider replacing it with JITDUMP or wrapping it in a #ifdef DEBUG guard.

Suggested change
printf("Helper %d (%s) has no hard-coded signature\n", helper, GetCompiler()->eeGetMethodFullName(params.methHnd));
JITDUMP("Helper %d (%s) has no hard-coded signature\n", helper, GetCompiler()->eeGetMethodFullName(params.methHnd));

Copilot uses AI. Check for mistakes.
Comment on lines +2152 to +2159
if (wvt >= WasmValueType::Count)
{
NYI_WASM("Unrecognized register type in genCallInstruction");
}
else
{
typeStack.Push((CorInfoWasmType)emitter::GetWasmValueTypeCode(wvt));
}
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When wvt >= WasmValueType::Count, the code hits NYI_WASM but then continues execution (skipping the Push), producing a signature with a missing argument type. This will result in a mismatched call signature at the Wasm level. If NYI_WASM is not fatal, the generated signature will be silently incorrect. Consider either making this unconditionally fatal or pushing a placeholder type to maintain signature arity.

Copilot uses AI. Check for mistakes.
Comment on lines +6382 to 6385
#if !TARGET_WASM
if (!hasIndirectionCell)
{
// Non-virtual direct calls to addresses accessed by
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The #if !TARGET_WASM guard only wraps part of the logic within this case. If hasIndirectionCell is false on Wasm, result may be left uninitialized or in an unexpected state since the indirection load is skipped. Consider verifying that the fallthrough path correctly handles the Wasm case, or adding a comment explaining why skipping this block is safe.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

arch-wasm WebAssembly architecture area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants