Skip to content

Commit d39b9db

Browse files
authored
Merge branch 'main' into wasm-fix-methodimpl-interpreter-crash
2 parents f837dd5 + 33db161 commit d39b9db

1,104 files changed

Lines changed: 13670 additions & 5434 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/skills/code-review/SKILL.md

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,11 @@ Use this skill when:
1919

2020
## Review Process
2121

22-
### Step 0: Gather Code Context (No PR Narrative Yet)
22+
### Step 0: Load Relevant Instructions
23+
24+
Before analyzing anything, load any and all instructions under `.github/instructions` that are relevant to the code changes, as indicated by the frontmatter. If conflict arises between said custom instructions and the instructions in this skill, the custom instructions supersede instructions in this skill.
25+
26+
### Step 1: Gather Code Context (No PR Narrative Yet)
2327

2428
Before analyzing anything, collect as much relevant **code** context as you can. **Critically, do NOT read the PR description, linked issues, or existing review comments yet.** You must form your own independent assessment of what the code does, why it might be needed, what problems it has, and whether the approach is sound — before being exposed to the author's framing. Reading the author's narrative first anchors your judgment and makes you less likely to find real problems.
2529

@@ -32,14 +36,14 @@ Before analyzing anything, collect as much relevant **code** context as you can.
3236
7. **Detect new public API surface**: Check whether the PR introduces new public API surface. Look for:
3337
- Changes to `ref/` assembly source files (the strongest signal — these define the public API contract)
3438
- New `public` members (methods, properties, types, enum values) in `src/` files
35-
- Note whether new public API was detected. If it was, you **MUST** load and execute the API approval verification procedure during Step 3. Read the file `.github/skills/code-review/api-approval-check.md` (relative to the repository root) and follow its instructions. Do not skip this step — it is blocking.
39+
- Note whether new public API was detected. If it was, you **MUST** load and execute the API approval verification procedure during Step 4. Read the file `.github/skills/code-review/api-approval-check.md` (relative to the repository root) and follow its instructions. Do not skip this step — it is blocking.
3640

37-
### Step 1: Discover Area-Specific Agents
41+
### Step 2: Discover Area-Specific Agents
3842
- Study **review** agents available in `.github/agents` folder that are capable of reviewing specific areas of the codebase. Their yaml frontmatter description tells when they apply.
3943
- When performing the review, invoke sub-agents to perform those area-specific reviews as subtasks during all subsequent steps, integrating those results.
4044
- Depending on the PR, more subagents might be launched. Launch them in parallel. Always continue regular review described here as well - the subagents are addons, not replacements.
4145

42-
### Step 2: Form an Independent Assessment
46+
### Step 3: Form an Independent Assessment
4347

4448
Based **only** on the code context gathered above (without the PR description or issue), answer these questions:
4549

@@ -50,7 +54,7 @@ Based **only** on the code context gathered above (without the PR description or
5054

5155
Write down your independent assessment before proceeding. You must produce a holistic assessment (see [Holistic PR Assessment](#holistic-pr-assessment)) at this stage.
5256

53-
### Step 3: Incorporate PR Narrative and Reconcile
57+
### Step 4: Incorporate PR Narrative and Reconcile
5458

5559
Now read the PR description, labels, linked issues (in full), author information, existing review comments, and any related open issues in the same area. Treat all of this as **claims to verify**, not facts to accept.
5660

@@ -59,9 +63,9 @@ Now read the PR description, labels, linked issues (in full), author information
5963
3. **Existing review comments**: Check if there are already review comments on the PR to avoid duplicating feedback.
6064
4. **Reconcile your assessment with the author's claims.** Where your independent reading of the code disagrees with the PR description or issue, investigate further — but do not simply defer to the author's framing. If the PR claims a bug fix, a performance improvement, or a behavioral correction, verify those claims against the code and any provided evidence. If your independent assessment found problems the PR narrative doesn't acknowledge, those problems are more likely to be real, not less.
6165
5. **Update your holistic assessment** if the additional context reveals information that genuinely changes your evaluation (e.g., a linked issue proves the bug is real, or an existing review comment already identified the same concern). But do not soften findings just because the PR description sounds reasonable.
62-
6. **API Approval Verification.** If Step 0 detected new public API surface, you **MUST** now load the file `.github/skills/code-review/api-approval-check.md` (relative to the repository root) and execute the full procedure described there. Use the `view` tool, `cat`, or equivalent to read the file contents into your context, then follow every step. This is a **blocking** gate — if any check in that procedure fails, the review verdict must be ❌ Reject or ❌ Needs Changes regardless of other findings. Do not proceed without completing this step when new public API is detected. **If the file cannot be loaded for any reason**, report ❌ error — "Unable to load API approval verification procedure; cannot verify new public API surface" — and set the verdict to ❌ Needs Changes.
66+
6. **API Approval Verification.** If Step 1 detected new public API surface, you **MUST** now load the file `.github/skills/code-review/api-approval-check.md` (relative to the repository root) and execute the full procedure described there. Use the `view` tool, `cat`, or equivalent to read the file contents into your context, then follow every step. This is a **blocking** gate — if any check in that procedure fails, the review verdict must be ❌ Reject or ❌ Needs Changes regardless of other findings. Do not proceed without completing this step when new public API is detected. **If the file cannot be loaded for any reason**, report ❌ error — "Unable to load API approval verification procedure; cannot verify new public API surface" — and set the verdict to ❌ Needs Changes.
6367

64-
### Step 4: Detailed Analysis
68+
### Step 5: Detailed Analysis
6569

6670
1. **Focus on what matters.** Prioritize bugs, performance regressions, safety issues, race conditions, resource management problems, incorrect assumptions about data or state, and API design problems. Do not comment on trivial style issues unless they violate an explicit rule below.
6771
2. **Consider collateral damage.** For every changed code path, actively brainstorm: what other scenarios, callers, or inputs flow through this code? Could any of them break or behave differently after this change? If you identify any plausible risk — even one you can't fully confirm — surface it so the author can evaluate. Do not dismiss behavioral changes because you believe the fix justifies them. The tradeoff is the author's decision — your job is to make it visible.

docs/coding-guidelines/interop-guidelines.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,10 @@ If implicit framework references are disabled (as is the case for most libraries
167167
- `System.Memory`
168168
- `System.Runtime.CompilerServices.Unsafe`
169169

170+
### Search paths
171+
172+
System.Private.CoreLib and libraries assemblies all set `DefaultDllImportSearchPaths` to `DllImportSearchPath.Assembly | DllImportSearchPath.System32` at the module level. This first looks in the assembly directory (application directory for single-file), then system directory on Windows or default search on non-Windows. For Windows P/Invokes that should only ever load from the system directory, this can be narrowed with `[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]` on the P/Invoke.
173+
170174
## UNIX shims
171175

172176
Often, various UNIX flavors offer the same API from the point-of-view of compatibility with C/C++ source code, but they do not have the same ABI. e.g. Fields can be laid out differently, constants can have different numeric values, exports can be named differently, etc. There are not only differences between operating systems (Mac OS X vs. Ubuntu vs. FreeBSD), but also differences related to the underlying processor architecture (x64 vs. x86 vs. ARM).
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Contract CallingConvention
2+
3+
This contract walks a method's argument signature using the runtime's
4+
calling-convention rules so consumers can locate each argument on the
5+
caller's transition frame and reason about which slots hold GC references.
6+
7+
The actual ABI (which registers hold which arguments, what alignment and
8+
padding rules apply, how structs are promoted to registers vs spilled, how
9+
varargs are passed, etc.) is documented in the CLR ABI specs and is not
10+
re-described here:
11+
12+
- [Common CLR ABI conventions](../coreclr/botr/clr-abi.md)
13+
14+
This contract's responsibility is to surface the *result* of that walk in
15+
a form the cDAC can use, byte-for-byte compatible with what the runtime
16+
itself produces.
17+
18+
## APIs of contract
19+
20+
``` csharp
21+
// Encode the argument GCRefMap blob for `methodDesc` byte-for-byte
22+
// compatible with the runtime's ComputeCallRefMap (frames.cpp).
23+
// Returns false when this contract declines to encode the method
24+
// (e.g. an unported ABI path); callers should map false to E_NOTIMPL.
25+
// When false, the value of `blob` is unspecified.
26+
bool TryComputeArgGCRefMapBlob(MethodDescHandle methodDesc, out byte[] blob);
27+
```
28+
29+
## Version 1
30+
31+
The single API is implemented by walking the shared `ArgIterator`
32+
(`src/coreclr/tools/Common/CallingConvention/ArgIterator.cs`) and feeding
33+
the per-argument result into a GCRefMap encoder that mirrors
34+
`GCRefMapBuilder` (`src/coreclr/inc/gcrefmap.h`).
35+
36+
`TryComputeArgGCRefMapBlob` returns `false` for any method whose
37+
signature, ABI path, or generic context the encoder hasn't been taught
38+
yet. The cdacstress harness (`src/coreclr/vm/cdacstress.cpp`,
39+
`ARGITER` sub-check) uses byte-for-byte comparison of the returned blob
40+
against the runtime's `ComputeCallRefMap` output as its correctness
41+
oracle.

docs/design/datacontracts/Object.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@ DelegateInfo GetDelegateInfo(TargetPointer address)
221221
Data.Delegate del = new Data.Delegate(target, address);
222222

223223
// Classify the delegate from its invocation count and auxiliary pointer.
224+
// This does not handle open virtual delegates correctly.
224225
DelegateType delegateType = target.ReadNInt(address + /* Delegate::InvocationCount offset */) switch
225226
{
226227
0 => del.MethodPtrAux == TargetCodePointer.Null

docs/design/datacontracts/RuntimeTypeSystem.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ partial interface IRuntimeTypeSystem : IContract
7373
public virtual TargetPointer GetWellKnownMethodTable(WellKnownMethodTable kind);
7474
// True if the MethodTable represents a type that contains managed references
7575
public virtual bool ContainsGCPointers(TypeHandle typeHandle);
76+
// True if the MethodTable represents a byref-like value type (Span<T>, ReadOnlySpan<T>, any ref struct).
77+
public virtual bool IsByRefLike(TypeHandle typeHandle);
7678
// True if the type requires 8-byte alignment on platforms that don't 8-byte align by default (FEATURE_64BIT_ALIGNMENT)
7779
public virtual bool RequiresAlign8(TypeHandle typeHandle);
7880
// True if the MethodTable represents a continuation type used by the async continuation feature
@@ -290,6 +292,10 @@ partial interface IRuntimeTypeSystem : IContract
290292
// Return true if the method is a wrapper stub (unboxing or instantiating).
291293
public virtual bool IsWrapperStub(MethodDescHandle methodDesc);
292294

295+
// Return true if the method is an unboxing stub (a wrapper around a
296+
// value-type instance method that unboxes `this` before forwarding).
297+
public virtual bool IsUnboxingStub(MethodDescHandle methodDesc);
298+
293299
}
294300
```
295301

@@ -302,6 +308,7 @@ bool IsFieldDescStatic(TargetPointer fieldDescPointer);
302308
bool IsFieldDescRVA(TargetPointer fieldDescPointer);
303309
uint GetFieldDescType(TargetPointer fieldDescPointer);
304310
uint GetFieldDescOffset(TargetPointer fieldDescPointer, FieldDefinition? fieldDef);
311+
TypeHandle GetFieldDescApproxTypeHandle(TargetPointer fieldDescPointer);
305312
TargetPointer GetFieldDescStaticAddress(TargetPointer fieldDescPointer, bool unboxValueTypes = true);
306313
TargetPointer GetFieldDescThreadStaticAddress(TargetPointer fieldDescPointer, TargetPointer thread, bool unboxValueTypes = true);
307314
```
@@ -330,6 +337,8 @@ internal partial struct RuntimeTypeSystem_1
330337
GenericsMask_SharedInst = 0x00000020, // shared instantiation, e.g. List<__Canon> or List<MyValueType<__Canon>>
331338
GenericsMask_TypicalInstantiation = 0x00000030, // the type instantiated at its formal parameters, e.g. List<T>
332339
340+
IsByRefLike = 0x00001000, // value type that may contain managed pointers (e.g. Span<T>, ReadOnlySpan<T>)
341+
333342
StringArrayValues = GenericsMask_NonGeneric,
334343
}
335344

@@ -404,6 +413,7 @@ internal partial struct RuntimeTypeSystem_1
404413
public bool IsTrackedReferenceWithFinalizer => GetFlag(WFLAGS_HIGH.IsTrackedReferenceWithFinalizer) != 0;
405414
public bool IsGenericTypeDefinition => TestFlagWithMask(WFLAGS_LOW.GenericsMask, WFLAGS_LOW.GenericsMask_TypicalInstantiation);
406415
public bool IsSharedByGenericInstantiations => TestFlagWithMask(WFLAGS_LOW.GenericsMask, WFLAGS_LOW.GenericsMask_SharedInst);
416+
public bool IsByRefLike => TestFlagWithMask(WFLAGS_LOW.IsByRefLike, WFLAGS_LOW.IsByRefLike);
407417
}
408418

409419
[Flags]
@@ -668,6 +678,8 @@ Contracts used:
668678

669679
public bool ContainsGCPointers(TypeHandle TypeHandle) => !typeHandle.IsMethodTable() ? false : _methodTables[TypeHandle.Address].Flags.ContainsGCPointers;
670680

681+
public bool IsByRefLike(TypeHandle typeHandle) => typeHandle.IsMethodTable() && _methodTables[typeHandle.Address].Flags.IsByRefLike;
682+
671683
public bool RequiresAlign8(TypeHandle typeHandle) => !typeHandle.IsMethodTable() ? false : _methodTables[typeHandle.Address].Flags.RequiresAlign8;
672684

673685
public bool IsCanonicalMethodTable(TypeHandle typeHandle)
@@ -1872,6 +1884,17 @@ Determining if a method is a wrapper stub (unboxing or instantiating):
18721884
}
18731885
```
18741886

1887+
Determining if a method is an unboxing stub. An unboxing stub is a wrapper
1888+
around a value-type instance method whose `this` is a boxed object: the
1889+
stub unboxes `this` and forwards to the real instance method. The bit is
1890+
stored in `MethodDescFlags3` and surfaces as the `IsUnboxingStub` flag on
1891+
`MethodDesc`:
1892+
1893+
```csharp
1894+
public bool IsUnboxingStub(MethodDescHandle methodDescHandle)
1895+
=> _methodDescs[methodDescHandle.Address].IsUnboxingStub;
1896+
```
1897+
18751898
Extracting a pointer to the `MethodDescVersioningState` data for a given method
18761899

18771900
```csharp
@@ -2232,6 +2255,15 @@ TargetPointer GetFieldDescThreadStaticAddress(TargetPointer fieldDescPointer, Ta
22322255
// Uses GetGCThreadStaticsBasePointer / GetNonGCThreadStaticsBasePointer.
22332256
// The unboxValueTypes parameter behaves the same as in GetFieldDescStaticAddress.
22342257
}
2258+
2259+
TypeHandle GetFieldDescApproxTypeHandle(TargetPointer fieldDescPointer)
2260+
{
2261+
// Resolve enclosing MT -> Module -> MetadataReader, decode the field's
2262+
// signature using the SignatureDecoder contract with a SignatureTypeProvider
2263+
// bound to the enclosing class as generic context, and return the resulting
2264+
// TypeHandle. Returns TypeHandle.Null if any link in the chain is unavailable
2265+
// (e.g. uncached constructed instantiation).
2266+
}
22352267
```
22362268

22372269
### Other APIs

docs/design/datacontracts/StackWalk.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ This contract depends on the following descriptors:
136136
| `ReadyToRunInfo` | `ImportSections` | Pointer to array of `READYTORUN_IMPORT_SECTION` structs for GCRefMap resolution |
137137
| `ReadyToRunInfo` | `NumImportSections` | Count of import sections in the array |
138138
| `FuncEvalFrame` | `DebuggerEvalPtr` | Pointer to the Frame's DebuggerEval object |
139+
| `FuncEvalFrame` | `ReturnAddress` | Return address of the frame |
139140
| `DebuggerEval` | `TargetContext` | Context saved inside DebuggerEval |
140141
| `DebuggerEval` | `EvalUsesHijack` | Flag used in processing FuncEvalFrame |
141142
| `DebuggerEval` | `MethodToken` | Metadata token of the method being evaluated |

docs/workflow/building/coreclr/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ As described in the [workflow README](/docs/workflow/README.md#building-the-repo
5050
Once you have both subsets built, you can generate the *Core_Root*, which as mentioned above, is the most flexible way of testing your changes. You can generate the *Core_Root* by running the following command, assuming a *Checked* clr build on an x64 machine:
5151

5252
```bash
53-
./src/tests/build.sh -x64 -checked -generatelayoutonly
53+
./src/tests/build.sh -arch x64 -checked -generatelayoutonly
5454
```
5555

5656
Since this is more related to testing, you can find the full details and instructions in the CoreCLR testing doc [over here](/docs/workflow/testing/coreclr/testing.md).

docs/workflow/building/coreclr/cross-building.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,15 +129,15 @@ The Crossgen2 JIT tools are used to run Crossgen2 on libraries built during the
129129
However, you might find yourself needing to (re)build them because either you made changes to them, or you built CoreCLR in a different way using `build-runtime.sh` instead of the usual default script at the root of the repo. To build these tools, you need to run the `src/coreclr/build-runtime.sh` script, and pass the `-hostarch` flag with the architecture of the host machine, alongside the `-component crosscomponents` flag to specify that you only want to build the cross-targeting tools. Retaking our previous example of building for ARM64 using an x64 Linux machine:
130130

131131
```bash
132-
./src/coreclr/build-runtime.sh -arm64 -hostarch x64 -component crosscomponents -cmakeargs "-DCLR_CROSS_COMPONENTS_BUILD=1"
132+
./src/coreclr/build-runtime.sh -arch arm64 -hostarch x64 -component crosscomponents -cmakeargs "-DCLR_CROSS_COMPONENTS_BUILD=1"
133133
```
134134

135135
The output of running this command is placed in `artifacts/bin/coreclr/linux.<target_arch>.<configuration>/<host_arch>`. For our example, it would be `artifacts/bin/coreclr/linux.arm64.Release/x64`.
136136

137137
On Windows, you can build these cross-targeting diagnostic libraries with the `linuxdac` and `alpinedac` subsets from the root `build.cmd` script. That said, you can also use the `build-runtime.cmd` script, like with Linux. These builds also require you to pass the `-os` flag to specify the target OS. For example:
138138

139139
```cmd
140-
.\src\coreclr\build-runtime.cmd -arm64 -hostarch x64 -os linux -component crosscomponents -cmakeargs "-DCLR_CROSS_COMPONENTS_BUILD=1"
140+
.\src\coreclr\build-runtime.cmd -arch arm64 -hostarch x64 -os linux -component crosscomponents -cmakeargs "-DCLR_CROSS_COMPONENTS_BUILD=1"
141141
```
142142

143143
If you're building the cross-components in powershell, you'll need to wrap `"-DCLR_CROSS_COMPONENTS_BUILD=1"` with single quotes (`'`) to ensure things are escaped correctly for CMD.
@@ -218,7 +218,7 @@ arch=arm64
218218
./build.sh clr+libs --cross --arch $arch --os $os --use-bootstrap
219219

220220
# CoreCLR runtime tests.
221-
src/tests/build.sh -cross -$arch -$os -p:LibrariesConfiguration=Debug --use-bootstrap
221+
src/tests/build.sh --cross --arch $arch --os $os -p:LibrariesConfiguration=Debug --use-bootstrap
222222

223223
# Libraries tests (produces zipped per-library test archives under artifacts/helix/tests/).
224224
./build.sh libs.tests --cross --arch $arch --os $os --use-bootstrap -p:ArchiveTests=true

docs/workflow/building/coreclr/ios.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ open ./src/mono/sample/iOS/bin/<ios|iossimulator|tvossimulator|maccatalyst>-arm6
107107
To build the runtime tests for iOS with CoreCLR, run the following command from `<repo-root>`:
108108
109109
```bash
110-
./src/tests/build.sh -os <ios|iossimulator|tvossimulator|maccatalyst> arm64 <Release|Debug> -p:UseMonoRuntime=false
110+
./src/tests/build.sh -os <ios|iossimulator|tvossimulator|maccatalyst> -arch arm64 <Release|Debug> -p:UseMonoRuntime=false
111111
```
112112
113113
## Debugging the runtime and the sample app

docs/workflow/testing/libraries/testing-apple.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ Currently, only the `tracing/eventpipe` subset of runtime tests is enabled on iO
9696
The subset of runtime tests can be built by executing the following shell script:
9797
```sh
9898
./build.sh -arch arm64 -os ios -s mono+libs -c Release
99-
./src/tests/build.sh os ios arm64 Release -mono tree tracing/eventpipe /p:LibrariesConfiguration=Release
99+
./src/tests/build.sh -os ios -arch arm64 Release -mono tree tracing/eventpipe /p:LibrariesConfiguration=Release
100100
```
101101

102102
The script generates an Apple bundle that can be executed using Xcode or XHarness.

0 commit comments

Comments
 (0)