Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
fee66de
Add READYTORUN_FIXUP_InjectStringThunks (0x39) for string-to-code thu…
davidwrighton Apr 23, 2026
8816791
Make InjectStringThunks import demand-driven via stub dependencies
davidwrighton Apr 23, 2026
549b981
Return signature string from WasmLowering.GetSignature
davidwrighton Apr 23, 2026
3ff2ebe
Replace GetSignature tuple with WasmSignature struct
davidwrighton Apr 23, 2026
1c79aab
Refactor WasmSignature, WasmImportThunk, and RaiseSignature
davidwrighton Apr 24, 2026
b6ada10
WasmImportThunk: iterate raised MethodSignature for arg handling
davidwrighton Apr 24, 2026
2692726
Flow through the jit call site recording into the existing recordCall…
davidwrighton Apr 24, 2026
7f6ef83
Encode 'this' parameter as 'T' in WasmSignature strings
davidwrighton Apr 24, 2026
1ced59b
Add WasmR2RToInterpreterThunkNode and WASM memory instructions
davidwrighton Apr 24, 2026
48562c3
Add WasmInterpreterToR2RThunkNode, fix retbuf handling, wire up R2R c…
davidwrighton Apr 24, 2026
71d86f0
Use _additionalDependencies for thunk wiring in CorInfoImpl
davidwrighton Apr 24, 2026
b1cc073
Fix the build.
davidwrighton Apr 24, 2026
a4aa03a
Tweak around callsite recording issues
davidwrighton Apr 24, 2026
895a6f6
Fix multiple crossgen2 WASM thunk generation bugs
davidwrighton Apr 27, 2026
032dcd9
Fix Wasm ArgIterator SizeOfArgStack for methods with only unnamed args
davidwrighton Apr 27, 2026
2db92ed
Align SignatureMapper with WasmLowering S<N> struct encoding
davidwrighton Apr 27, 2026
3e424ff
Fix struct size in thunk names and slot indexing, remove blittable gate
davidwrighton Apr 27, 2026
3573b5d
Align signature encoding across crossgen2, SignatureMapper, and runtime
davidwrighton Apr 27, 2026
e5479d6
Fix handling of This parameters in SignatureMapper
davidwrighton Apr 27, 2026
2b240a0
Use fixed stack buffer with alloca fallback for signature key computa…
davidwrighton Apr 27, 2026
01cb40e
Add R2R pregenerated thunk fallback to LookupThunk and LookupPortable…
davidwrighton Apr 27, 2026
fd87e4c
Deferred R2R thunk resolution for PortableEntryPoints
davidwrighton Apr 27, 2026
3caf6dc
Fix size calculation in SignatureMapper
davidwrighton Apr 28, 2026
49fc698
Merge branch 'main' of https://github.com/dotnet/runtime into R2RThun…
davidwrighton Apr 28, 2026
b1065f3
Fix issue where function pointer we're using needs to be offset by Ta…
davidwrighton Apr 28, 2026
3046e4f
Prevent duplicate pending thunk entries for reused DynamicMethodDescs
davidwrighton Apr 28, 2026
f7a9600
Guard pregenerated thunks infrastructure with TARGET_WASM
davidwrighton Apr 28, 2026
ce2f3f0
Fail build on unknown multi-field structs in SignatureMapper
davidwrighton Apr 28, 2026
601ed47
Apply formatting patch
davidwrighton Apr 28, 2026
d60c5a3
Merge branch 'main' of https://github.com/dotnet/runtime into R2RThun…
davidwrighton Apr 30, 2026
165325c
- Correct the implementation of LowerTypeHandle
davidwrighton May 1, 2026
81c32b1
- Fix WasmLowering to properly handle an unmanaged callers only
davidwrighton May 1, 2026
fafce52
Add R2R helper for dispatch to interpreter for portable entrypoints
davidwrighton May 1, 2026
7675879
Fix codegen for R2RToInterpreterThunk
davidwrighton May 2, 2026
763c406
Tweak handling for when EnsurePortableEntryPointIsCallableFromR2R so …
davidwrighton May 4, 2026
d5969b2
- Update arg iterator usage in thunks for ByRef parameters
davidwrighton May 4, 2026
815b107
Feedback
davidwrighton May 4, 2026
e691577
Merge branch 'main' of https://github.com/dotnet/runtime into R2RThun…
davidwrighton May 5, 2026
c233d72
Follow up on re-running the tooling
davidwrighton May 5, 2026
e43ee36
Adjust thunk abi
davidwrighton May 5, 2026
d9090d8
Add support for compiling R2R files as part of testing Wasm
davidwrighton May 5, 2026
102d90f
Add Webcil support to R2RDump
davidwrighton May 5, 2026
bde557b
Add GetSectionData to IAssemblyMetadata and implement in all types
davidwrighton May 5, 2026
43dca47
Add WASM bytecode disassembler for R2RDump
davidwrighton May 5, 2026
19586b8
Fix GC collection of pinned metadata array in WebcilAssemblyMetadata
davidwrighton May 5, 2026
54a66dd
Use .wasm file extension for WASM R2R output in test scripts
davidwrighton May 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 32 additions & 2 deletions docs/design/coreclr/botr/clr-abi.md
Original file line number Diff line number Diff line change
Expand Up @@ -714,12 +714,42 @@ The linear stack pointer `$sp` is the first argument to all methods. At a native

A frame pointer, if used, points at the bottom of the "fixed" portion of the stack to facilitate use of Wasm addressing modes, which only allow positive offsets.

Structs are generally passed by-reference, unless they happen to exactly contain a single primitive field (or be a struct exactly containing such a struct). The linear stack provides the backing storage for the by-reference structs.
Arguments and return values are processed via the Type Lowering algorithm below.

Structs are generally returned via hidden buffers, whose address is supplied by the caller and passed just after the managed `this`, or after `$sp` argument when `this` is not present. In such cases the return value of the method is the address of the return value. But if the struct can be passed on the Wasm stack it is returned on the Wasm stack.
If a struct is returned via a hidden buffer, the address is supplied by the caller and passed just after the managed `this`, or after `$sp` argument when `this` is not present. In such cases the return value of the method is the address of the return value. But if the struct can be passed on the Wasm stack it is returned on the Wasm stack per the Type Lowering rules.

(TBD: ABI for vector types)

### Type Lowering

Managed types are lowered to WebAssembly value types according to the following rules
(implemented in `WasmLowering.LowerToAbiType` and `WasmLowering.LowerType`):

| Managed type | Wasm value type |
|---|---|
| `bool`, `char`, `sbyte`, `byte`, `short`, `ushort`, `int`, `uint` | `i32` |
| `long`, `ulong` | `i64` |
| `float` | `f32` |
| `double` | `f64` |
| `nint`, `nuint`, pointer, byref, function pointer | `i32` (pointer-sized) |
| Reference types (class, string, array, szarray, interface) | `i32` (pointer-sized) |
| Value type (struct) — single primitive field, no padding | Unwrap recursively to the field's wasm type |
| Value type (struct) — single field with padding, or multiple fields | Passed by reference (`i32` pointer) |
| Empty struct (zero instance fields) | Elided from the signature entirely |

**Struct unwrapping** is recursive: a struct containing a single struct field, where the inner struct
has the same size as the outer, is unwrapped until a primitive is reached or the rule no longer applies.
For example, a struct `Wrapper { Inner value; }` where `Inner { int x; }` is unwrapped all the way
to `i32`.

A struct is **not** unwrapped when:
- It has more than one instance field.
- It has exactly one instance field but the field's size differs from the struct's size (i.e., the
struct has padding due to explicit layout or alignment attributes).

Structs that cannot be unwrapped are passed by reference. The caller allocates space on the linear
stack and passes a pointer. For return values, the caller provides a hidden return buffer pointer.

### Prolog

The prolog will decrement the stack pointer by the fixed frame size, home any arguments that are stored on the linear stack, and zero initialize slots on the linear stack as appropriate. It will establish a frame pointer if one is needed.
Expand Down
106 changes: 106 additions & 0 deletions docs/design/coreclr/botr/readytorun-format.md
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,7 @@ fixup kind, the rest of the signature varies based on the fixup kind.
| READYTORUN_FIXUP_Verify_IL_Body | 0x36 | Verify an IL body is defined the same at compile time and runtime. A failed match will cause a hard runtime failure. See[IL Body signatures](il-body-signatures) for details.
| READYTORUN_FIXUP_ContinuationLayout | 0x37 | Layout of an async method continuation type, followed by typespec signature
| READYTORUN_FIXUP_ResumptionStubEntryPoint | 0x38 | Entry point of an async method resumption stub
| READYTORUN_FIXUP_InjectStringThunks | 0x39 | Inject pregenerated string-to-code thunk mappings. See [InjectStringThunks signatures](#injectstringthunks-signatures) for details.
| READYTORUN_FIXUP_ModuleOverride | 0x80 | When or-ed to the fixup ID, the fixup byte in the signature is followed by an encoded uint with assemblyref index, either within the MSIL metadata of the master context module for the signature or within the manifest metadata R2R header table (used in cases inlining brings in references to assemblies not seen in the input MSIL).

#### Method Signatures
Expand Down Expand Up @@ -333,6 +334,21 @@ ECMA 335 does not have a natural encoding for describing an overridden method. T

ECMA 335 does not define a format that can represent the exact implementation of a method by itself. This signature holds all of the IL of the method, the EH table, the locals table, and each token (other than type references) in those tables is replaced with an index into a local stream of signatures. Those signatures are simply verbatim copies of the needed metadata to describe MemberRefs, TypeSpecs, MethodSpecs, StandaloneSignatures and strings. All of that is bundled into a large byte array. In addition, a series of TypeSignatures follows which allow the type references to be resolved, as well as a methodreference to the uninstantiated method. Assuming all of this matches with the data that is present at runtime, the fixup is considered to be satisfied. See ReadyToRunStandaloneMetadata.cs for the exact details of the format.

#### InjectStringThunks signatures

The `READYTORUN_FIXUP_InjectStringThunks` fixup is placed in an eager import section and is processed at R2R module load time. There is at most one such fixup per compilation. It encodes a mapping from UTF-8 strings to pregenerated code thunks embedded in the R2R image.

The signature following the fixup kind byte is a series of elements:

| Field | Size | Description
|:------|-----:|:-----------
| LookupString | variable | A null-terminated UTF-8 string (the lookup key)
| ThunkRVA | 4 bytes | An RVA into the module indicating the location of the thunk code. On WebAssembly platforms, this is an I32 function table index instead.

The series terminates when the null-terminated string is the empty string (a single `0x00` byte). There is no trailing RVA after the terminal empty string.

At runtime, the entries are merged into a global hash table. Strings already present in the table from previously loaded modules take precedence over new entries. The table can be queried via `LookupPregeneratedThunkByString`.

### READYTORUN_IMPORT_SECTIONS::AuxiliaryData

For slots resolved lazily via `READYTORUN_HELPER_DelayLoad_MethodCall` helper, auxiliary data are
Expand Down Expand Up @@ -985,6 +1001,96 @@ enum ReadyToRunHelper
};
```

# Wasm Signature String Encoding

Every managed method signature is encoded as a compact string that uniquely identifies its
lowered Wasm calling convention. This encoding is used in R2R thunk lookup tables and is
shared across three codebases:

- **crossgen2** (`WasmLowering.GetSignature`): reference implementation, produces the string
during R2R compilation.
- **WasmAppBuilder** (`SignatureMapper`): MSBuild task that generates interpreter-to-native
thunk tables from reflection metadata.
- **CoreCLR runtime** (`helpers.cpp`, `GetSignatureKey`): runtime signature computation for
calli and portable entrypoint thunks.

The string format is:

```
<return> [<this>] [<hidden-params>...] <explicit-params>... [p]
```

**Return type** (first character):

| Encoding | Meaning |
|---|---|
| `v` | void return, or empty struct return (no return buffer) |
| `i` | returns `i32` |
| `l` | returns `i64` |
| `f` | returns `f32` |
| `d` | returns `f64` |
| `S<N>` | struct return via hidden buffer, `N` is the struct size in bytes |

**This pointer** (if the method has a `this` parameter):

| Encoding | Meaning |
|---|---|
| `T` | `this` pointer (managed instance methods) |

**Hidden parameters** (inserted between `this` and explicit parameters, in order):

1. **Generic context** (`i`): present when the method requires an inst method desc or
method table argument.
2. **Async continuation** (`i`): present for async calls.

Note: the hidden return buffer pointer is **not** encoded in the signature string. Its
presence is implied by the return type being `S<N>` — when the caller sees a struct return,
it knows a hidden retbuf pointer argument is present in the Wasm parameter list.

**Explicit parameters** (one token per parameter, in declaration order):

| Encoding | Meaning |
|---|---|
| `i` | `i32` parameter |
| `l` | `i64` parameter |
| `f` | `f32` parameter |
| `d` | `f64` parameter |
| `S<N>` | struct parameter passed by reference, `N` is the struct size in bytes |
| `e` | empty struct parameter — elided from Wasm args but present in the string |

**Suffix**:

| Encoding | Meaning |
|---|---|
| `p` | managed call with portable entrypoint (the `&pe` argument is implicit) |
| *(absent)* | unmanaged callers only (reverse P/Invoke) |

**Prefix** (applied by the caller, not part of the core encoding):

When storing signature strings in thunk lookup tables, callers prepend a single-character
prefix to distinguish thunk categories:

| Prefix | Meaning |
|---|---|
| `M` | Calli thunk or interpreter-to-native thunk |
| `I` | Portable entrypoint-to-interpreter thunk |

**Examples**:

| Method | Signature string (no prefix) |
|---|---|
| `static void F()` | `vp` |
| `static int F(int x)` | `iip` |
| `void F(int x)` (instance) | `vTip` |
| `static MyStruct F()` where `MyStruct` is 16 bytes | `S16p` |
| `static void F(MyStruct s)` where `MyStruct` is 8 bytes | `vS8p` |
| `static int F(float x, double y)` | `ifdp` |
| `[UnmanagedCallersOnly] static int F(int x)` | `ii` |

**Slot sizing for structs**: When computing interpreter stack layout, struct parameters
(`S<N>`) consume `max(N / 8, 1)` interpreter stack slots, while all other parameter types
consume exactly 1 slot.

# References

[ECMA-335](https://www.ecma-international.org/publications-and-standards/standards/ecma-335)
4 changes: 4 additions & 0 deletions src/coreclr/inc/CrstTypes.def
Original file line number Diff line number Diff line change
Expand Up @@ -525,3 +525,7 @@ End
Crst CallStubCache
AcquiredBefore LoaderHeap
End

Crst PregeneratedStringThunks
AcquiredBefore UnresolvedClassLock
End
65 changes: 34 additions & 31 deletions src/coreclr/inc/crsttypes_generated.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,37 +88,38 @@ enum CrstType
CrstPgoData = 70,
CrstPinnedByrefValidation = 71,
CrstPinnedHeapHandleTable = 72,
CrstProfilerGCRefDataFreeList = 73,
CrstProfilingAPIStatus = 74,
CrstRCWCache = 75,
CrstRCWCleanupList = 76,
CrstReadyToRunEntryPointToMethodDescMap = 77,
CrstReflection = 78,
CrstReJITGlobalRequest = 79,
CrstSigConvert = 80,
CrstSingleUseLock = 81,
CrstStressLog = 82,
CrstStubCache = 83,
CrstStubDispatchCache = 84,
CrstSyncBlockCache = 85,
CrstSyncHashLock = 86,
CrstSystemDomain = 87,
CrstSystemDomainDelayedUnloadList = 88,
CrstThreadIdDispenser = 89,
CrstThreadLocalStorageLock = 90,
CrstThreadStore = 91,
CrstTieredCompilation = 92,
CrstTypeEquivalenceMap = 93,
CrstTypeIDMap = 94,
CrstUMEntryThunkCache = 95,
CrstUMEntryThunkFreeListLock = 96,
CrstUniqueStack = 97,
CrstUnresolvedClassLock = 98,
CrstUnwindInfoTablePendingLock = 99,
CrstUnwindInfoTablePublishLock = 100,
CrstVSDIndirectionCellLock = 101,
CrstWrapperTemplate = 102,
kNumberOfCrstTypes = 103
CrstPregeneratedStringThunks = 73,
CrstProfilerGCRefDataFreeList = 74,
CrstProfilingAPIStatus = 75,
CrstRCWCache = 76,
CrstRCWCleanupList = 77,
CrstReadyToRunEntryPointToMethodDescMap = 78,
CrstReflection = 79,
CrstReJITGlobalRequest = 80,
CrstSigConvert = 81,
CrstSingleUseLock = 82,
CrstStressLog = 83,
CrstStubCache = 84,
CrstStubDispatchCache = 85,
CrstSyncBlockCache = 86,
CrstSyncHashLock = 87,
CrstSystemDomain = 88,
CrstSystemDomainDelayedUnloadList = 89,
CrstThreadIdDispenser = 90,
CrstThreadLocalStorageLock = 91,
CrstThreadStore = 92,
CrstTieredCompilation = 93,
CrstTypeEquivalenceMap = 94,
CrstTypeIDMap = 95,
CrstUMEntryThunkCache = 96,
CrstUMEntryThunkFreeListLock = 97,
CrstUniqueStack = 98,
CrstUnresolvedClassLock = 99,
CrstUnwindInfoTablePendingLock = 100,
CrstUnwindInfoTablePublishLock = 101,
CrstVSDIndirectionCellLock = 102,
CrstWrapperTemplate = 103,
kNumberOfCrstTypes = 104
};

#endif // __CRST_TYPES_INCLUDED
Expand Down Expand Up @@ -202,6 +203,7 @@ int g_rgCrstLevelMap[] =
3, // CrstPgoData
0, // CrstPinnedByrefValidation
15, // CrstPinnedHeapHandleTable
7, // CrstPregeneratedStringThunks
0, // CrstProfilerGCRefDataFreeList
14, // CrstProfilingAPIStatus
3, // CrstRCWCache
Expand Down Expand Up @@ -310,6 +312,7 @@ LPCSTR g_rgCrstNameMap[] =
"CrstPgoData",
"CrstPinnedByrefValidation",
"CrstPinnedHeapHandleTable",
"CrstPregeneratedStringThunks",
"CrstProfilerGCRefDataFreeList",
"CrstProfilingAPIStatus",
"CrstRCWCache",
Expand Down
7 changes: 6 additions & 1 deletion src/coreclr/inc/readytorun.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
// If you update this, ensure you run `git grep MINIMUM_READYTORUN_MAJOR_VERSION`
// and handle pending work.
#define READYTORUN_MAJOR_VERSION 18
#define READYTORUN_MINOR_VERSION 0x0005
#define READYTORUN_MINOR_VERSION 0x0007

#define MINIMUM_READYTORUN_MAJOR_VERSION 18

Expand Down Expand Up @@ -56,6 +56,8 @@
// R2R Version 18.3 adds the ExternalTypeMaps, ProxyTypeMaps, TypeMapAssemblyTargets sections
// R2R Version 18.4 adds ThrowArgument, ThrowArgumentOutOfRange, ThrowPlatformNotSupported, and ThrowNotImplemented helpers
// R2R Version 18.5 adds READYTORUN_FLAG_STRIPPED_IL_BODIES, READYTORUN_FLAG_STRIPPED_INLINING_INFO, and READYTORUN_FLAG_STRIPPED_DEBUG_INFO flags
// R2R Version 18.6 adds READYTORUN_FIXUP_InjectStringThunks for mapping strings to pregenerated code thunks
// R2R Version 18.7 adds READYTORUN_HELPER_R2RToInterpreter

struct READYTORUN_CORE_HEADER
{
Expand Down Expand Up @@ -310,6 +312,8 @@ enum ReadyToRunFixupKind
READYTORUN_FIXUP_Continuation_Layout = 0x37, /* Layout of an async method continuation type */
READYTORUN_FIXUP_ResumptionStubEntryPoint = 0x38, /* Entry point of an async method resumption stub */

READYTORUN_FIXUP_InjectStringThunks = 0x39, /* Inject pregenerated string-to-code thunk mappings into the global lookup table */

READYTORUN_FIXUP_ModuleOverride = 0x80, /* followed by sig-encoded UInt with assemblyref index into either the assemblyref table of the MSIL metadata of the master context module for the signature or */
/* into the extra assemblyref table in the manifest metadata R2R header table (used in cases inlining brings in references to assemblies not seen in the MSIL). */
};
Expand Down Expand Up @@ -490,6 +494,7 @@ enum ReadyToRunHelper

READYTORUN_HELPER_InitClass = 0x116,
READYTORUN_HELPER_InitInstClass = 0x117,
READYTORUN_HELPER_R2RToInterpreter = 0x118,
};

#include "readytoruninstructionset.h"
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/inc/webcildecoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,8 @@ class WebcilDecoder

CHECK CheckDirectory(IMAGE_DATA_DIRECTORY *pDir, int forbiddenFlags = 0, IsNullOK ok = NULL_NOT_OK) const;
TADDR GetDirectoryData(IMAGE_DATA_DIRECTORY *pDir) const;

public:
SSIZE_T GetTableBaseOffset() const
{
if (m_pHeader == NULL)
Expand Down
7 changes: 5 additions & 2 deletions src/coreclr/jit/codegenwasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2480,14 +2480,17 @@ void CodeGen::genCallInstruction(GenTreeCall* call)
params.debugInfo = di;
}

#ifdef DEBUG
#if defined(DEBUG) || defined(TARGET_WASM)
// Pass the call signature information down into the emitter so the emitter can associate
// native call sites with the signatures they were generated from.
if (!call->IsHelperCall())
{
params.sigInfo = call->callSig;
_ASSERTE(call->callSig == NULL || params.hasAsyncRet == call->callSig->isAsyncCall());
params.sigInfo = call->callSig;
params.isUnmanagedCall = call->IsUnmanaged();
}
#endif // DEBUG

GenTree* target = getCallTarget(call, &params.methHnd);

ArrayStack<CorInfoWasmType> typeStack(m_compiler->getAllocator(CMK_Codegen));
Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/jit/emit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -883,7 +883,7 @@ void emitter::emitBegCG(Compiler* comp, COMP_HANDLE cmpHandle)
m_compiler = comp;
emitCmpHandle = cmpHandle;
m_debugInfoSize = sizeof(instrDescDebugInfo*);
#ifndef DEBUG
#if !defined(DEBUG) && !defined(TARGET_WASM)
if (!comp->opts.disAsm)
m_debugInfoSize = 0;
#endif
Expand Down Expand Up @@ -10590,7 +10590,7 @@ void emitter::emitRecordCallSite(ULONG instrOffset, /* IN */
CORINFO_SIG_INFO* callSig, /* IN */
CORINFO_METHOD_HANDLE methodHandle) /* IN */
{
#if defined(DEBUG)
#if defined(DEBUG) || defined(TARGET_WASM)
// Since CORINFO_SIG_INFO is a heavyweight structure, in most cases we can
// lazily obtain it here using the given method handle (we only save the sig
// info when we explicitly need it, i.e. for CALLI calls, vararg calls, and
Expand Down
28 changes: 17 additions & 11 deletions src/coreclr/jit/emit.h
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,7 @@ struct EmitCallParams
{
EmitCallType callType = EC_COUNT;
CORINFO_METHOD_HANDLE methHnd = NO_METHOD_HANDLE;
#ifdef DEBUG
#if defined(DEBUG) || defined(TARGET_WASM)
// Used to report call sites to the EE
CORINFO_SIG_INFO* sigInfo = nullptr;
#endif
Expand All @@ -494,6 +494,9 @@ struct EmitCallParams
ssize_t disp = 0;
bool isJump = false;
bool noSafePoint = false;
#ifdef TARGET_WASM
bool isUnmanagedCall = false;
#endif
#ifdef TARGET_WASM
CORINFO_WASM_TYPE_SYMBOL_HANDLE wasmSignature = nullptr;
#endif
Expand Down Expand Up @@ -641,16 +644,19 @@ class emitter

struct instrDescDebugInfo
{
unsigned idNum = 0;
size_t idSize = 0; // size of the instruction descriptor
unsigned idVarRefOffs = 0; // IL offset for LclVar reference
unsigned idVarRefOffs2 = 0; // IL offset for 2nd LclVar reference (in case this is a pair)
size_t idMemCookie = 0; // compile time handle (check idFlags)
GenTreeFlags idFlags = GTF_EMPTY; // for determining type of handle in idMemCookie
bool idFinallyCall = false; // Branch instruction is a call to finally
bool idCatchRet = false; // Instruction is for a catch 'return'
CORINFO_SIG_INFO* idCallSig = nullptr; // Used to report native call site signatures to the EE
BasicBlock* idTargetBlock = nullptr; // Target block for branches
unsigned idNum = 0;
size_t idSize = 0; // size of the instruction descriptor
unsigned idVarRefOffs = 0; // IL offset for LclVar reference
unsigned idVarRefOffs2 = 0; // IL offset for 2nd LclVar reference (in case this is a pair)
size_t idMemCookie = 0; // compile time handle (check idFlags)
GenTreeFlags idFlags = GTF_EMPTY; // for determining type of handle in idMemCookie
bool idFinallyCall = false; // Branch instruction is a call to finally
bool idCatchRet = false; // Instruction is for a catch 'return'
#ifdef TARGET_WASM
bool idIsUnmanagedCall = false; // Instruction is for an unmanaged call
#endif
CORINFO_SIG_INFO* idCallSig = nullptr; // Used to report native call site signatures to the EE
BasicBlock* idTargetBlock = nullptr; // Target block for branches

#ifdef TARGET_WASM
int lclBaseIndex = 0; // Base index of the WASM locals being declared
Expand Down
Loading
Loading