Skip to content

Improve managed ilasm test coverage - #131509

Open
jkoritzinsky wants to merge 14 commits into
ilasm-fixupsfrom
ilasm-more-tests
Open

Improve managed ilasm test coverage#131509
jkoritzinsky wants to merge 14 commits into
ilasm-fixupsfrom
ilasm-more-tests

Conversation

@jkoritzinsky

@jkoritzinskyjkoritzinsky commented Jul 28, 2026

Copy link
Copy Markdown
Member

Add feature-focused metadata and PE validation tests and fix emitter issues exposed by them.

With these unit tests (amongst others added in the stack) we can have more confidence in the managed ilasm implementation. In the future, we may even be able to move ilasm round-trip testing to an "outerloop" experience for ilasm instead of being the primary validation pipeline.

This PR also includes fixes and corresponding tests for failures identified with ildasm/ilasm round-trip testing (all except one, which is addressed by #132346).


Stack created with GitHub Stacks CLIGive Feedback 💬

Note

This PR description was generated with GitHub Copilot.

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
16 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

@jkoritzinskyjkoritzinsky changed the title ilasm more testsImprove ILAssembler test coverageJul 28, 2026
@jkoritzinskyjkoritzinsky changed the title Improve ILAssembler test coverageImprove managed ilasm test coverageJul 28, 2026
@jkoritzinsky
jkoritzinsky marked this pull request as ready for review July 28, 2026 23:33
CopilotAI lite review requested due to automatic review settings July 28, 2026 23:33
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
16 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 significantly expands the managed ilasm unit test suite to validate emitted metadata/PE structures (exports, resources, PDBs, signatures, marshalling, etc.), and adjusts the managed ilasm emitter/parser to satisfy the newly-covered scenarios.

Changes:

  • Add many new ILAssembler.Tests cases that decode emitted metadata/PE/PDB and validate specific directives and operand forms.
  • Fix/extend ilasm implementation details in GrammarVisitor (e.g., custom attribute serialization, .module handling, sequence points, callconv explicit/instance) and VTableExportPEBuilder (vtable fixup directory offset + export table layout).
  • Improve test infra helpers to compile IL text and decode IL token operands/signatures more easily.

Reviewed changes

Copilot reviewed 32 out of 32 changed files in this pull request and generated 2 comments.

Show a summary per file
FileDescription
src/tools/ilasm/tests/ILAssembler.Tests/VTableTests.csMinor formatting-only change.
src/tools/ilasm/tests/ILAssembler.Tests/TypeSignatureTests.csAdd tests for multidimensional array local signature shapes.
src/tools/ilasm/tests/ILAssembler.Tests/TypeReferenceTests.csAdd tests for .this/.base/.nester/mdtoken type refs, module-scoped refs, typelist parsing.
src/tools/ilasm/tests/ILAssembler.Tests/TypedefTests.csAdd tests for .typedef aliases for fields and custom attributes.
src/tools/ilasm/tests/ILAssembler.Tests/TypeDefinitionTests.csAdd tests for type name splitting, class flags/attributes, nested types, interface impl metadata.
src/tools/ilasm/tests/ILAssembler.Tests/SourceDirectiveTests.csStrengthen .line/.language coverage and validate emitted embedded PDB details + string escape correctness.
src/tools/ilasm/tests/ILAssembler.Tests/SecurityTests.csAdd extensive .permissionset emission/shape tests (incl. tolerant-mode behavior).
src/tools/ilasm/tests/ILAssembler.Tests/PropertyTests.csAdd property attribute/accessor/signature metadata validation.
src/tools/ilasm/tests/ILAssembler.Tests/PropertyEventTests.csNew test file covering PropertyMap/EventMap + MethodSemantics emission.
src/tools/ilasm/tests/ILAssembler.Tests/PreprocessorIntegrationTests.csNew integration tests for nested includes, conditional compilation, multi-token macros.
src/tools/ilasm/tests/ILAssembler.Tests/ParameterTests.csAdd tests for parameter attribute forms and raw flag parsing.
src/tools/ilasm/tests/ILAssembler.Tests/NativeExportTests.csNew tests validating when exports are (not) emitted and verifying export directory/stubs.
src/tools/ilasm/tests/ILAssembler.Tests/ModuleTests.csAdd tests for .file, .module extern, bare .module, and global method/module metadata + PDB.
src/tools/ilasm/tests/ILAssembler.Tests/MethodTests.csAdd tests for method attributes/impl flags, method body directives, entrypoint token, override forms.
src/tools/ilasm/tests/ILAssembler.Tests/MemberReferenceTests.csAdd tests for vararg MemberRef signatures, generic-instantiation MemberRefs, method spec emission.
src/tools/ilasm/tests/ILAssembler.Tests/ManifestResourceTests.csNew tests for embedded/assembly/file-backed manifest resources + tolerant/deterministic behaviors.
src/tools/ilasm/tests/ILAssembler.Tests/InteropTests.csAdd marshalling and P/Invoke import metadata tests (incl. complex native type payloads).
src/tools/ilasm/tests/ILAssembler.Tests/InstructionTests.csAdd coverage for float bit-pattern literals, calli sigs, ldstr forms, switch table forms, token operands.
src/tools/ilasm/tests/ILAssembler.Tests/GenericTests.csAdd generic parameter name/bounds/variance/custom attribute/constraint metadata tests.
src/tools/ilasm/tests/ILAssembler.Tests/FunctionPointerTests.csUpdate function pointer signature assertions to use decoded signatures; add vararg fnptr test.
src/tools/ilasm/tests/ILAssembler.Tests/FieldTests.csAdd tests for field attribute flags, volatile/literal/nullref constant emission.
src/tools/ilasm/tests/ILAssembler.Tests/ExportedTypeTests.csAdd tests for exported type attributes/implementations + custom attributes.
src/tools/ilasm/tests/ILAssembler.Tests/ExceptionHandlingTests.csAdd tests validating EH region bounds/kinds for multiple clause forms.
src/tools/ilasm/tests/ILAssembler.Tests/EventTests.csAdd tests for event raise accessor, event “other” accessor, and attribute emission.
src/tools/ilasm/tests/ILAssembler.Tests/DocumentCompilerTests.csNew test validating diagnostics pathing across multi-document compilation in tolerant mode.
src/tools/ilasm/tests/ILAssembler.Tests/DocumentCompilerTestHelpers.csAdd decoder + richer compile helpers and IL token operand extraction.
src/tools/ilasm/tests/ILAssembler.Tests/DataTests.csAdd tests for .data directive typed byte emission, repeats, and class-scoped .data.
src/tools/ilasm/tests/ILAssembler.Tests/CustomAttributeTests.csAdd broad structured custom attribute decoding tests (arrays, boxed values, owner targeting, type args).
src/tools/ilasm/tests/ILAssembler.Tests/CompilerOptionsTests.csNew tests validating Options-driven PE/header/corflags/debug/pdb/determinism/keyfile behaviors.
src/tools/ilasm/tests/ILAssembler.Tests/AssemblyTests.csAdd tests for assembly reference identity metadata and aliased reference/assembly attributes.
src/tools/ilasm/src/ILAssembler/VTableExportPEBuilder.csFix COR header vtable fixup directory offset; refactor vtable slot serialization and export table layout.
src/tools/ilasm/src/ILAssembler/GrammarVisitor.csNumerous parser/emitter fixes to support new metadata/PDB/custom-attribute/directive scenarios.
Comments suppressed due to low confidence (1)

src/tools/ilasm/src/ILAssembler/GrammarVisitor.cs:2924

  • Same as above: ToImmutable() copies; MoveToImmutable() can transfer the backing array without allocating, which is preferable in a potentially hot parsing path.
 return new(builder.ToImmutable().SerializeSequence());

Comment threadsrc/tools/ilasm/src/ILAssembler/GrammarVisitor.cs Outdated
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

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

CopilotAI review requested due to automatic review settings July 29, 2026 00:01

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 32 out of 32 changed files in this pull request and generated no new comments.

CopilotAI review requested due to automatic review settings July 29, 2026 00:07

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 32 out of 32 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (3)

src/tools/ilasm/tests/ILAssembler.Tests/TypeSignatureTests.cs:92

  • This test assumes the locals signature is always StandAloneSig row 1. Using the method body's LocalSignature handle avoids tying the assertion to metadata row ordering.
 var signature = reader.GetStandaloneSignature(MetadataTokens.StandaloneSignatureHandle(1));

src/tools/ilasm/tests/ILAssembler.Tests/TypeSignatureTests.cs:125

  • Hard-coding StandaloneSignatureHandle(1) here couples the test to metadata emission order. Use the method body's LocalSignature to make the test robust against unrelated StandAloneSig additions.
 var signature = reader.GetStandaloneSignature(MetadataTokens.StandaloneSignatureHandle(1));

src/tools/ilasm/tests/ILAssembler.Tests/TypeSignatureTests.cs:66

  • This test hard-codes StandaloneSignatureHandle(1), which makes it brittle if the compiler ever emits another StandAloneSig row before the locals signature. Prefer using the method body's LocalSignature handle so the test is resilient to unrelated metadata changes.

This issue also appears in the following locations of the same file:

  • line 92
  • line 125
 var signature = reader.GetStandaloneSignature(MetadataTokens.StandaloneSignatureHandle(1));

CopilotAI review requested due to automatic review settings July 29, 2026 00:34

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 32 out of 32 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (1)

src/tools/ilasm/src/ILAssembler/GrammarVisitor.cs:5573

  • In structured custom attribute encoding, a boxed object(...) value must include the SerializationTypeCode.TaggedObject (0x51) prefix, followed by the embedded value’s FieldOrPropType and value bytes. The current object(...) branch writes only the embedded type/value and omits the TaggedObject prefix, which will make decoding object arguments invalid (and can break object[] element encoding too).
 if (context.serInit() is CILParser.SerInitContext serInit)
{
Debug.Assert(context.OBJECT() is not null);
BlobBuilder taggedObjectBlob = new();
WriteCustomAttributeFieldOrPropType(taggedObjectBlob, serInit);
taggedObjectBlob.LinkSuffix(VisitSerInit(serInit).Value);
return new(taggedObjectBlob);

Comment threadsrc/tools/ilasm/src/ILAssembler/GrammarVisitor.cs
CopilotAI review requested due to automatic review settings July 29, 2026 00:44

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 32 out of 32 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (1)

src/tools/ilasm/tests/ILAssembler.Tests/DocumentCompilerTestHelpers.cs:123

  • GetTokenOperands reads the method body without validating RelativeVirtualAddress > 0, so callers get an exception from PEReader.GetMethodBody instead of a clear test failure message when the target method has no body (e.g., runtime/abstract methods). This helper already has a good pattern in GetFirstTokenOperand; it should mirror that assert for consistency and debuggability.
 var method = reader.MethodDefinitions
.Select(reader.GetMethodDefinition)
.First(definition => reader.GetString(definition.Name) == methodName);
byte[] il = pe.GetMethodBody(method.RelativeVirtualAddress).GetILBytes()!;
var operands = ImmutableArray.CreateBuilder<int>();

CopilotAI review requested due to automatic review settings July 29, 2026 19:00
CopilotAI review requested due to automatic review settings August 24, 2026 21:28

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 44 out of 48 changed files in this pull request and generated 4 comments.

Comment threadsrc/tools/ilasm/src/ILAssembler/DocumentCompiler.cs Outdated
Comment threadsrc/tools/ilasm/src/ILAssembler/Options.cs
Comment threadsrc/tools/ilasm/src/ILAssembler/CompilationResult.cs
Comment threadsrc/tools/ilasm/src/ILAssembler/DocumentCompiler.cs
CopilotAI review requested due to automatic review settings August 26, 2026 20:30

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 41 out of 45 changed files in this pull request and generated 3 comments.

Suppressed comments (1)

src/tools/ilasm/src/ILAssembler/EntityRegistry.cs:418

  • The fallback AddMethodBody(...) paths also OR in MethodBodyAttributes.InitLocals when forceFatHeader is true. For the same reason as the main path, this can set InitLocals even when it wasn’t requested; it should be sufficient to pass the existing attributes and use hasDynamicStackAllocation to prevent a tiny header.
 localsSigHandle,
forceFatHeader ? methodDef.BodyAttributes | MethodBodyAttributes.InitLocals : methodDef.BodyAttributes,
hasDynamicStackAllocation: methodDef.HasDynamicStackAllocation || forceFatHeader);

Comment on lines +393 to +404
MethodBodyAttributes encodingAttributes = methodDef.BodyAttributes;
if (forceFatHeader)
{
encodingAttributes |= MethodBodyAttributes.InitLocals;
}

bodyOffset = bodyStreamEncoder.AddMethodBody(
methodDef.MethodBody,
methodDef.MaxStack,
localsSigHandle,
methodDef.BodyAttributes);
encodingAttributes,
methodDef.HasDynamicStackAllocation || forceFatHeader);
Comment threadsrc/tools/ilasm/tests/ILAssembler.Tests/GenericTests.cs
Comment on lines +18 to +29
<PropertyGroup>
<!-- Keep these NativeAOT runtime settings in sync with the first PropertyGroup in AotCompilerCommon.props. -->
<ServerGarbageCollection>true</ServerGarbageCollection>
<TieredCompilation>false</TieredCompilation>
<EventSourceSupport>true</EventSourceSupport>
<OptimizationPreference>Speed</OptimizationPreference>
<ControlFlowGuard>Guard</ControlFlowGuard>
<InvariantGlobalization>true</InvariantGlobalization>
<StripSymbols Condition="'$(KeepNativeSymbols)' == 'true'">false</StripSymbols>
<XmlResolverIsNetworkingEnabledByDefault>false</XmlResolverIsNetworkingEnabledByDefault>
<StackTraceLineNumberSupport>true</StackTraceLineNumberSupport>
</PropertyGroup>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This looks like valid feedback to me. Why do we need to have this copy?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

AotCompilerCommon.props also copies all of the JITs, which was exacerbating some of the CI failures I was seeing on the ilasm pipeline. I'll refactor out AotCompilerCommon.props into an "AotTool.props" that contains the AOT config settings and keep the original file for the info to copy JITs.

CopilotAI review requested due to automatic review settings August 26, 2026 20:46

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 41 out of 45 changed files in this pull request and generated 1 comment.

Comment on lines +524 to 528
for (int ordinal = baseOrdinal; ordinal <= maxOrdinal; ordinal++)
{
int stubIndex = Array.FindIndex(exportsArray, e => e.Ordinal == export.Ordinal);
builder.WriteInt32(exportStubRvas[stubIndex]);
int stubIndex = Array.FindIndex(exportsArray, export => export.Ordinal == ordinal);
builder.WriteInt32(stubIndex >= 0 ? exportStubRvas[stubIndex] : 0);
}
jkoritzinskyand others added 14 commits August 26, 2026 14:31
Use content-based portable PDB IDs for deterministic builds and add in-process coverage for byte-identical PDB output and non-empty PDB ID GUIDs.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2fb9f1ef-f721-49e0-bf48-4a7a9458d53a
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2fb9f1ef-f721-49e0-bf48-4a7a9458d53a
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2fb9f1ef-f721-49e0-bf48-4a7a9458d53a
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2fb9f1ef-f721-49e0-bf48-4a7a9458d53a
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2fb9f1ef-f721-49e0-bf48-4a7a9458d53a
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 106f96fe-da32-41d4-8aa5-7431edb36fc6
…ompiler, it's a compiler that's AOT compiled)
Add feature-focused metadata and PE validation tests and fix emitter issues exposed by them.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 4307156b-37a7-495d-9af6-fe9174c05b0b
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
… attribute encoding
When an object(...) element in an object[] custom attribute had nested
object() wrappers (e.g. object(object(bool(true)))), VisitSerInit's
object() branch would call WriteCustomAttributeFieldOrPropType on the
inner object() context, producing TaggedObject (0x51) as the element
type code. The .NET metadata decoder does not accept 0x51 as a
FieldOrPropType for object[] elements and throws BadImageFormatException.
Fix VisitObjSeq to fully unwrap any object(...) nesting using a while
loop, so that WriteCustomAttributeFieldOrPropType is always called with
the innermost concrete typed element (bool, int32, string, etc.). This
also makes type-byte handling uniform - always done by VisitObjSeq
rather than split between caller and callee.
Add a regression test CustomAttribute_ObjectArrayWithNestedObjectWrapper
_DecodesProperly that exercises object[](object(bool(true)) object(int32
(42))) and verifies the attribute decodes correctly.
Use comma separators between double-quoted GUID arguments so the tests match the supported .language grammar.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: adc580d5-8f1c-4772-bfc2-7a943aa0959d
Pre-size floating-point sequence builders and transfer their arrays without copying. Handle empty floating-point and string sequences and cover their custom attribute encoding.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: adc580d5-8f1c-4772-bfc2-7a943aa0959d
foreach (GenericParameterEntity genericParam in GetSeenEntities(TableIndex.GenericParam))
{
// GenericParam index is stored as a 2-byte value; skip params beyond the limit
// COMPAT: Native ilasm ignores generic parameters whose indices exceed the 2-byte metadata limit.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should this fail with an error instead?

I do not think we need to preserve every native ilasm bug. We should fix these bugs as we run into them.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

My goal was to get us to a clean ilasm round trip run without adding support for a "managed ilasm incompatible" flag. I'll add such a flag for the test case that fails because of this (and revert this compat quirk) so we can review if the test is interesting as-is.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

4 participants

@jkoritzinsky@jkotas@JulieLeeMSFT
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Improve managed ilasm test coverage by jkoritzinsky · Pull Request #131509 · dotnet/runtime · GitHub
Skip to content

Improve managed ilasm test coverage - #131509

Open
jkoritzinsky wants to merge 14 commits into
ilasm-fixupsfrom
ilasm-more-tests
Open

Improve managed ilasm test coverage#131509
jkoritzinsky wants to merge 14 commits into
ilasm-fixupsfrom
ilasm-more-tests

Conversation

@jkoritzinsky

@jkoritzinskyjkoritzinsky commented Jul 28, 2026

Copy link
Copy Markdown
Member

Add feature-focused metadata and PE validation tests and fix emitter issues exposed by them.

With these unit tests (amongst others added in the stack) we can have more confidence in the managed ilasm implementation. In the future, we may even be able to move ilasm round-trip testing to an "outerloop" experience for ilasm instead of being the primary validation pipeline.

This PR also includes fixes and corresponding tests for failures identified with ildasm/ilasm round-trip testing (all except one, which is addressed by #132346).


Stack created with GitHub Stacks CLIGive Feedback 💬

Note

This PR description was generated with GitHub Copilot.

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
16 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

@jkoritzinskyjkoritzinsky changed the title ilasm more testsImprove ILAssembler test coverageJul 28, 2026
@jkoritzinskyjkoritzinsky changed the title Improve ILAssembler test coverageImprove managed ilasm test coverageJul 28, 2026
@jkoritzinsky
jkoritzinsky marked this pull request as ready for review July 28, 2026 23:33
CopilotAI lite review requested due to automatic review settings July 28, 2026 23:33
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
16 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 significantly expands the managed ilasm unit test suite to validate emitted metadata/PE structures (exports, resources, PDBs, signatures, marshalling, etc.), and adjusts the managed ilasm emitter/parser to satisfy the newly-covered scenarios.

Changes:

  • Add many new ILAssembler.Tests cases that decode emitted metadata/PE/PDB and validate specific directives and operand forms.
  • Fix/extend ilasm implementation details in GrammarVisitor (e.g., custom attribute serialization, .module handling, sequence points, callconv explicit/instance) and VTableExportPEBuilder (vtable fixup directory offset + export table layout).
  • Improve test infra helpers to compile IL text and decode IL token operands/signatures more easily.

Reviewed changes

Copilot reviewed 32 out of 32 changed files in this pull request and generated 2 comments.

Show a summary per file
FileDescription
src/tools/ilasm/tests/ILAssembler.Tests/VTableTests.csMinor formatting-only change.
src/tools/ilasm/tests/ILAssembler.Tests/TypeSignatureTests.csAdd tests for multidimensional array local signature shapes.
src/tools/ilasm/tests/ILAssembler.Tests/TypeReferenceTests.csAdd tests for .this/.base/.nester/mdtoken type refs, module-scoped refs, typelist parsing.
src/tools/ilasm/tests/ILAssembler.Tests/TypedefTests.csAdd tests for .typedef aliases for fields and custom attributes.
src/tools/ilasm/tests/ILAssembler.Tests/TypeDefinitionTests.csAdd tests for type name splitting, class flags/attributes, nested types, interface impl metadata.
src/tools/ilasm/tests/ILAssembler.Tests/SourceDirectiveTests.csStrengthen .line/.language coverage and validate emitted embedded PDB details + string escape correctness.
src/tools/ilasm/tests/ILAssembler.Tests/SecurityTests.csAdd extensive .permissionset emission/shape tests (incl. tolerant-mode behavior).
src/tools/ilasm/tests/ILAssembler.Tests/PropertyTests.csAdd property attribute/accessor/signature metadata validation.
src/tools/ilasm/tests/ILAssembler.Tests/PropertyEventTests.csNew test file covering PropertyMap/EventMap + MethodSemantics emission.
src/tools/ilasm/tests/ILAssembler.Tests/PreprocessorIntegrationTests.csNew integration tests for nested includes, conditional compilation, multi-token macros.
src/tools/ilasm/tests/ILAssembler.Tests/ParameterTests.csAdd tests for parameter attribute forms and raw flag parsing.
src/tools/ilasm/tests/ILAssembler.Tests/NativeExportTests.csNew tests validating when exports are (not) emitted and verifying export directory/stubs.
src/tools/ilasm/tests/ILAssembler.Tests/ModuleTests.csAdd tests for .file, .module extern, bare .module, and global method/module metadata + PDB.
src/tools/ilasm/tests/ILAssembler.Tests/MethodTests.csAdd tests for method attributes/impl flags, method body directives, entrypoint token, override forms.
src/tools/ilasm/tests/ILAssembler.Tests/MemberReferenceTests.csAdd tests for vararg MemberRef signatures, generic-instantiation MemberRefs, method spec emission.
src/tools/ilasm/tests/ILAssembler.Tests/ManifestResourceTests.csNew tests for embedded/assembly/file-backed manifest resources + tolerant/deterministic behaviors.
src/tools/ilasm/tests/ILAssembler.Tests/InteropTests.csAdd marshalling and P/Invoke import metadata tests (incl. complex native type payloads).
src/tools/ilasm/tests/ILAssembler.Tests/InstructionTests.csAdd coverage for float bit-pattern literals, calli sigs, ldstr forms, switch table forms, token operands.
src/tools/ilasm/tests/ILAssembler.Tests/GenericTests.csAdd generic parameter name/bounds/variance/custom attribute/constraint metadata tests.
src/tools/ilasm/tests/ILAssembler.Tests/FunctionPointerTests.csUpdate function pointer signature assertions to use decoded signatures; add vararg fnptr test.
src/tools/ilasm/tests/ILAssembler.Tests/FieldTests.csAdd tests for field attribute flags, volatile/literal/nullref constant emission.
src/tools/ilasm/tests/ILAssembler.Tests/ExportedTypeTests.csAdd tests for exported type attributes/implementations + custom attributes.
src/tools/ilasm/tests/ILAssembler.Tests/ExceptionHandlingTests.csAdd tests validating EH region bounds/kinds for multiple clause forms.
src/tools/ilasm/tests/ILAssembler.Tests/EventTests.csAdd tests for event raise accessor, event “other” accessor, and attribute emission.
src/tools/ilasm/tests/ILAssembler.Tests/DocumentCompilerTests.csNew test validating diagnostics pathing across multi-document compilation in tolerant mode.
src/tools/ilasm/tests/ILAssembler.Tests/DocumentCompilerTestHelpers.csAdd decoder + richer compile helpers and IL token operand extraction.
src/tools/ilasm/tests/ILAssembler.Tests/DataTests.csAdd tests for .data directive typed byte emission, repeats, and class-scoped .data.
src/tools/ilasm/tests/ILAssembler.Tests/CustomAttributeTests.csAdd broad structured custom attribute decoding tests (arrays, boxed values, owner targeting, type args).
src/tools/ilasm/tests/ILAssembler.Tests/CompilerOptionsTests.csNew tests validating Options-driven PE/header/corflags/debug/pdb/determinism/keyfile behaviors.
src/tools/ilasm/tests/ILAssembler.Tests/AssemblyTests.csAdd tests for assembly reference identity metadata and aliased reference/assembly attributes.
src/tools/ilasm/src/ILAssembler/VTableExportPEBuilder.csFix COR header vtable fixup directory offset; refactor vtable slot serialization and export table layout.
src/tools/ilasm/src/ILAssembler/GrammarVisitor.csNumerous parser/emitter fixes to support new metadata/PDB/custom-attribute/directive scenarios.
Comments suppressed due to low confidence (1)

src/tools/ilasm/src/ILAssembler/GrammarVisitor.cs:2924

  • Same as above: ToImmutable() copies; MoveToImmutable() can transfer the backing array without allocating, which is preferable in a potentially hot parsing path.
 return new(builder.ToImmutable().SerializeSequence());

Comment threadsrc/tools/ilasm/src/ILAssembler/GrammarVisitor.cs Outdated
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

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

CopilotAI review requested due to automatic review settings July 29, 2026 00:01

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 32 out of 32 changed files in this pull request and generated no new comments.

CopilotAI review requested due to automatic review settings July 29, 2026 00:07

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 32 out of 32 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (3)

src/tools/ilasm/tests/ILAssembler.Tests/TypeSignatureTests.cs:92

  • This test assumes the locals signature is always StandAloneSig row 1. Using the method body's LocalSignature handle avoids tying the assertion to metadata row ordering.
 var signature = reader.GetStandaloneSignature(MetadataTokens.StandaloneSignatureHandle(1));

src/tools/ilasm/tests/ILAssembler.Tests/TypeSignatureTests.cs:125

  • Hard-coding StandaloneSignatureHandle(1) here couples the test to metadata emission order. Use the method body's LocalSignature to make the test robust against unrelated StandAloneSig additions.
 var signature = reader.GetStandaloneSignature(MetadataTokens.StandaloneSignatureHandle(1));

src/tools/ilasm/tests/ILAssembler.Tests/TypeSignatureTests.cs:66

  • This test hard-codes StandaloneSignatureHandle(1), which makes it brittle if the compiler ever emits another StandAloneSig row before the locals signature. Prefer using the method body's LocalSignature handle so the test is resilient to unrelated metadata changes.

This issue also appears in the following locations of the same file:

  • line 92
  • line 125
 var signature = reader.GetStandaloneSignature(MetadataTokens.StandaloneSignatureHandle(1));

CopilotAI review requested due to automatic review settings July 29, 2026 00:34

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 32 out of 32 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (1)

src/tools/ilasm/src/ILAssembler/GrammarVisitor.cs:5573

  • In structured custom attribute encoding, a boxed object(...) value must include the SerializationTypeCode.TaggedObject (0x51) prefix, followed by the embedded value’s FieldOrPropType and value bytes. The current object(...) branch writes only the embedded type/value and omits the TaggedObject prefix, which will make decoding object arguments invalid (and can break object[] element encoding too).
 if (context.serInit() is CILParser.SerInitContext serInit)
{
Debug.Assert(context.OBJECT() is not null);
BlobBuilder taggedObjectBlob = new();
WriteCustomAttributeFieldOrPropType(taggedObjectBlob, serInit);
taggedObjectBlob.LinkSuffix(VisitSerInit(serInit).Value);
return new(taggedObjectBlob);

Comment threadsrc/tools/ilasm/src/ILAssembler/GrammarVisitor.cs
CopilotAI review requested due to automatic review settings July 29, 2026 00:44

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 32 out of 32 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (1)

src/tools/ilasm/tests/ILAssembler.Tests/DocumentCompilerTestHelpers.cs:123

  • GetTokenOperands reads the method body without validating RelativeVirtualAddress > 0, so callers get an exception from PEReader.GetMethodBody instead of a clear test failure message when the target method has no body (e.g., runtime/abstract methods). This helper already has a good pattern in GetFirstTokenOperand; it should mirror that assert for consistency and debuggability.
 var method = reader.MethodDefinitions
.Select(reader.GetMethodDefinition)
.First(definition => reader.GetString(definition.Name) == methodName);
byte[] il = pe.GetMethodBody(method.RelativeVirtualAddress).GetILBytes()!;
var operands = ImmutableArray.CreateBuilder<int>();

CopilotAI review requested due to automatic review settings July 29, 2026 19:00
CopilotAI review requested due to automatic review settings August 24, 2026 21:28

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 44 out of 48 changed files in this pull request and generated 4 comments.

Comment threadsrc/tools/ilasm/src/ILAssembler/DocumentCompiler.cs Outdated
Comment threadsrc/tools/ilasm/src/ILAssembler/Options.cs
Comment threadsrc/tools/ilasm/src/ILAssembler/CompilationResult.cs
Comment threadsrc/tools/ilasm/src/ILAssembler/DocumentCompiler.cs
CopilotAI review requested due to automatic review settings August 26, 2026 20:30

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 41 out of 45 changed files in this pull request and generated 3 comments.

Suppressed comments (1)

src/tools/ilasm/src/ILAssembler/EntityRegistry.cs:418

  • The fallback AddMethodBody(...) paths also OR in MethodBodyAttributes.InitLocals when forceFatHeader is true. For the same reason as the main path, this can set InitLocals even when it wasn’t requested; it should be sufficient to pass the existing attributes and use hasDynamicStackAllocation to prevent a tiny header.
 localsSigHandle,
forceFatHeader ? methodDef.BodyAttributes | MethodBodyAttributes.InitLocals : methodDef.BodyAttributes,
hasDynamicStackAllocation: methodDef.HasDynamicStackAllocation || forceFatHeader);

Comment on lines +393 to +404
MethodBodyAttributes encodingAttributes = methodDef.BodyAttributes;
if (forceFatHeader)
{
encodingAttributes |= MethodBodyAttributes.InitLocals;
}

bodyOffset = bodyStreamEncoder.AddMethodBody(
methodDef.MethodBody,
methodDef.MaxStack,
localsSigHandle,
methodDef.BodyAttributes);
encodingAttributes,
methodDef.HasDynamicStackAllocation || forceFatHeader);
Comment threadsrc/tools/ilasm/tests/ILAssembler.Tests/GenericTests.cs
Comment on lines +18 to +29
<PropertyGroup>
<!-- Keep these NativeAOT runtime settings in sync with the first PropertyGroup in AotCompilerCommon.props. -->
<ServerGarbageCollection>true</ServerGarbageCollection>
<TieredCompilation>false</TieredCompilation>
<EventSourceSupport>true</EventSourceSupport>
<OptimizationPreference>Speed</OptimizationPreference>
<ControlFlowGuard>Guard</ControlFlowGuard>
<InvariantGlobalization>true</InvariantGlobalization>
<StripSymbols Condition="'$(KeepNativeSymbols)' == 'true'">false</StripSymbols>
<XmlResolverIsNetworkingEnabledByDefault>false</XmlResolverIsNetworkingEnabledByDefault>
<StackTraceLineNumberSupport>true</StackTraceLineNumberSupport>
</PropertyGroup>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This looks like valid feedback to me. Why do we need to have this copy?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

AotCompilerCommon.props also copies all of the JITs, which was exacerbating some of the CI failures I was seeing on the ilasm pipeline. I'll refactor out AotCompilerCommon.props into an "AotTool.props" that contains the AOT config settings and keep the original file for the info to copy JITs.

CopilotAI review requested due to automatic review settings August 26, 2026 20:46

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 41 out of 45 changed files in this pull request and generated 1 comment.

Comment on lines +524 to 528
for (int ordinal = baseOrdinal; ordinal <= maxOrdinal; ordinal++)
{
int stubIndex = Array.FindIndex(exportsArray, e => e.Ordinal == export.Ordinal);
builder.WriteInt32(exportStubRvas[stubIndex]);
int stubIndex = Array.FindIndex(exportsArray, export => export.Ordinal == ordinal);
builder.WriteInt32(stubIndex >= 0 ? exportStubRvas[stubIndex] : 0);
}
jkoritzinskyand others added 14 commits August 26, 2026 14:31
Use content-based portable PDB IDs for deterministic builds and add in-process coverage for byte-identical PDB output and non-empty PDB ID GUIDs.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2fb9f1ef-f721-49e0-bf48-4a7a9458d53a
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2fb9f1ef-f721-49e0-bf48-4a7a9458d53a
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2fb9f1ef-f721-49e0-bf48-4a7a9458d53a
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2fb9f1ef-f721-49e0-bf48-4a7a9458d53a
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2fb9f1ef-f721-49e0-bf48-4a7a9458d53a
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 106f96fe-da32-41d4-8aa5-7431edb36fc6
…ompiler, it's a compiler that's AOT compiled)
Add feature-focused metadata and PE validation tests and fix emitter issues exposed by them.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 4307156b-37a7-495d-9af6-fe9174c05b0b
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
… attribute encoding
When an object(...) element in an object[] custom attribute had nested
object() wrappers (e.g. object(object(bool(true)))), VisitSerInit's
object() branch would call WriteCustomAttributeFieldOrPropType on the
inner object() context, producing TaggedObject (0x51) as the element
type code. The .NET metadata decoder does not accept 0x51 as a
FieldOrPropType for object[] elements and throws BadImageFormatException.
Fix VisitObjSeq to fully unwrap any object(...) nesting using a while
loop, so that WriteCustomAttributeFieldOrPropType is always called with
the innermost concrete typed element (bool, int32, string, etc.). This
also makes type-byte handling uniform - always done by VisitObjSeq
rather than split between caller and callee.
Add a regression test CustomAttribute_ObjectArrayWithNestedObjectWrapper
_DecodesProperly that exercises object[](object(bool(true)) object(int32
(42))) and verifies the attribute decodes correctly.
Use comma separators between double-quoted GUID arguments so the tests match the supported .language grammar.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: adc580d5-8f1c-4772-bfc2-7a943aa0959d
Pre-size floating-point sequence builders and transfer their arrays without copying. Handle empty floating-point and string sequences and cover their custom attribute encoding.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: adc580d5-8f1c-4772-bfc2-7a943aa0959d
foreach (GenericParameterEntity genericParam in GetSeenEntities(TableIndex.GenericParam))
{
// GenericParam index is stored as a 2-byte value; skip params beyond the limit
// COMPAT: Native ilasm ignores generic parameters whose indices exceed the 2-byte metadata limit.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should this fail with an error instead?

I do not think we need to preserve every native ilasm bug. We should fix these bugs as we run into them.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

My goal was to get us to a clean ilasm round trip run without adding support for a "managed ilasm incompatible" flag. I'll add such a flag for the test case that fails because of this (and revert this compat quirk) so we can review if the test is interesting as-is.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

4 participants

@jkoritzinsky@jkotas@JulieLeeMSFT
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Improve managed ilasm test coverage by jkoritzinsky · Pull Request #131509 · dotnet/runtime · GitHub
Skip to content

Improve managed ilasm test coverage - #131509

Open
jkoritzinsky wants to merge 14 commits into
ilasm-fixupsfrom
ilasm-more-tests
Open

Improve managed ilasm test coverage#131509
jkoritzinsky wants to merge 14 commits into
ilasm-fixupsfrom
ilasm-more-tests

Conversation

@jkoritzinsky

@jkoritzinskyjkoritzinsky commented Jul 28, 2026

Copy link
Copy Markdown
Member

Add feature-focused metadata and PE validation tests and fix emitter issues exposed by them.

With these unit tests (amongst others added in the stack) we can have more confidence in the managed ilasm implementation. In the future, we may even be able to move ilasm round-trip testing to an "outerloop" experience for ilasm instead of being the primary validation pipeline.

This PR also includes fixes and corresponding tests for failures identified with ildasm/ilasm round-trip testing (all except one, which is addressed by #132346).


Stack created with GitHub Stacks CLIGive Feedback 💬

Note

This PR description was generated with GitHub Copilot.

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
16 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

@jkoritzinskyjkoritzinsky changed the title ilasm more testsImprove ILAssembler test coverageJul 28, 2026
@jkoritzinskyjkoritzinsky changed the title Improve ILAssembler test coverageImprove managed ilasm test coverageJul 28, 2026
@jkoritzinsky
jkoritzinsky marked this pull request as ready for review July 28, 2026 23:33
CopilotAI lite review requested due to automatic review settings July 28, 2026 23:33
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
16 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 significantly expands the managed ilasm unit test suite to validate emitted metadata/PE structures (exports, resources, PDBs, signatures, marshalling, etc.), and adjusts the managed ilasm emitter/parser to satisfy the newly-covered scenarios.

Changes:

  • Add many new ILAssembler.Tests cases that decode emitted metadata/PE/PDB and validate specific directives and operand forms.
  • Fix/extend ilasm implementation details in GrammarVisitor (e.g., custom attribute serialization, .module handling, sequence points, callconv explicit/instance) and VTableExportPEBuilder (vtable fixup directory offset + export table layout).
  • Improve test infra helpers to compile IL text and decode IL token operands/signatures more easily.

Reviewed changes

Copilot reviewed 32 out of 32 changed files in this pull request and generated 2 comments.

Show a summary per file
FileDescription
src/tools/ilasm/tests/ILAssembler.Tests/VTableTests.csMinor formatting-only change.
src/tools/ilasm/tests/ILAssembler.Tests/TypeSignatureTests.csAdd tests for multidimensional array local signature shapes.
src/tools/ilasm/tests/ILAssembler.Tests/TypeReferenceTests.csAdd tests for .this/.base/.nester/mdtoken type refs, module-scoped refs, typelist parsing.
src/tools/ilasm/tests/ILAssembler.Tests/TypedefTests.csAdd tests for .typedef aliases for fields and custom attributes.
src/tools/ilasm/tests/ILAssembler.Tests/TypeDefinitionTests.csAdd tests for type name splitting, class flags/attributes, nested types, interface impl metadata.
src/tools/ilasm/tests/ILAssembler.Tests/SourceDirectiveTests.csStrengthen .line/.language coverage and validate emitted embedded PDB details + string escape correctness.
src/tools/ilasm/tests/ILAssembler.Tests/SecurityTests.csAdd extensive .permissionset emission/shape tests (incl. tolerant-mode behavior).
src/tools/ilasm/tests/ILAssembler.Tests/PropertyTests.csAdd property attribute/accessor/signature metadata validation.
src/tools/ilasm/tests/ILAssembler.Tests/PropertyEventTests.csNew test file covering PropertyMap/EventMap + MethodSemantics emission.
src/tools/ilasm/tests/ILAssembler.Tests/PreprocessorIntegrationTests.csNew integration tests for nested includes, conditional compilation, multi-token macros.
src/tools/ilasm/tests/ILAssembler.Tests/ParameterTests.csAdd tests for parameter attribute forms and raw flag parsing.
src/tools/ilasm/tests/ILAssembler.Tests/NativeExportTests.csNew tests validating when exports are (not) emitted and verifying export directory/stubs.
src/tools/ilasm/tests/ILAssembler.Tests/ModuleTests.csAdd tests for .file, .module extern, bare .module, and global method/module metadata + PDB.
src/tools/ilasm/tests/ILAssembler.Tests/MethodTests.csAdd tests for method attributes/impl flags, method body directives, entrypoint token, override forms.
src/tools/ilasm/tests/ILAssembler.Tests/MemberReferenceTests.csAdd tests for vararg MemberRef signatures, generic-instantiation MemberRefs, method spec emission.
src/tools/ilasm/tests/ILAssembler.Tests/ManifestResourceTests.csNew tests for embedded/assembly/file-backed manifest resources + tolerant/deterministic behaviors.
src/tools/ilasm/tests/ILAssembler.Tests/InteropTests.csAdd marshalling and P/Invoke import metadata tests (incl. complex native type payloads).
src/tools/ilasm/tests/ILAssembler.Tests/InstructionTests.csAdd coverage for float bit-pattern literals, calli sigs, ldstr forms, switch table forms, token operands.
src/tools/ilasm/tests/ILAssembler.Tests/GenericTests.csAdd generic parameter name/bounds/variance/custom attribute/constraint metadata tests.
src/tools/ilasm/tests/ILAssembler.Tests/FunctionPointerTests.csUpdate function pointer signature assertions to use decoded signatures; add vararg fnptr test.
src/tools/ilasm/tests/ILAssembler.Tests/FieldTests.csAdd tests for field attribute flags, volatile/literal/nullref constant emission.
src/tools/ilasm/tests/ILAssembler.Tests/ExportedTypeTests.csAdd tests for exported type attributes/implementations + custom attributes.
src/tools/ilasm/tests/ILAssembler.Tests/ExceptionHandlingTests.csAdd tests validating EH region bounds/kinds for multiple clause forms.
src/tools/ilasm/tests/ILAssembler.Tests/EventTests.csAdd tests for event raise accessor, event “other” accessor, and attribute emission.
src/tools/ilasm/tests/ILAssembler.Tests/DocumentCompilerTests.csNew test validating diagnostics pathing across multi-document compilation in tolerant mode.
src/tools/ilasm/tests/ILAssembler.Tests/DocumentCompilerTestHelpers.csAdd decoder + richer compile helpers and IL token operand extraction.
src/tools/ilasm/tests/ILAssembler.Tests/DataTests.csAdd tests for .data directive typed byte emission, repeats, and class-scoped .data.
src/tools/ilasm/tests/ILAssembler.Tests/CustomAttributeTests.csAdd broad structured custom attribute decoding tests (arrays, boxed values, owner targeting, type args).
src/tools/ilasm/tests/ILAssembler.Tests/CompilerOptionsTests.csNew tests validating Options-driven PE/header/corflags/debug/pdb/determinism/keyfile behaviors.
src/tools/ilasm/tests/ILAssembler.Tests/AssemblyTests.csAdd tests for assembly reference identity metadata and aliased reference/assembly attributes.
src/tools/ilasm/src/ILAssembler/VTableExportPEBuilder.csFix COR header vtable fixup directory offset; refactor vtable slot serialization and export table layout.
src/tools/ilasm/src/ILAssembler/GrammarVisitor.csNumerous parser/emitter fixes to support new metadata/PDB/custom-attribute/directive scenarios.
Comments suppressed due to low confidence (1)

src/tools/ilasm/src/ILAssembler/GrammarVisitor.cs:2924

  • Same as above: ToImmutable() copies; MoveToImmutable() can transfer the backing array without allocating, which is preferable in a potentially hot parsing path.
 return new(builder.ToImmutable().SerializeSequence());

Comment threadsrc/tools/ilasm/src/ILAssembler/GrammarVisitor.cs Outdated
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

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

CopilotAI review requested due to automatic review settings July 29, 2026 00:01

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 32 out of 32 changed files in this pull request and generated no new comments.

CopilotAI review requested due to automatic review settings July 29, 2026 00:07

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 32 out of 32 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (3)

src/tools/ilasm/tests/ILAssembler.Tests/TypeSignatureTests.cs:92

  • This test assumes the locals signature is always StandAloneSig row 1. Using the method body's LocalSignature handle avoids tying the assertion to metadata row ordering.
 var signature = reader.GetStandaloneSignature(MetadataTokens.StandaloneSignatureHandle(1));

src/tools/ilasm/tests/ILAssembler.Tests/TypeSignatureTests.cs:125

  • Hard-coding StandaloneSignatureHandle(1) here couples the test to metadata emission order. Use the method body's LocalSignature to make the test robust against unrelated StandAloneSig additions.
 var signature = reader.GetStandaloneSignature(MetadataTokens.StandaloneSignatureHandle(1));

src/tools/ilasm/tests/ILAssembler.Tests/TypeSignatureTests.cs:66

  • This test hard-codes StandaloneSignatureHandle(1), which makes it brittle if the compiler ever emits another StandAloneSig row before the locals signature. Prefer using the method body's LocalSignature handle so the test is resilient to unrelated metadata changes.

This issue also appears in the following locations of the same file:

  • line 92
  • line 125
 var signature = reader.GetStandaloneSignature(MetadataTokens.StandaloneSignatureHandle(1));

CopilotAI review requested due to automatic review settings July 29, 2026 00:34

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 32 out of 32 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (1)

src/tools/ilasm/src/ILAssembler/GrammarVisitor.cs:5573

  • In structured custom attribute encoding, a boxed object(...) value must include the SerializationTypeCode.TaggedObject (0x51) prefix, followed by the embedded value’s FieldOrPropType and value bytes. The current object(...) branch writes only the embedded type/value and omits the TaggedObject prefix, which will make decoding object arguments invalid (and can break object[] element encoding too).
 if (context.serInit() is CILParser.SerInitContext serInit)
{
Debug.Assert(context.OBJECT() is not null);
BlobBuilder taggedObjectBlob = new();
WriteCustomAttributeFieldOrPropType(taggedObjectBlob, serInit);
taggedObjectBlob.LinkSuffix(VisitSerInit(serInit).Value);
return new(taggedObjectBlob);

Comment threadsrc/tools/ilasm/src/ILAssembler/GrammarVisitor.cs
CopilotAI review requested due to automatic review settings July 29, 2026 00:44

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 32 out of 32 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (1)

src/tools/ilasm/tests/ILAssembler.Tests/DocumentCompilerTestHelpers.cs:123

  • GetTokenOperands reads the method body without validating RelativeVirtualAddress > 0, so callers get an exception from PEReader.GetMethodBody instead of a clear test failure message when the target method has no body (e.g., runtime/abstract methods). This helper already has a good pattern in GetFirstTokenOperand; it should mirror that assert for consistency and debuggability.
 var method = reader.MethodDefinitions
.Select(reader.GetMethodDefinition)
.First(definition => reader.GetString(definition.Name) == methodName);
byte[] il = pe.GetMethodBody(method.RelativeVirtualAddress).GetILBytes()!;
var operands = ImmutableArray.CreateBuilder<int>();

CopilotAI review requested due to automatic review settings July 29, 2026 19:00
CopilotAI review requested due to automatic review settings August 24, 2026 21:28

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 44 out of 48 changed files in this pull request and generated 4 comments.

Comment threadsrc/tools/ilasm/src/ILAssembler/DocumentCompiler.cs Outdated
Comment threadsrc/tools/ilasm/src/ILAssembler/Options.cs
Comment threadsrc/tools/ilasm/src/ILAssembler/CompilationResult.cs
Comment threadsrc/tools/ilasm/src/ILAssembler/DocumentCompiler.cs
CopilotAI review requested due to automatic review settings August 26, 2026 20:30

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 41 out of 45 changed files in this pull request and generated 3 comments.

Suppressed comments (1)

src/tools/ilasm/src/ILAssembler/EntityRegistry.cs:418

  • The fallback AddMethodBody(...) paths also OR in MethodBodyAttributes.InitLocals when forceFatHeader is true. For the same reason as the main path, this can set InitLocals even when it wasn’t requested; it should be sufficient to pass the existing attributes and use hasDynamicStackAllocation to prevent a tiny header.
 localsSigHandle,
forceFatHeader ? methodDef.BodyAttributes | MethodBodyAttributes.InitLocals : methodDef.BodyAttributes,
hasDynamicStackAllocation: methodDef.HasDynamicStackAllocation || forceFatHeader);

Comment on lines +393 to +404
MethodBodyAttributes encodingAttributes = methodDef.BodyAttributes;
if (forceFatHeader)
{
encodingAttributes |= MethodBodyAttributes.InitLocals;
}

bodyOffset = bodyStreamEncoder.AddMethodBody(
methodDef.MethodBody,
methodDef.MaxStack,
localsSigHandle,
methodDef.BodyAttributes);
encodingAttributes,
methodDef.HasDynamicStackAllocation || forceFatHeader);
Comment threadsrc/tools/ilasm/tests/ILAssembler.Tests/GenericTests.cs
Comment on lines +18 to +29
<PropertyGroup>
<!-- Keep these NativeAOT runtime settings in sync with the first PropertyGroup in AotCompilerCommon.props. -->
<ServerGarbageCollection>true</ServerGarbageCollection>
<TieredCompilation>false</TieredCompilation>
<EventSourceSupport>true</EventSourceSupport>
<OptimizationPreference>Speed</OptimizationPreference>
<ControlFlowGuard>Guard</ControlFlowGuard>
<InvariantGlobalization>true</InvariantGlobalization>
<StripSymbols Condition="'$(KeepNativeSymbols)' == 'true'">false</StripSymbols>
<XmlResolverIsNetworkingEnabledByDefault>false</XmlResolverIsNetworkingEnabledByDefault>
<StackTraceLineNumberSupport>true</StackTraceLineNumberSupport>
</PropertyGroup>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This looks like valid feedback to me. Why do we need to have this copy?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

AotCompilerCommon.props also copies all of the JITs, which was exacerbating some of the CI failures I was seeing on the ilasm pipeline. I'll refactor out AotCompilerCommon.props into an "AotTool.props" that contains the AOT config settings and keep the original file for the info to copy JITs.

CopilotAI review requested due to automatic review settings August 26, 2026 20:46

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 41 out of 45 changed files in this pull request and generated 1 comment.

Comment on lines +524 to 528
for (int ordinal = baseOrdinal; ordinal <= maxOrdinal; ordinal++)
{
int stubIndex = Array.FindIndex(exportsArray, e => e.Ordinal == export.Ordinal);
builder.WriteInt32(exportStubRvas[stubIndex]);
int stubIndex = Array.FindIndex(exportsArray, export => export.Ordinal == ordinal);
builder.WriteInt32(stubIndex >= 0 ? exportStubRvas[stubIndex] : 0);
}
jkoritzinskyand others added 14 commits August 26, 2026 14:31
Use content-based portable PDB IDs for deterministic builds and add in-process coverage for byte-identical PDB output and non-empty PDB ID GUIDs.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2fb9f1ef-f721-49e0-bf48-4a7a9458d53a
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2fb9f1ef-f721-49e0-bf48-4a7a9458d53a
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2fb9f1ef-f721-49e0-bf48-4a7a9458d53a
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2fb9f1ef-f721-49e0-bf48-4a7a9458d53a
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2fb9f1ef-f721-49e0-bf48-4a7a9458d53a
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 106f96fe-da32-41d4-8aa5-7431edb36fc6
…ompiler, it's a compiler that's AOT compiled)
Add feature-focused metadata and PE validation tests and fix emitter issues exposed by them.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 4307156b-37a7-495d-9af6-fe9174c05b0b
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
… attribute encoding
When an object(...) element in an object[] custom attribute had nested
object() wrappers (e.g. object(object(bool(true)))), VisitSerInit's
object() branch would call WriteCustomAttributeFieldOrPropType on the
inner object() context, producing TaggedObject (0x51) as the element
type code. The .NET metadata decoder does not accept 0x51 as a
FieldOrPropType for object[] elements and throws BadImageFormatException.
Fix VisitObjSeq to fully unwrap any object(...) nesting using a while
loop, so that WriteCustomAttributeFieldOrPropType is always called with
the innermost concrete typed element (bool, int32, string, etc.). This
also makes type-byte handling uniform - always done by VisitObjSeq
rather than split between caller and callee.
Add a regression test CustomAttribute_ObjectArrayWithNestedObjectWrapper
_DecodesProperly that exercises object[](object(bool(true)) object(int32
(42))) and verifies the attribute decodes correctly.
Use comma separators between double-quoted GUID arguments so the tests match the supported .language grammar.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: adc580d5-8f1c-4772-bfc2-7a943aa0959d
Pre-size floating-point sequence builders and transfer their arrays without copying. Handle empty floating-point and string sequences and cover their custom attribute encoding.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: adc580d5-8f1c-4772-bfc2-7a943aa0959d
foreach (GenericParameterEntity genericParam in GetSeenEntities(TableIndex.GenericParam))
{
// GenericParam index is stored as a 2-byte value; skip params beyond the limit
// COMPAT: Native ilasm ignores generic parameters whose indices exceed the 2-byte metadata limit.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should this fail with an error instead?

I do not think we need to preserve every native ilasm bug. We should fix these bugs as we run into them.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

My goal was to get us to a clean ilasm round trip run without adding support for a "managed ilasm incompatible" flag. I'll add such a flag for the test case that fails because of this (and revert this compat quirk) so we can review if the test is interesting as-is.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

4 participants

@jkoritzinsky@jkotas@JulieLeeMSFT
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Improve managed ilasm test coverage by jkoritzinsky · Pull Request #131509 · dotnet/runtime · GitHub
Skip to content

Improve managed ilasm test coverage - #131509

Open
jkoritzinsky wants to merge 14 commits into
ilasm-fixupsfrom
ilasm-more-tests
Open

Improve managed ilasm test coverage#131509
jkoritzinsky wants to merge 14 commits into
ilasm-fixupsfrom
ilasm-more-tests

Conversation

@jkoritzinsky

@jkoritzinskyjkoritzinsky commented Jul 28, 2026

Copy link
Copy Markdown
Member

Add feature-focused metadata and PE validation tests and fix emitter issues exposed by them.

With these unit tests (amongst others added in the stack) we can have more confidence in the managed ilasm implementation. In the future, we may even be able to move ilasm round-trip testing to an "outerloop" experience for ilasm instead of being the primary validation pipeline.

This PR also includes fixes and corresponding tests for failures identified with ildasm/ilasm round-trip testing (all except one, which is addressed by #132346).


Stack created with GitHub Stacks CLIGive Feedback 💬

Note

This PR description was generated with GitHub Copilot.

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
16 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

@jkoritzinskyjkoritzinsky changed the title ilasm more testsImprove ILAssembler test coverageJul 28, 2026
@jkoritzinskyjkoritzinsky changed the title Improve ILAssembler test coverageImprove managed ilasm test coverageJul 28, 2026
@jkoritzinsky
jkoritzinsky marked this pull request as ready for review July 28, 2026 23:33
CopilotAI lite review requested due to automatic review settings July 28, 2026 23:33
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
16 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 significantly expands the managed ilasm unit test suite to validate emitted metadata/PE structures (exports, resources, PDBs, signatures, marshalling, etc.), and adjusts the managed ilasm emitter/parser to satisfy the newly-covered scenarios.

Changes:

  • Add many new ILAssembler.Tests cases that decode emitted metadata/PE/PDB and validate specific directives and operand forms.
  • Fix/extend ilasm implementation details in GrammarVisitor (e.g., custom attribute serialization, .module handling, sequence points, callconv explicit/instance) and VTableExportPEBuilder (vtable fixup directory offset + export table layout).
  • Improve test infra helpers to compile IL text and decode IL token operands/signatures more easily.

Reviewed changes

Copilot reviewed 32 out of 32 changed files in this pull request and generated 2 comments.

Show a summary per file
FileDescription
src/tools/ilasm/tests/ILAssembler.Tests/VTableTests.csMinor formatting-only change.
src/tools/ilasm/tests/ILAssembler.Tests/TypeSignatureTests.csAdd tests for multidimensional array local signature shapes.
src/tools/ilasm/tests/ILAssembler.Tests/TypeReferenceTests.csAdd tests for .this/.base/.nester/mdtoken type refs, module-scoped refs, typelist parsing.
src/tools/ilasm/tests/ILAssembler.Tests/TypedefTests.csAdd tests for .typedef aliases for fields and custom attributes.
src/tools/ilasm/tests/ILAssembler.Tests/TypeDefinitionTests.csAdd tests for type name splitting, class flags/attributes, nested types, interface impl metadata.
src/tools/ilasm/tests/ILAssembler.Tests/SourceDirectiveTests.csStrengthen .line/.language coverage and validate emitted embedded PDB details + string escape correctness.
src/tools/ilasm/tests/ILAssembler.Tests/SecurityTests.csAdd extensive .permissionset emission/shape tests (incl. tolerant-mode behavior).
src/tools/ilasm/tests/ILAssembler.Tests/PropertyTests.csAdd property attribute/accessor/signature metadata validation.
src/tools/ilasm/tests/ILAssembler.Tests/PropertyEventTests.csNew test file covering PropertyMap/EventMap + MethodSemantics emission.
src/tools/ilasm/tests/ILAssembler.Tests/PreprocessorIntegrationTests.csNew integration tests for nested includes, conditional compilation, multi-token macros.
src/tools/ilasm/tests/ILAssembler.Tests/ParameterTests.csAdd tests for parameter attribute forms and raw flag parsing.
src/tools/ilasm/tests/ILAssembler.Tests/NativeExportTests.csNew tests validating when exports are (not) emitted and verifying export directory/stubs.
src/tools/ilasm/tests/ILAssembler.Tests/ModuleTests.csAdd tests for .file, .module extern, bare .module, and global method/module metadata + PDB.
src/tools/ilasm/tests/ILAssembler.Tests/MethodTests.csAdd tests for method attributes/impl flags, method body directives, entrypoint token, override forms.
src/tools/ilasm/tests/ILAssembler.Tests/MemberReferenceTests.csAdd tests for vararg MemberRef signatures, generic-instantiation MemberRefs, method spec emission.
src/tools/ilasm/tests/ILAssembler.Tests/ManifestResourceTests.csNew tests for embedded/assembly/file-backed manifest resources + tolerant/deterministic behaviors.
src/tools/ilasm/tests/ILAssembler.Tests/InteropTests.csAdd marshalling and P/Invoke import metadata tests (incl. complex native type payloads).
src/tools/ilasm/tests/ILAssembler.Tests/InstructionTests.csAdd coverage for float bit-pattern literals, calli sigs, ldstr forms, switch table forms, token operands.
src/tools/ilasm/tests/ILAssembler.Tests/GenericTests.csAdd generic parameter name/bounds/variance/custom attribute/constraint metadata tests.
src/tools/ilasm/tests/ILAssembler.Tests/FunctionPointerTests.csUpdate function pointer signature assertions to use decoded signatures; add vararg fnptr test.
src/tools/ilasm/tests/ILAssembler.Tests/FieldTests.csAdd tests for field attribute flags, volatile/literal/nullref constant emission.
src/tools/ilasm/tests/ILAssembler.Tests/ExportedTypeTests.csAdd tests for exported type attributes/implementations + custom attributes.
src/tools/ilasm/tests/ILAssembler.Tests/ExceptionHandlingTests.csAdd tests validating EH region bounds/kinds for multiple clause forms.
src/tools/ilasm/tests/ILAssembler.Tests/EventTests.csAdd tests for event raise accessor, event “other” accessor, and attribute emission.
src/tools/ilasm/tests/ILAssembler.Tests/DocumentCompilerTests.csNew test validating diagnostics pathing across multi-document compilation in tolerant mode.
src/tools/ilasm/tests/ILAssembler.Tests/DocumentCompilerTestHelpers.csAdd decoder + richer compile helpers and IL token operand extraction.
src/tools/ilasm/tests/ILAssembler.Tests/DataTests.csAdd tests for .data directive typed byte emission, repeats, and class-scoped .data.
src/tools/ilasm/tests/ILAssembler.Tests/CustomAttributeTests.csAdd broad structured custom attribute decoding tests (arrays, boxed values, owner targeting, type args).
src/tools/ilasm/tests/ILAssembler.Tests/CompilerOptionsTests.csNew tests validating Options-driven PE/header/corflags/debug/pdb/determinism/keyfile behaviors.
src/tools/ilasm/tests/ILAssembler.Tests/AssemblyTests.csAdd tests for assembly reference identity metadata and aliased reference/assembly attributes.
src/tools/ilasm/src/ILAssembler/VTableExportPEBuilder.csFix COR header vtable fixup directory offset; refactor vtable slot serialization and export table layout.
src/tools/ilasm/src/ILAssembler/GrammarVisitor.csNumerous parser/emitter fixes to support new metadata/PDB/custom-attribute/directive scenarios.
Comments suppressed due to low confidence (1)

src/tools/ilasm/src/ILAssembler/GrammarVisitor.cs:2924

  • Same as above: ToImmutable() copies; MoveToImmutable() can transfer the backing array without allocating, which is preferable in a potentially hot parsing path.
 return new(builder.ToImmutable().SerializeSequence());

Comment threadsrc/tools/ilasm/src/ILAssembler/GrammarVisitor.cs Outdated
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

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

CopilotAI review requested due to automatic review settings July 29, 2026 00:01

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 32 out of 32 changed files in this pull request and generated no new comments.

CopilotAI review requested due to automatic review settings July 29, 2026 00:07

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 32 out of 32 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (3)

src/tools/ilasm/tests/ILAssembler.Tests/TypeSignatureTests.cs:92

  • This test assumes the locals signature is always StandAloneSig row 1. Using the method body's LocalSignature handle avoids tying the assertion to metadata row ordering.
 var signature = reader.GetStandaloneSignature(MetadataTokens.StandaloneSignatureHandle(1));

src/tools/ilasm/tests/ILAssembler.Tests/TypeSignatureTests.cs:125

  • Hard-coding StandaloneSignatureHandle(1) here couples the test to metadata emission order. Use the method body's LocalSignature to make the test robust against unrelated StandAloneSig additions.
 var signature = reader.GetStandaloneSignature(MetadataTokens.StandaloneSignatureHandle(1));

src/tools/ilasm/tests/ILAssembler.Tests/TypeSignatureTests.cs:66

  • This test hard-codes StandaloneSignatureHandle(1), which makes it brittle if the compiler ever emits another StandAloneSig row before the locals signature. Prefer using the method body's LocalSignature handle so the test is resilient to unrelated metadata changes.

This issue also appears in the following locations of the same file:

  • line 92
  • line 125
 var signature = reader.GetStandaloneSignature(MetadataTokens.StandaloneSignatureHandle(1));

CopilotAI review requested due to automatic review settings July 29, 2026 00:34

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 32 out of 32 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (1)

src/tools/ilasm/src/ILAssembler/GrammarVisitor.cs:5573

  • In structured custom attribute encoding, a boxed object(...) value must include the SerializationTypeCode.TaggedObject (0x51) prefix, followed by the embedded value’s FieldOrPropType and value bytes. The current object(...) branch writes only the embedded type/value and omits the TaggedObject prefix, which will make decoding object arguments invalid (and can break object[] element encoding too).
 if (context.serInit() is CILParser.SerInitContext serInit)
{
Debug.Assert(context.OBJECT() is not null);
BlobBuilder taggedObjectBlob = new();
WriteCustomAttributeFieldOrPropType(taggedObjectBlob, serInit);
taggedObjectBlob.LinkSuffix(VisitSerInit(serInit).Value);
return new(taggedObjectBlob);

Comment threadsrc/tools/ilasm/src/ILAssembler/GrammarVisitor.cs
CopilotAI review requested due to automatic review settings July 29, 2026 00:44

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 32 out of 32 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (1)

src/tools/ilasm/tests/ILAssembler.Tests/DocumentCompilerTestHelpers.cs:123

  • GetTokenOperands reads the method body without validating RelativeVirtualAddress > 0, so callers get an exception from PEReader.GetMethodBody instead of a clear test failure message when the target method has no body (e.g., runtime/abstract methods). This helper already has a good pattern in GetFirstTokenOperand; it should mirror that assert for consistency and debuggability.
 var method = reader.MethodDefinitions
.Select(reader.GetMethodDefinition)
.First(definition => reader.GetString(definition.Name) == methodName);
byte[] il = pe.GetMethodBody(method.RelativeVirtualAddress).GetILBytes()!;
var operands = ImmutableArray.CreateBuilder<int>();

CopilotAI review requested due to automatic review settings July 29, 2026 19:00
CopilotAI review requested due to automatic review settings August 24, 2026 21:28

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 44 out of 48 changed files in this pull request and generated 4 comments.

Comment threadsrc/tools/ilasm/src/ILAssembler/DocumentCompiler.cs Outdated
Comment threadsrc/tools/ilasm/src/ILAssembler/Options.cs
Comment threadsrc/tools/ilasm/src/ILAssembler/CompilationResult.cs
Comment threadsrc/tools/ilasm/src/ILAssembler/DocumentCompiler.cs
CopilotAI review requested due to automatic review settings August 26, 2026 20:30

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 41 out of 45 changed files in this pull request and generated 3 comments.

Suppressed comments (1)

src/tools/ilasm/src/ILAssembler/EntityRegistry.cs:418

  • The fallback AddMethodBody(...) paths also OR in MethodBodyAttributes.InitLocals when forceFatHeader is true. For the same reason as the main path, this can set InitLocals even when it wasn’t requested; it should be sufficient to pass the existing attributes and use hasDynamicStackAllocation to prevent a tiny header.
 localsSigHandle,
forceFatHeader ? methodDef.BodyAttributes | MethodBodyAttributes.InitLocals : methodDef.BodyAttributes,
hasDynamicStackAllocation: methodDef.HasDynamicStackAllocation || forceFatHeader);

Comment on lines +393 to +404
MethodBodyAttributes encodingAttributes = methodDef.BodyAttributes;
if (forceFatHeader)
{
encodingAttributes |= MethodBodyAttributes.InitLocals;
}

bodyOffset = bodyStreamEncoder.AddMethodBody(
methodDef.MethodBody,
methodDef.MaxStack,
localsSigHandle,
methodDef.BodyAttributes);
encodingAttributes,
methodDef.HasDynamicStackAllocation || forceFatHeader);
Comment threadsrc/tools/ilasm/tests/ILAssembler.Tests/GenericTests.cs
Comment on lines +18 to +29
<PropertyGroup>
<!-- Keep these NativeAOT runtime settings in sync with the first PropertyGroup in AotCompilerCommon.props. -->
<ServerGarbageCollection>true</ServerGarbageCollection>
<TieredCompilation>false</TieredCompilation>
<EventSourceSupport>true</EventSourceSupport>
<OptimizationPreference>Speed</OptimizationPreference>
<ControlFlowGuard>Guard</ControlFlowGuard>
<InvariantGlobalization>true</InvariantGlobalization>
<StripSymbols Condition="'$(KeepNativeSymbols)' == 'true'">false</StripSymbols>
<XmlResolverIsNetworkingEnabledByDefault>false</XmlResolverIsNetworkingEnabledByDefault>
<StackTraceLineNumberSupport>true</StackTraceLineNumberSupport>
</PropertyGroup>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This looks like valid feedback to me. Why do we need to have this copy?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

AotCompilerCommon.props also copies all of the JITs, which was exacerbating some of the CI failures I was seeing on the ilasm pipeline. I'll refactor out AotCompilerCommon.props into an "AotTool.props" that contains the AOT config settings and keep the original file for the info to copy JITs.

CopilotAI review requested due to automatic review settings August 26, 2026 20:46

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 41 out of 45 changed files in this pull request and generated 1 comment.

Comment on lines +524 to 528
for (int ordinal = baseOrdinal; ordinal <= maxOrdinal; ordinal++)
{
int stubIndex = Array.FindIndex(exportsArray, e => e.Ordinal == export.Ordinal);
builder.WriteInt32(exportStubRvas[stubIndex]);
int stubIndex = Array.FindIndex(exportsArray, export => export.Ordinal == ordinal);
builder.WriteInt32(stubIndex >= 0 ? exportStubRvas[stubIndex] : 0);
}
jkoritzinskyand others added 14 commits August 26, 2026 14:31
Use content-based portable PDB IDs for deterministic builds and add in-process coverage for byte-identical PDB output and non-empty PDB ID GUIDs.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2fb9f1ef-f721-49e0-bf48-4a7a9458d53a
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2fb9f1ef-f721-49e0-bf48-4a7a9458d53a
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2fb9f1ef-f721-49e0-bf48-4a7a9458d53a
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2fb9f1ef-f721-49e0-bf48-4a7a9458d53a
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2fb9f1ef-f721-49e0-bf48-4a7a9458d53a
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 106f96fe-da32-41d4-8aa5-7431edb36fc6
…ompiler, it's a compiler that's AOT compiled)
Add feature-focused metadata and PE validation tests and fix emitter issues exposed by them.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 4307156b-37a7-495d-9af6-fe9174c05b0b
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
… attribute encoding
When an object(...) element in an object[] custom attribute had nested
object() wrappers (e.g. object(object(bool(true)))), VisitSerInit's
object() branch would call WriteCustomAttributeFieldOrPropType on the
inner object() context, producing TaggedObject (0x51) as the element
type code. The .NET metadata decoder does not accept 0x51 as a
FieldOrPropType for object[] elements and throws BadImageFormatException.
Fix VisitObjSeq to fully unwrap any object(...) nesting using a while
loop, so that WriteCustomAttributeFieldOrPropType is always called with
the innermost concrete typed element (bool, int32, string, etc.). This
also makes type-byte handling uniform - always done by VisitObjSeq
rather than split between caller and callee.
Add a regression test CustomAttribute_ObjectArrayWithNestedObjectWrapper
_DecodesProperly that exercises object[](object(bool(true)) object(int32
(42))) and verifies the attribute decodes correctly.
Use comma separators between double-quoted GUID arguments so the tests match the supported .language grammar.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: adc580d5-8f1c-4772-bfc2-7a943aa0959d
Pre-size floating-point sequence builders and transfer their arrays without copying. Handle empty floating-point and string sequences and cover their custom attribute encoding.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: adc580d5-8f1c-4772-bfc2-7a943aa0959d
foreach (GenericParameterEntity genericParam in GetSeenEntities(TableIndex.GenericParam))
{
// GenericParam index is stored as a 2-byte value; skip params beyond the limit
// COMPAT: Native ilasm ignores generic parameters whose indices exceed the 2-byte metadata limit.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should this fail with an error instead?

I do not think we need to preserve every native ilasm bug. We should fix these bugs as we run into them.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

My goal was to get us to a clean ilasm round trip run without adding support for a "managed ilasm incompatible" flag. I'll add such a flag for the test case that fails because of this (and revert this compat quirk) so we can review if the test is interesting as-is.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

4 participants

@jkoritzinsky@jkotas@JulieLeeMSFT
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' Improve managed ilasm test coverage by jkoritzinsky · Pull Request #131509 · dotnet/runtime · GitHub
Skip to content

Improve managed ilasm test coverage - #131509

Open
jkoritzinsky wants to merge 14 commits into
ilasm-fixupsfrom
ilasm-more-tests
Open

Improve managed ilasm test coverage#131509
jkoritzinsky wants to merge 14 commits into
ilasm-fixupsfrom
ilasm-more-tests

Conversation

@jkoritzinsky

@jkoritzinskyjkoritzinsky commented Jul 28, 2026

Copy link
Copy Markdown
Member

Add feature-focused metadata and PE validation tests and fix emitter issues exposed by them.

With these unit tests (amongst others added in the stack) we can have more confidence in the managed ilasm implementation. In the future, we may even be able to move ilasm round-trip testing to an "outerloop" experience for ilasm instead of being the primary validation pipeline.

This PR also includes fixes and corresponding tests for failures identified with ildasm/ilasm round-trip testing (all except one, which is addressed by #132346).


Stack created with GitHub Stacks CLIGive Feedback 💬

Note

This PR description was generated with GitHub Copilot.

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
16 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

@jkoritzinskyjkoritzinsky changed the title ilasm more testsImprove ILAssembler test coverageJul 28, 2026
@jkoritzinskyjkoritzinsky changed the title Improve ILAssembler test coverageImprove managed ilasm test coverageJul 28, 2026
@jkoritzinsky
jkoritzinsky marked this pull request as ready for review July 28, 2026 23:33
CopilotAI lite review requested due to automatic review settings July 28, 2026 23:33
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
16 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 significantly expands the managed ilasm unit test suite to validate emitted metadata/PE structures (exports, resources, PDBs, signatures, marshalling, etc.), and adjusts the managed ilasm emitter/parser to satisfy the newly-covered scenarios.

Changes:

  • Add many new ILAssembler.Tests cases that decode emitted metadata/PE/PDB and validate specific directives and operand forms.
  • Fix/extend ilasm implementation details in GrammarVisitor (e.g., custom attribute serialization, .module handling, sequence points, callconv explicit/instance) and VTableExportPEBuilder (vtable fixup directory offset + export table layout).
  • Improve test infra helpers to compile IL text and decode IL token operands/signatures more easily.

Reviewed changes

Copilot reviewed 32 out of 32 changed files in this pull request and generated 2 comments.

Show a summary per file
FileDescription
src/tools/ilasm/tests/ILAssembler.Tests/VTableTests.csMinor formatting-only change.
src/tools/ilasm/tests/ILAssembler.Tests/TypeSignatureTests.csAdd tests for multidimensional array local signature shapes.
src/tools/ilasm/tests/ILAssembler.Tests/TypeReferenceTests.csAdd tests for .this/.base/.nester/mdtoken type refs, module-scoped refs, typelist parsing.
src/tools/ilasm/tests/ILAssembler.Tests/TypedefTests.csAdd tests for .typedef aliases for fields and custom attributes.
src/tools/ilasm/tests/ILAssembler.Tests/TypeDefinitionTests.csAdd tests for type name splitting, class flags/attributes, nested types, interface impl metadata.
src/tools/ilasm/tests/ILAssembler.Tests/SourceDirectiveTests.csStrengthen .line/.language coverage and validate emitted embedded PDB details + string escape correctness.
src/tools/ilasm/tests/ILAssembler.Tests/SecurityTests.csAdd extensive .permissionset emission/shape tests (incl. tolerant-mode behavior).
src/tools/ilasm/tests/ILAssembler.Tests/PropertyTests.csAdd property attribute/accessor/signature metadata validation.
src/tools/ilasm/tests/ILAssembler.Tests/PropertyEventTests.csNew test file covering PropertyMap/EventMap + MethodSemantics emission.
src/tools/ilasm/tests/ILAssembler.Tests/PreprocessorIntegrationTests.csNew integration tests for nested includes, conditional compilation, multi-token macros.
src/tools/ilasm/tests/ILAssembler.Tests/ParameterTests.csAdd tests for parameter attribute forms and raw flag parsing.
src/tools/ilasm/tests/ILAssembler.Tests/NativeExportTests.csNew tests validating when exports are (not) emitted and verifying export directory/stubs.
src/tools/ilasm/tests/ILAssembler.Tests/ModuleTests.csAdd tests for .file, .module extern, bare .module, and global method/module metadata + PDB.
src/tools/ilasm/tests/ILAssembler.Tests/MethodTests.csAdd tests for method attributes/impl flags, method body directives, entrypoint token, override forms.
src/tools/ilasm/tests/ILAssembler.Tests/MemberReferenceTests.csAdd tests for vararg MemberRef signatures, generic-instantiation MemberRefs, method spec emission.
src/tools/ilasm/tests/ILAssembler.Tests/ManifestResourceTests.csNew tests for embedded/assembly/file-backed manifest resources + tolerant/deterministic behaviors.
src/tools/ilasm/tests/ILAssembler.Tests/InteropTests.csAdd marshalling and P/Invoke import metadata tests (incl. complex native type payloads).
src/tools/ilasm/tests/ILAssembler.Tests/InstructionTests.csAdd coverage for float bit-pattern literals, calli sigs, ldstr forms, switch table forms, token operands.
src/tools/ilasm/tests/ILAssembler.Tests/GenericTests.csAdd generic parameter name/bounds/variance/custom attribute/constraint metadata tests.
src/tools/ilasm/tests/ILAssembler.Tests/FunctionPointerTests.csUpdate function pointer signature assertions to use decoded signatures; add vararg fnptr test.
src/tools/ilasm/tests/ILAssembler.Tests/FieldTests.csAdd tests for field attribute flags, volatile/literal/nullref constant emission.
src/tools/ilasm/tests/ILAssembler.Tests/ExportedTypeTests.csAdd tests for exported type attributes/implementations + custom attributes.
src/tools/ilasm/tests/ILAssembler.Tests/ExceptionHandlingTests.csAdd tests validating EH region bounds/kinds for multiple clause forms.
src/tools/ilasm/tests/ILAssembler.Tests/EventTests.csAdd tests for event raise accessor, event “other” accessor, and attribute emission.
src/tools/ilasm/tests/ILAssembler.Tests/DocumentCompilerTests.csNew test validating diagnostics pathing across multi-document compilation in tolerant mode.
src/tools/ilasm/tests/ILAssembler.Tests/DocumentCompilerTestHelpers.csAdd decoder + richer compile helpers and IL token operand extraction.
src/tools/ilasm/tests/ILAssembler.Tests/DataTests.csAdd tests for .data directive typed byte emission, repeats, and class-scoped .data.
src/tools/ilasm/tests/ILAssembler.Tests/CustomAttributeTests.csAdd broad structured custom attribute decoding tests (arrays, boxed values, owner targeting, type args).
src/tools/ilasm/tests/ILAssembler.Tests/CompilerOptionsTests.csNew tests validating Options-driven PE/header/corflags/debug/pdb/determinism/keyfile behaviors.
src/tools/ilasm/tests/ILAssembler.Tests/AssemblyTests.csAdd tests for assembly reference identity metadata and aliased reference/assembly attributes.
src/tools/ilasm/src/ILAssembler/VTableExportPEBuilder.csFix COR header vtable fixup directory offset; refactor vtable slot serialization and export table layout.
src/tools/ilasm/src/ILAssembler/GrammarVisitor.csNumerous parser/emitter fixes to support new metadata/PDB/custom-attribute/directive scenarios.
Comments suppressed due to low confidence (1)

src/tools/ilasm/src/ILAssembler/GrammarVisitor.cs:2924

  • Same as above: ToImmutable() copies; MoveToImmutable() can transfer the backing array without allocating, which is preferable in a potentially hot parsing path.
 return new(builder.ToImmutable().SerializeSequence());

Comment threadsrc/tools/ilasm/src/ILAssembler/GrammarVisitor.cs Outdated
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

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

CopilotAI review requested due to automatic review settings July 29, 2026 00:01

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 32 out of 32 changed files in this pull request and generated no new comments.

CopilotAI review requested due to automatic review settings July 29, 2026 00:07

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 32 out of 32 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (3)

src/tools/ilasm/tests/ILAssembler.Tests/TypeSignatureTests.cs:92

  • This test assumes the locals signature is always StandAloneSig row 1. Using the method body's LocalSignature handle avoids tying the assertion to metadata row ordering.
 var signature = reader.GetStandaloneSignature(MetadataTokens.StandaloneSignatureHandle(1));

src/tools/ilasm/tests/ILAssembler.Tests/TypeSignatureTests.cs:125

  • Hard-coding StandaloneSignatureHandle(1) here couples the test to metadata emission order. Use the method body's LocalSignature to make the test robust against unrelated StandAloneSig additions.
 var signature = reader.GetStandaloneSignature(MetadataTokens.StandaloneSignatureHandle(1));

src/tools/ilasm/tests/ILAssembler.Tests/TypeSignatureTests.cs:66

  • This test hard-codes StandaloneSignatureHandle(1), which makes it brittle if the compiler ever emits another StandAloneSig row before the locals signature. Prefer using the method body's LocalSignature handle so the test is resilient to unrelated metadata changes.

This issue also appears in the following locations of the same file:

  • line 92
  • line 125
 var signature = reader.GetStandaloneSignature(MetadataTokens.StandaloneSignatureHandle(1));

CopilotAI review requested due to automatic review settings July 29, 2026 00:34

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 32 out of 32 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (1)

src/tools/ilasm/src/ILAssembler/GrammarVisitor.cs:5573

  • In structured custom attribute encoding, a boxed object(...) value must include the SerializationTypeCode.TaggedObject (0x51) prefix, followed by the embedded value’s FieldOrPropType and value bytes. The current object(...) branch writes only the embedded type/value and omits the TaggedObject prefix, which will make decoding object arguments invalid (and can break object[] element encoding too).
 if (context.serInit() is CILParser.SerInitContext serInit)
{
Debug.Assert(context.OBJECT() is not null);
BlobBuilder taggedObjectBlob = new();
WriteCustomAttributeFieldOrPropType(taggedObjectBlob, serInit);
taggedObjectBlob.LinkSuffix(VisitSerInit(serInit).Value);
return new(taggedObjectBlob);

Comment threadsrc/tools/ilasm/src/ILAssembler/GrammarVisitor.cs
CopilotAI review requested due to automatic review settings July 29, 2026 00:44

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 32 out of 32 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (1)

src/tools/ilasm/tests/ILAssembler.Tests/DocumentCompilerTestHelpers.cs:123

  • GetTokenOperands reads the method body without validating RelativeVirtualAddress > 0, so callers get an exception from PEReader.GetMethodBody instead of a clear test failure message when the target method has no body (e.g., runtime/abstract methods). This helper already has a good pattern in GetFirstTokenOperand; it should mirror that assert for consistency and debuggability.
 var method = reader.MethodDefinitions
.Select(reader.GetMethodDefinition)
.First(definition => reader.GetString(definition.Name) == methodName);
byte[] il = pe.GetMethodBody(method.RelativeVirtualAddress).GetILBytes()!;
var operands = ImmutableArray.CreateBuilder<int>();

CopilotAI review requested due to automatic review settings July 29, 2026 19:00
CopilotAI review requested due to automatic review settings August 24, 2026 21:28

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 44 out of 48 changed files in this pull request and generated 4 comments.

Comment threadsrc/tools/ilasm/src/ILAssembler/DocumentCompiler.cs Outdated
Comment threadsrc/tools/ilasm/src/ILAssembler/Options.cs
Comment threadsrc/tools/ilasm/src/ILAssembler/CompilationResult.cs
Comment threadsrc/tools/ilasm/src/ILAssembler/DocumentCompiler.cs
CopilotAI review requested due to automatic review settings August 26, 2026 20:30

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 41 out of 45 changed files in this pull request and generated 3 comments.

Suppressed comments (1)

src/tools/ilasm/src/ILAssembler/EntityRegistry.cs:418

  • The fallback AddMethodBody(...) paths also OR in MethodBodyAttributes.InitLocals when forceFatHeader is true. For the same reason as the main path, this can set InitLocals even when it wasn’t requested; it should be sufficient to pass the existing attributes and use hasDynamicStackAllocation to prevent a tiny header.
 localsSigHandle,
forceFatHeader ? methodDef.BodyAttributes | MethodBodyAttributes.InitLocals : methodDef.BodyAttributes,
hasDynamicStackAllocation: methodDef.HasDynamicStackAllocation || forceFatHeader);

Comment on lines +393 to +404
MethodBodyAttributes encodingAttributes = methodDef.BodyAttributes;
if (forceFatHeader)
{
encodingAttributes |= MethodBodyAttributes.InitLocals;
}

bodyOffset = bodyStreamEncoder.AddMethodBody(
methodDef.MethodBody,
methodDef.MaxStack,
localsSigHandle,
methodDef.BodyAttributes);
encodingAttributes,
methodDef.HasDynamicStackAllocation || forceFatHeader);
Comment threadsrc/tools/ilasm/tests/ILAssembler.Tests/GenericTests.cs
Comment on lines +18 to +29
<PropertyGroup>
<!-- Keep these NativeAOT runtime settings in sync with the first PropertyGroup in AotCompilerCommon.props. -->
<ServerGarbageCollection>true</ServerGarbageCollection>
<TieredCompilation>false</TieredCompilation>
<EventSourceSupport>true</EventSourceSupport>
<OptimizationPreference>Speed</OptimizationPreference>
<ControlFlowGuard>Guard</ControlFlowGuard>
<InvariantGlobalization>true</InvariantGlobalization>
<StripSymbols Condition="'$(KeepNativeSymbols)' == 'true'">false</StripSymbols>
<XmlResolverIsNetworkingEnabledByDefault>false</XmlResolverIsNetworkingEnabledByDefault>
<StackTraceLineNumberSupport>true</StackTraceLineNumberSupport>
</PropertyGroup>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This looks like valid feedback to me. Why do we need to have this copy?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

AotCompilerCommon.props also copies all of the JITs, which was exacerbating some of the CI failures I was seeing on the ilasm pipeline. I'll refactor out AotCompilerCommon.props into an "AotTool.props" that contains the AOT config settings and keep the original file for the info to copy JITs.

CopilotAI review requested due to automatic review settings August 26, 2026 20:46

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 41 out of 45 changed files in this pull request and generated 1 comment.

Comment on lines +524 to 528
for (int ordinal = baseOrdinal; ordinal <= maxOrdinal; ordinal++)
{
int stubIndex = Array.FindIndex(exportsArray, e => e.Ordinal == export.Ordinal);
builder.WriteInt32(exportStubRvas[stubIndex]);
int stubIndex = Array.FindIndex(exportsArray, export => export.Ordinal == ordinal);
builder.WriteInt32(stubIndex >= 0 ? exportStubRvas[stubIndex] : 0);
}
jkoritzinskyand others added 14 commits August 26, 2026 14:31
Use content-based portable PDB IDs for deterministic builds and add in-process coverage for byte-identical PDB output and non-empty PDB ID GUIDs.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2fb9f1ef-f721-49e0-bf48-4a7a9458d53a
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2fb9f1ef-f721-49e0-bf48-4a7a9458d53a
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2fb9f1ef-f721-49e0-bf48-4a7a9458d53a
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2fb9f1ef-f721-49e0-bf48-4a7a9458d53a
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2fb9f1ef-f721-49e0-bf48-4a7a9458d53a
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 106f96fe-da32-41d4-8aa5-7431edb36fc6
…ompiler, it's a compiler that's AOT compiled)
Add feature-focused metadata and PE validation tests and fix emitter issues exposed by them.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 4307156b-37a7-495d-9af6-fe9174c05b0b
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
… attribute encoding
When an object(...) element in an object[] custom attribute had nested
object() wrappers (e.g. object(object(bool(true)))), VisitSerInit's
object() branch would call WriteCustomAttributeFieldOrPropType on the
inner object() context, producing TaggedObject (0x51) as the element
type code. The .NET metadata decoder does not accept 0x51 as a
FieldOrPropType for object[] elements and throws BadImageFormatException.
Fix VisitObjSeq to fully unwrap any object(...) nesting using a while
loop, so that WriteCustomAttributeFieldOrPropType is always called with
the innermost concrete typed element (bool, int32, string, etc.). This
also makes type-byte handling uniform - always done by VisitObjSeq
rather than split between caller and callee.
Add a regression test CustomAttribute_ObjectArrayWithNestedObjectWrapper
_DecodesProperly that exercises object[](object(bool(true)) object(int32
(42))) and verifies the attribute decodes correctly.
Use comma separators between double-quoted GUID arguments so the tests match the supported .language grammar.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: adc580d5-8f1c-4772-bfc2-7a943aa0959d
Pre-size floating-point sequence builders and transfer their arrays without copying. Handle empty floating-point and string sequences and cover their custom attribute encoding.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: adc580d5-8f1c-4772-bfc2-7a943aa0959d
foreach (GenericParameterEntity genericParam in GetSeenEntities(TableIndex.GenericParam))
{
// GenericParam index is stored as a 2-byte value; skip params beyond the limit
// COMPAT: Native ilasm ignores generic parameters whose indices exceed the 2-byte metadata limit.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should this fail with an error instead?

I do not think we need to preserve every native ilasm bug. We should fix these bugs as we run into them.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

My goal was to get us to a clean ilasm round trip run without adding support for a "managed ilasm incompatible" flag. I'll add such a flag for the test case that fails because of this (and revert this compat quirk) so we can review if the test is interesting as-is.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

4 participants

@jkoritzinsky@jkotas@JulieLeeMSFT
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Improve managed ilasm test coverage by jkoritzinsky · Pull Request #131509 · dotnet/runtime · GitHub
Skip to content

Improve managed ilasm test coverage - #131509

Open
jkoritzinsky wants to merge 14 commits into
ilasm-fixupsfrom
ilasm-more-tests
Open

Improve managed ilasm test coverage#131509
jkoritzinsky wants to merge 14 commits into
ilasm-fixupsfrom
ilasm-more-tests

Conversation

@jkoritzinsky

@jkoritzinskyjkoritzinsky commented Jul 28, 2026

Copy link
Copy Markdown
Member

Add feature-focused metadata and PE validation tests and fix emitter issues exposed by them.

With these unit tests (amongst others added in the stack) we can have more confidence in the managed ilasm implementation. In the future, we may even be able to move ilasm round-trip testing to an "outerloop" experience for ilasm instead of being the primary validation pipeline.

This PR also includes fixes and corresponding tests for failures identified with ildasm/ilasm round-trip testing (all except one, which is addressed by #132346).


Stack created with GitHub Stacks CLIGive Feedback 💬

Note

This PR description was generated with GitHub Copilot.

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
16 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

@jkoritzinskyjkoritzinsky changed the title ilasm more testsImprove ILAssembler test coverageJul 28, 2026
@jkoritzinskyjkoritzinsky changed the title Improve ILAssembler test coverageImprove managed ilasm test coverageJul 28, 2026
@jkoritzinsky
jkoritzinsky marked this pull request as ready for review July 28, 2026 23:33
CopilotAI lite review requested due to automatic review settings July 28, 2026 23:33
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
16 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 significantly expands the managed ilasm unit test suite to validate emitted metadata/PE structures (exports, resources, PDBs, signatures, marshalling, etc.), and adjusts the managed ilasm emitter/parser to satisfy the newly-covered scenarios.

Changes:

  • Add many new ILAssembler.Tests cases that decode emitted metadata/PE/PDB and validate specific directives and operand forms.
  • Fix/extend ilasm implementation details in GrammarVisitor (e.g., custom attribute serialization, .module handling, sequence points, callconv explicit/instance) and VTableExportPEBuilder (vtable fixup directory offset + export table layout).
  • Improve test infra helpers to compile IL text and decode IL token operands/signatures more easily.

Reviewed changes

Copilot reviewed 32 out of 32 changed files in this pull request and generated 2 comments.

Show a summary per file
FileDescription
src/tools/ilasm/tests/ILAssembler.Tests/VTableTests.csMinor formatting-only change.
src/tools/ilasm/tests/ILAssembler.Tests/TypeSignatureTests.csAdd tests for multidimensional array local signature shapes.
src/tools/ilasm/tests/ILAssembler.Tests/TypeReferenceTests.csAdd tests for .this/.base/.nester/mdtoken type refs, module-scoped refs, typelist parsing.
src/tools/ilasm/tests/ILAssembler.Tests/TypedefTests.csAdd tests for .typedef aliases for fields and custom attributes.
src/tools/ilasm/tests/ILAssembler.Tests/TypeDefinitionTests.csAdd tests for type name splitting, class flags/attributes, nested types, interface impl metadata.
src/tools/ilasm/tests/ILAssembler.Tests/SourceDirectiveTests.csStrengthen .line/.language coverage and validate emitted embedded PDB details + string escape correctness.
src/tools/ilasm/tests/ILAssembler.Tests/SecurityTests.csAdd extensive .permissionset emission/shape tests (incl. tolerant-mode behavior).
src/tools/ilasm/tests/ILAssembler.Tests/PropertyTests.csAdd property attribute/accessor/signature metadata validation.
src/tools/ilasm/tests/ILAssembler.Tests/PropertyEventTests.csNew test file covering PropertyMap/EventMap + MethodSemantics emission.
src/tools/ilasm/tests/ILAssembler.Tests/PreprocessorIntegrationTests.csNew integration tests for nested includes, conditional compilation, multi-token macros.
src/tools/ilasm/tests/ILAssembler.Tests/ParameterTests.csAdd tests for parameter attribute forms and raw flag parsing.
src/tools/ilasm/tests/ILAssembler.Tests/NativeExportTests.csNew tests validating when exports are (not) emitted and verifying export directory/stubs.
src/tools/ilasm/tests/ILAssembler.Tests/ModuleTests.csAdd tests for .file, .module extern, bare .module, and global method/module metadata + PDB.
src/tools/ilasm/tests/ILAssembler.Tests/MethodTests.csAdd tests for method attributes/impl flags, method body directives, entrypoint token, override forms.
src/tools/ilasm/tests/ILAssembler.Tests/MemberReferenceTests.csAdd tests for vararg MemberRef signatures, generic-instantiation MemberRefs, method spec emission.
src/tools/ilasm/tests/ILAssembler.Tests/ManifestResourceTests.csNew tests for embedded/assembly/file-backed manifest resources + tolerant/deterministic behaviors.
src/tools/ilasm/tests/ILAssembler.Tests/InteropTests.csAdd marshalling and P/Invoke import metadata tests (incl. complex native type payloads).
src/tools/ilasm/tests/ILAssembler.Tests/InstructionTests.csAdd coverage for float bit-pattern literals, calli sigs, ldstr forms, switch table forms, token operands.
src/tools/ilasm/tests/ILAssembler.Tests/GenericTests.csAdd generic parameter name/bounds/variance/custom attribute/constraint metadata tests.
src/tools/ilasm/tests/ILAssembler.Tests/FunctionPointerTests.csUpdate function pointer signature assertions to use decoded signatures; add vararg fnptr test.
src/tools/ilasm/tests/ILAssembler.Tests/FieldTests.csAdd tests for field attribute flags, volatile/literal/nullref constant emission.
src/tools/ilasm/tests/ILAssembler.Tests/ExportedTypeTests.csAdd tests for exported type attributes/implementations + custom attributes.
src/tools/ilasm/tests/ILAssembler.Tests/ExceptionHandlingTests.csAdd tests validating EH region bounds/kinds for multiple clause forms.
src/tools/ilasm/tests/ILAssembler.Tests/EventTests.csAdd tests for event raise accessor, event “other” accessor, and attribute emission.
src/tools/ilasm/tests/ILAssembler.Tests/DocumentCompilerTests.csNew test validating diagnostics pathing across multi-document compilation in tolerant mode.
src/tools/ilasm/tests/ILAssembler.Tests/DocumentCompilerTestHelpers.csAdd decoder + richer compile helpers and IL token operand extraction.
src/tools/ilasm/tests/ILAssembler.Tests/DataTests.csAdd tests for .data directive typed byte emission, repeats, and class-scoped .data.
src/tools/ilasm/tests/ILAssembler.Tests/CustomAttributeTests.csAdd broad structured custom attribute decoding tests (arrays, boxed values, owner targeting, type args).
src/tools/ilasm/tests/ILAssembler.Tests/CompilerOptionsTests.csNew tests validating Options-driven PE/header/corflags/debug/pdb/determinism/keyfile behaviors.
src/tools/ilasm/tests/ILAssembler.Tests/AssemblyTests.csAdd tests for assembly reference identity metadata and aliased reference/assembly attributes.
src/tools/ilasm/src/ILAssembler/VTableExportPEBuilder.csFix COR header vtable fixup directory offset; refactor vtable slot serialization and export table layout.
src/tools/ilasm/src/ILAssembler/GrammarVisitor.csNumerous parser/emitter fixes to support new metadata/PDB/custom-attribute/directive scenarios.
Comments suppressed due to low confidence (1)

src/tools/ilasm/src/ILAssembler/GrammarVisitor.cs:2924

  • Same as above: ToImmutable() copies; MoveToImmutable() can transfer the backing array without allocating, which is preferable in a potentially hot parsing path.
 return new(builder.ToImmutable().SerializeSequence());

Comment threadsrc/tools/ilasm/src/ILAssembler/GrammarVisitor.cs Outdated
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

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

CopilotAI review requested due to automatic review settings July 29, 2026 00:01

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 32 out of 32 changed files in this pull request and generated no new comments.

CopilotAI review requested due to automatic review settings July 29, 2026 00:07

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 32 out of 32 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (3)

src/tools/ilasm/tests/ILAssembler.Tests/TypeSignatureTests.cs:92

  • This test assumes the locals signature is always StandAloneSig row 1. Using the method body's LocalSignature handle avoids tying the assertion to metadata row ordering.
 var signature = reader.GetStandaloneSignature(MetadataTokens.StandaloneSignatureHandle(1));

src/tools/ilasm/tests/ILAssembler.Tests/TypeSignatureTests.cs:125

  • Hard-coding StandaloneSignatureHandle(1) here couples the test to metadata emission order. Use the method body's LocalSignature to make the test robust against unrelated StandAloneSig additions.
 var signature = reader.GetStandaloneSignature(MetadataTokens.StandaloneSignatureHandle(1));

src/tools/ilasm/tests/ILAssembler.Tests/TypeSignatureTests.cs:66

  • This test hard-codes StandaloneSignatureHandle(1), which makes it brittle if the compiler ever emits another StandAloneSig row before the locals signature. Prefer using the method body's LocalSignature handle so the test is resilient to unrelated metadata changes.

This issue also appears in the following locations of the same file:

  • line 92
  • line 125
 var signature = reader.GetStandaloneSignature(MetadataTokens.StandaloneSignatureHandle(1));

CopilotAI review requested due to automatic review settings July 29, 2026 00:34

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 32 out of 32 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (1)

src/tools/ilasm/src/ILAssembler/GrammarVisitor.cs:5573

  • In structured custom attribute encoding, a boxed object(...) value must include the SerializationTypeCode.TaggedObject (0x51) prefix, followed by the embedded value’s FieldOrPropType and value bytes. The current object(...) branch writes only the embedded type/value and omits the TaggedObject prefix, which will make decoding object arguments invalid (and can break object[] element encoding too).
 if (context.serInit() is CILParser.SerInitContext serInit)
{
Debug.Assert(context.OBJECT() is not null);
BlobBuilder taggedObjectBlob = new();
WriteCustomAttributeFieldOrPropType(taggedObjectBlob, serInit);
taggedObjectBlob.LinkSuffix(VisitSerInit(serInit).Value);
return new(taggedObjectBlob);

Comment threadsrc/tools/ilasm/src/ILAssembler/GrammarVisitor.cs
CopilotAI review requested due to automatic review settings July 29, 2026 00:44

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 32 out of 32 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (1)

src/tools/ilasm/tests/ILAssembler.Tests/DocumentCompilerTestHelpers.cs:123

  • GetTokenOperands reads the method body without validating RelativeVirtualAddress > 0, so callers get an exception from PEReader.GetMethodBody instead of a clear test failure message when the target method has no body (e.g., runtime/abstract methods). This helper already has a good pattern in GetFirstTokenOperand; it should mirror that assert for consistency and debuggability.
 var method = reader.MethodDefinitions
.Select(reader.GetMethodDefinition)
.First(definition => reader.GetString(definition.Name) == methodName);
byte[] il = pe.GetMethodBody(method.RelativeVirtualAddress).GetILBytes()!;
var operands = ImmutableArray.CreateBuilder<int>();

CopilotAI review requested due to automatic review settings July 29, 2026 19:00
CopilotAI review requested due to automatic review settings August 24, 2026 21:28

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 44 out of 48 changed files in this pull request and generated 4 comments.

Comment threadsrc/tools/ilasm/src/ILAssembler/DocumentCompiler.cs Outdated
Comment threadsrc/tools/ilasm/src/ILAssembler/Options.cs
Comment threadsrc/tools/ilasm/src/ILAssembler/CompilationResult.cs
Comment threadsrc/tools/ilasm/src/ILAssembler/DocumentCompiler.cs
CopilotAI review requested due to automatic review settings August 26, 2026 20:30

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 41 out of 45 changed files in this pull request and generated 3 comments.

Suppressed comments (1)

src/tools/ilasm/src/ILAssembler/EntityRegistry.cs:418

  • The fallback AddMethodBody(...) paths also OR in MethodBodyAttributes.InitLocals when forceFatHeader is true. For the same reason as the main path, this can set InitLocals even when it wasn’t requested; it should be sufficient to pass the existing attributes and use hasDynamicStackAllocation to prevent a tiny header.
 localsSigHandle,
forceFatHeader ? methodDef.BodyAttributes | MethodBodyAttributes.InitLocals : methodDef.BodyAttributes,
hasDynamicStackAllocation: methodDef.HasDynamicStackAllocation || forceFatHeader);

Comment on lines +393 to +404
MethodBodyAttributes encodingAttributes = methodDef.BodyAttributes;
if (forceFatHeader)
{
encodingAttributes |= MethodBodyAttributes.InitLocals;
}

bodyOffset = bodyStreamEncoder.AddMethodBody(
methodDef.MethodBody,
methodDef.MaxStack,
localsSigHandle,
methodDef.BodyAttributes);
encodingAttributes,
methodDef.HasDynamicStackAllocation || forceFatHeader);
Comment threadsrc/tools/ilasm/tests/ILAssembler.Tests/GenericTests.cs
Comment on lines +18 to +29
<PropertyGroup>
<!-- Keep these NativeAOT runtime settings in sync with the first PropertyGroup in AotCompilerCommon.props. -->
<ServerGarbageCollection>true</ServerGarbageCollection>
<TieredCompilation>false</TieredCompilation>
<EventSourceSupport>true</EventSourceSupport>
<OptimizationPreference>Speed</OptimizationPreference>
<ControlFlowGuard>Guard</ControlFlowGuard>
<InvariantGlobalization>true</InvariantGlobalization>
<StripSymbols Condition="'$(KeepNativeSymbols)' == 'true'">false</StripSymbols>
<XmlResolverIsNetworkingEnabledByDefault>false</XmlResolverIsNetworkingEnabledByDefault>
<StackTraceLineNumberSupport>true</StackTraceLineNumberSupport>
</PropertyGroup>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This looks like valid feedback to me. Why do we need to have this copy?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

AotCompilerCommon.props also copies all of the JITs, which was exacerbating some of the CI failures I was seeing on the ilasm pipeline. I'll refactor out AotCompilerCommon.props into an "AotTool.props" that contains the AOT config settings and keep the original file for the info to copy JITs.

CopilotAI review requested due to automatic review settings August 26, 2026 20:46

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 41 out of 45 changed files in this pull request and generated 1 comment.

Comment on lines +524 to 528
for (int ordinal = baseOrdinal; ordinal <= maxOrdinal; ordinal++)
{
int stubIndex = Array.FindIndex(exportsArray, e => e.Ordinal == export.Ordinal);
builder.WriteInt32(exportStubRvas[stubIndex]);
int stubIndex = Array.FindIndex(exportsArray, export => export.Ordinal == ordinal);
builder.WriteInt32(stubIndex >= 0 ? exportStubRvas[stubIndex] : 0);
}
jkoritzinskyand others added 14 commits August 26, 2026 14:31
Use content-based portable PDB IDs for deterministic builds and add in-process coverage for byte-identical PDB output and non-empty PDB ID GUIDs.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2fb9f1ef-f721-49e0-bf48-4a7a9458d53a
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2fb9f1ef-f721-49e0-bf48-4a7a9458d53a
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2fb9f1ef-f721-49e0-bf48-4a7a9458d53a
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2fb9f1ef-f721-49e0-bf48-4a7a9458d53a
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2fb9f1ef-f721-49e0-bf48-4a7a9458d53a
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 106f96fe-da32-41d4-8aa5-7431edb36fc6
…ompiler, it's a compiler that's AOT compiled)
Add feature-focused metadata and PE validation tests and fix emitter issues exposed by them.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 4307156b-37a7-495d-9af6-fe9174c05b0b
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
… attribute encoding
When an object(...) element in an object[] custom attribute had nested
object() wrappers (e.g. object(object(bool(true)))), VisitSerInit's
object() branch would call WriteCustomAttributeFieldOrPropType on the
inner object() context, producing TaggedObject (0x51) as the element
type code. The .NET metadata decoder does not accept 0x51 as a
FieldOrPropType for object[] elements and throws BadImageFormatException.
Fix VisitObjSeq to fully unwrap any object(...) nesting using a while
loop, so that WriteCustomAttributeFieldOrPropType is always called with
the innermost concrete typed element (bool, int32, string, etc.). This
also makes type-byte handling uniform - always done by VisitObjSeq
rather than split between caller and callee.
Add a regression test CustomAttribute_ObjectArrayWithNestedObjectWrapper
_DecodesProperly that exercises object[](object(bool(true)) object(int32
(42))) and verifies the attribute decodes correctly.
Use comma separators between double-quoted GUID arguments so the tests match the supported .language grammar.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: adc580d5-8f1c-4772-bfc2-7a943aa0959d
Pre-size floating-point sequence builders and transfer their arrays without copying. Handle empty floating-point and string sequences and cover their custom attribute encoding.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: adc580d5-8f1c-4772-bfc2-7a943aa0959d
foreach (GenericParameterEntity genericParam in GetSeenEntities(TableIndex.GenericParam))
{
// GenericParam index is stored as a 2-byte value; skip params beyond the limit
// COMPAT: Native ilasm ignores generic parameters whose indices exceed the 2-byte metadata limit.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should this fail with an error instead?

I do not think we need to preserve every native ilasm bug. We should fix these bugs as we run into them.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

My goal was to get us to a clean ilasm round trip run without adding support for a "managed ilasm incompatible" flag. I'll add such a flag for the test case that fails because of this (and revert this compat quirk) so we can review if the test is interesting as-is.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

4 participants

@jkoritzinsky@jkotas@JulieLeeMSFT
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Improve managed ilasm test coverage by jkoritzinsky · Pull Request #131509 · dotnet/runtime · GitHub
Skip to content

Improve managed ilasm test coverage - #131509

Open
jkoritzinsky wants to merge 14 commits into
ilasm-fixupsfrom
ilasm-more-tests
Open

Improve managed ilasm test coverage#131509
jkoritzinsky wants to merge 14 commits into
ilasm-fixupsfrom
ilasm-more-tests

Conversation

@jkoritzinsky

@jkoritzinskyjkoritzinsky commented Jul 28, 2026

Copy link
Copy Markdown
Member

Add feature-focused metadata and PE validation tests and fix emitter issues exposed by them.

With these unit tests (amongst others added in the stack) we can have more confidence in the managed ilasm implementation. In the future, we may even be able to move ilasm round-trip testing to an "outerloop" experience for ilasm instead of being the primary validation pipeline.

This PR also includes fixes and corresponding tests for failures identified with ildasm/ilasm round-trip testing (all except one, which is addressed by #132346).


Stack created with GitHub Stacks CLIGive Feedback 💬

Note

This PR description was generated with GitHub Copilot.

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
16 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

@jkoritzinskyjkoritzinsky changed the title ilasm more testsImprove ILAssembler test coverageJul 28, 2026
@jkoritzinskyjkoritzinsky changed the title Improve ILAssembler test coverageImprove managed ilasm test coverageJul 28, 2026
@jkoritzinsky
jkoritzinsky marked this pull request as ready for review July 28, 2026 23:33
CopilotAI lite review requested due to automatic review settings July 28, 2026 23:33
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
16 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 significantly expands the managed ilasm unit test suite to validate emitted metadata/PE structures (exports, resources, PDBs, signatures, marshalling, etc.), and adjusts the managed ilasm emitter/parser to satisfy the newly-covered scenarios.

Changes:

  • Add many new ILAssembler.Tests cases that decode emitted metadata/PE/PDB and validate specific directives and operand forms.
  • Fix/extend ilasm implementation details in GrammarVisitor (e.g., custom attribute serialization, .module handling, sequence points, callconv explicit/instance) and VTableExportPEBuilder (vtable fixup directory offset + export table layout).
  • Improve test infra helpers to compile IL text and decode IL token operands/signatures more easily.

Reviewed changes

Copilot reviewed 32 out of 32 changed files in this pull request and generated 2 comments.

Show a summary per file
FileDescription
src/tools/ilasm/tests/ILAssembler.Tests/VTableTests.csMinor formatting-only change.
src/tools/ilasm/tests/ILAssembler.Tests/TypeSignatureTests.csAdd tests for multidimensional array local signature shapes.
src/tools/ilasm/tests/ILAssembler.Tests/TypeReferenceTests.csAdd tests for .this/.base/.nester/mdtoken type refs, module-scoped refs, typelist parsing.
src/tools/ilasm/tests/ILAssembler.Tests/TypedefTests.csAdd tests for .typedef aliases for fields and custom attributes.
src/tools/ilasm/tests/ILAssembler.Tests/TypeDefinitionTests.csAdd tests for type name splitting, class flags/attributes, nested types, interface impl metadata.
src/tools/ilasm/tests/ILAssembler.Tests/SourceDirectiveTests.csStrengthen .line/.language coverage and validate emitted embedded PDB details + string escape correctness.
src/tools/ilasm/tests/ILAssembler.Tests/SecurityTests.csAdd extensive .permissionset emission/shape tests (incl. tolerant-mode behavior).
src/tools/ilasm/tests/ILAssembler.Tests/PropertyTests.csAdd property attribute/accessor/signature metadata validation.
src/tools/ilasm/tests/ILAssembler.Tests/PropertyEventTests.csNew test file covering PropertyMap/EventMap + MethodSemantics emission.
src/tools/ilasm/tests/ILAssembler.Tests/PreprocessorIntegrationTests.csNew integration tests for nested includes, conditional compilation, multi-token macros.
src/tools/ilasm/tests/ILAssembler.Tests/ParameterTests.csAdd tests for parameter attribute forms and raw flag parsing.
src/tools/ilasm/tests/ILAssembler.Tests/NativeExportTests.csNew tests validating when exports are (not) emitted and verifying export directory/stubs.
src/tools/ilasm/tests/ILAssembler.Tests/ModuleTests.csAdd tests for .file, .module extern, bare .module, and global method/module metadata + PDB.
src/tools/ilasm/tests/ILAssembler.Tests/MethodTests.csAdd tests for method attributes/impl flags, method body directives, entrypoint token, override forms.
src/tools/ilasm/tests/ILAssembler.Tests/MemberReferenceTests.csAdd tests for vararg MemberRef signatures, generic-instantiation MemberRefs, method spec emission.
src/tools/ilasm/tests/ILAssembler.Tests/ManifestResourceTests.csNew tests for embedded/assembly/file-backed manifest resources + tolerant/deterministic behaviors.
src/tools/ilasm/tests/ILAssembler.Tests/InteropTests.csAdd marshalling and P/Invoke import metadata tests (incl. complex native type payloads).
src/tools/ilasm/tests/ILAssembler.Tests/InstructionTests.csAdd coverage for float bit-pattern literals, calli sigs, ldstr forms, switch table forms, token operands.
src/tools/ilasm/tests/ILAssembler.Tests/GenericTests.csAdd generic parameter name/bounds/variance/custom attribute/constraint metadata tests.
src/tools/ilasm/tests/ILAssembler.Tests/FunctionPointerTests.csUpdate function pointer signature assertions to use decoded signatures; add vararg fnptr test.
src/tools/ilasm/tests/ILAssembler.Tests/FieldTests.csAdd tests for field attribute flags, volatile/literal/nullref constant emission.
src/tools/ilasm/tests/ILAssembler.Tests/ExportedTypeTests.csAdd tests for exported type attributes/implementations + custom attributes.
src/tools/ilasm/tests/ILAssembler.Tests/ExceptionHandlingTests.csAdd tests validating EH region bounds/kinds for multiple clause forms.
src/tools/ilasm/tests/ILAssembler.Tests/EventTests.csAdd tests for event raise accessor, event “other” accessor, and attribute emission.
src/tools/ilasm/tests/ILAssembler.Tests/DocumentCompilerTests.csNew test validating diagnostics pathing across multi-document compilation in tolerant mode.
src/tools/ilasm/tests/ILAssembler.Tests/DocumentCompilerTestHelpers.csAdd decoder + richer compile helpers and IL token operand extraction.
src/tools/ilasm/tests/ILAssembler.Tests/DataTests.csAdd tests for .data directive typed byte emission, repeats, and class-scoped .data.
src/tools/ilasm/tests/ILAssembler.Tests/CustomAttributeTests.csAdd broad structured custom attribute decoding tests (arrays, boxed values, owner targeting, type args).
src/tools/ilasm/tests/ILAssembler.Tests/CompilerOptionsTests.csNew tests validating Options-driven PE/header/corflags/debug/pdb/determinism/keyfile behaviors.
src/tools/ilasm/tests/ILAssembler.Tests/AssemblyTests.csAdd tests for assembly reference identity metadata and aliased reference/assembly attributes.
src/tools/ilasm/src/ILAssembler/VTableExportPEBuilder.csFix COR header vtable fixup directory offset; refactor vtable slot serialization and export table layout.
src/tools/ilasm/src/ILAssembler/GrammarVisitor.csNumerous parser/emitter fixes to support new metadata/PDB/custom-attribute/directive scenarios.
Comments suppressed due to low confidence (1)

src/tools/ilasm/src/ILAssembler/GrammarVisitor.cs:2924

  • Same as above: ToImmutable() copies; MoveToImmutable() can transfer the backing array without allocating, which is preferable in a potentially hot parsing path.
 return new(builder.ToImmutable().SerializeSequence());

Comment threadsrc/tools/ilasm/src/ILAssembler/GrammarVisitor.cs Outdated
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

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

CopilotAI review requested due to automatic review settings July 29, 2026 00:01

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 32 out of 32 changed files in this pull request and generated no new comments.

CopilotAI review requested due to automatic review settings July 29, 2026 00:07

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 32 out of 32 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (3)

src/tools/ilasm/tests/ILAssembler.Tests/TypeSignatureTests.cs:92

  • This test assumes the locals signature is always StandAloneSig row 1. Using the method body's LocalSignature handle avoids tying the assertion to metadata row ordering.
 var signature = reader.GetStandaloneSignature(MetadataTokens.StandaloneSignatureHandle(1));

src/tools/ilasm/tests/ILAssembler.Tests/TypeSignatureTests.cs:125

  • Hard-coding StandaloneSignatureHandle(1) here couples the test to metadata emission order. Use the method body's LocalSignature to make the test robust against unrelated StandAloneSig additions.
 var signature = reader.GetStandaloneSignature(MetadataTokens.StandaloneSignatureHandle(1));

src/tools/ilasm/tests/ILAssembler.Tests/TypeSignatureTests.cs:66

  • This test hard-codes StandaloneSignatureHandle(1), which makes it brittle if the compiler ever emits another StandAloneSig row before the locals signature. Prefer using the method body's LocalSignature handle so the test is resilient to unrelated metadata changes.

This issue also appears in the following locations of the same file:

  • line 92
  • line 125
 var signature = reader.GetStandaloneSignature(MetadataTokens.StandaloneSignatureHandle(1));

CopilotAI review requested due to automatic review settings July 29, 2026 00:34

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 32 out of 32 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (1)

src/tools/ilasm/src/ILAssembler/GrammarVisitor.cs:5573

  • In structured custom attribute encoding, a boxed object(...) value must include the SerializationTypeCode.TaggedObject (0x51) prefix, followed by the embedded value’s FieldOrPropType and value bytes. The current object(...) branch writes only the embedded type/value and omits the TaggedObject prefix, which will make decoding object arguments invalid (and can break object[] element encoding too).
 if (context.serInit() is CILParser.SerInitContext serInit)
{
Debug.Assert(context.OBJECT() is not null);
BlobBuilder taggedObjectBlob = new();
WriteCustomAttributeFieldOrPropType(taggedObjectBlob, serInit);
taggedObjectBlob.LinkSuffix(VisitSerInit(serInit).Value);
return new(taggedObjectBlob);

Comment threadsrc/tools/ilasm/src/ILAssembler/GrammarVisitor.cs
CopilotAI review requested due to automatic review settings July 29, 2026 00:44

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 32 out of 32 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (1)

src/tools/ilasm/tests/ILAssembler.Tests/DocumentCompilerTestHelpers.cs:123

  • GetTokenOperands reads the method body without validating RelativeVirtualAddress > 0, so callers get an exception from PEReader.GetMethodBody instead of a clear test failure message when the target method has no body (e.g., runtime/abstract methods). This helper already has a good pattern in GetFirstTokenOperand; it should mirror that assert for consistency and debuggability.
 var method = reader.MethodDefinitions
.Select(reader.GetMethodDefinition)
.First(definition => reader.GetString(definition.Name) == methodName);
byte[] il = pe.GetMethodBody(method.RelativeVirtualAddress).GetILBytes()!;
var operands = ImmutableArray.CreateBuilder<int>();

CopilotAI review requested due to automatic review settings July 29, 2026 19:00
CopilotAI review requested due to automatic review settings August 24, 2026 21:28

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 44 out of 48 changed files in this pull request and generated 4 comments.

Comment threadsrc/tools/ilasm/src/ILAssembler/DocumentCompiler.cs Outdated
Comment threadsrc/tools/ilasm/src/ILAssembler/Options.cs
Comment threadsrc/tools/ilasm/src/ILAssembler/CompilationResult.cs
Comment threadsrc/tools/ilasm/src/ILAssembler/DocumentCompiler.cs
CopilotAI review requested due to automatic review settings August 26, 2026 20:30

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 41 out of 45 changed files in this pull request and generated 3 comments.

Suppressed comments (1)

src/tools/ilasm/src/ILAssembler/EntityRegistry.cs:418

  • The fallback AddMethodBody(...) paths also OR in MethodBodyAttributes.InitLocals when forceFatHeader is true. For the same reason as the main path, this can set InitLocals even when it wasn’t requested; it should be sufficient to pass the existing attributes and use hasDynamicStackAllocation to prevent a tiny header.
 localsSigHandle,
forceFatHeader ? methodDef.BodyAttributes | MethodBodyAttributes.InitLocals : methodDef.BodyAttributes,
hasDynamicStackAllocation: methodDef.HasDynamicStackAllocation || forceFatHeader);

Comment on lines +393 to +404
MethodBodyAttributes encodingAttributes = methodDef.BodyAttributes;
if (forceFatHeader)
{
encodingAttributes |= MethodBodyAttributes.InitLocals;
}

bodyOffset = bodyStreamEncoder.AddMethodBody(
methodDef.MethodBody,
methodDef.MaxStack,
localsSigHandle,
methodDef.BodyAttributes);
encodingAttributes,
methodDef.HasDynamicStackAllocation || forceFatHeader);
Comment threadsrc/tools/ilasm/tests/ILAssembler.Tests/GenericTests.cs
Comment on lines +18 to +29
<PropertyGroup>
<!-- Keep these NativeAOT runtime settings in sync with the first PropertyGroup in AotCompilerCommon.props. -->
<ServerGarbageCollection>true</ServerGarbageCollection>
<TieredCompilation>false</TieredCompilation>
<EventSourceSupport>true</EventSourceSupport>
<OptimizationPreference>Speed</OptimizationPreference>
<ControlFlowGuard>Guard</ControlFlowGuard>
<InvariantGlobalization>true</InvariantGlobalization>
<StripSymbols Condition="'$(KeepNativeSymbols)' == 'true'">false</StripSymbols>
<XmlResolverIsNetworkingEnabledByDefault>false</XmlResolverIsNetworkingEnabledByDefault>
<StackTraceLineNumberSupport>true</StackTraceLineNumberSupport>
</PropertyGroup>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This looks like valid feedback to me. Why do we need to have this copy?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

AotCompilerCommon.props also copies all of the JITs, which was exacerbating some of the CI failures I was seeing on the ilasm pipeline. I'll refactor out AotCompilerCommon.props into an "AotTool.props" that contains the AOT config settings and keep the original file for the info to copy JITs.

CopilotAI review requested due to automatic review settings August 26, 2026 20:46

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 41 out of 45 changed files in this pull request and generated 1 comment.

Comment on lines +524 to 528
for (int ordinal = baseOrdinal; ordinal <= maxOrdinal; ordinal++)
{
int stubIndex = Array.FindIndex(exportsArray, e => e.Ordinal == export.Ordinal);
builder.WriteInt32(exportStubRvas[stubIndex]);
int stubIndex = Array.FindIndex(exportsArray, export => export.Ordinal == ordinal);
builder.WriteInt32(stubIndex >= 0 ? exportStubRvas[stubIndex] : 0);
}
jkoritzinskyand others added 14 commits August 26, 2026 14:31
Use content-based portable PDB IDs for deterministic builds and add in-process coverage for byte-identical PDB output and non-empty PDB ID GUIDs.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2fb9f1ef-f721-49e0-bf48-4a7a9458d53a
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2fb9f1ef-f721-49e0-bf48-4a7a9458d53a
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2fb9f1ef-f721-49e0-bf48-4a7a9458d53a
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2fb9f1ef-f721-49e0-bf48-4a7a9458d53a
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2fb9f1ef-f721-49e0-bf48-4a7a9458d53a
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 106f96fe-da32-41d4-8aa5-7431edb36fc6
…ompiler, it's a compiler that's AOT compiled)
Add feature-focused metadata and PE validation tests and fix emitter issues exposed by them.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 4307156b-37a7-495d-9af6-fe9174c05b0b
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
… attribute encoding
When an object(...) element in an object[] custom attribute had nested
object() wrappers (e.g. object(object(bool(true)))), VisitSerInit's
object() branch would call WriteCustomAttributeFieldOrPropType on the
inner object() context, producing TaggedObject (0x51) as the element
type code. The .NET metadata decoder does not accept 0x51 as a
FieldOrPropType for object[] elements and throws BadImageFormatException.
Fix VisitObjSeq to fully unwrap any object(...) nesting using a while
loop, so that WriteCustomAttributeFieldOrPropType is always called with
the innermost concrete typed element (bool, int32, string, etc.). This
also makes type-byte handling uniform - always done by VisitObjSeq
rather than split between caller and callee.
Add a regression test CustomAttribute_ObjectArrayWithNestedObjectWrapper
_DecodesProperly that exercises object[](object(bool(true)) object(int32
(42))) and verifies the attribute decodes correctly.
Use comma separators between double-quoted GUID arguments so the tests match the supported .language grammar.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: adc580d5-8f1c-4772-bfc2-7a943aa0959d
Pre-size floating-point sequence builders and transfer their arrays without copying. Handle empty floating-point and string sequences and cover their custom attribute encoding.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: adc580d5-8f1c-4772-bfc2-7a943aa0959d
foreach (GenericParameterEntity genericParam in GetSeenEntities(TableIndex.GenericParam))
{
// GenericParam index is stored as a 2-byte value; skip params beyond the limit
// COMPAT: Native ilasm ignores generic parameters whose indices exceed the 2-byte metadata limit.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should this fail with an error instead?

I do not think we need to preserve every native ilasm bug. We should fix these bugs as we run into them.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

My goal was to get us to a clean ilasm round trip run without adding support for a "managed ilasm incompatible" flag. I'll add such a flag for the test case that fails because of this (and revert this compat quirk) so we can review if the test is interesting as-is.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

4 participants

@jkoritzinsky@jkotas@JulieLeeMSFT
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); Improve managed ilasm test coverage by jkoritzinsky · Pull Request #131509 · dotnet/runtime · GitHub
Skip to content

Improve managed ilasm test coverage - #131509

Open
jkoritzinsky wants to merge 14 commits into
ilasm-fixupsfrom
ilasm-more-tests
Open

Improve managed ilasm test coverage#131509
jkoritzinsky wants to merge 14 commits into
ilasm-fixupsfrom
ilasm-more-tests

Conversation

@jkoritzinsky

@jkoritzinskyjkoritzinsky commented Jul 28, 2026

Copy link
Copy Markdown
Member

Add feature-focused metadata and PE validation tests and fix emitter issues exposed by them.

With these unit tests (amongst others added in the stack) we can have more confidence in the managed ilasm implementation. In the future, we may even be able to move ilasm round-trip testing to an "outerloop" experience for ilasm instead of being the primary validation pipeline.

This PR also includes fixes and corresponding tests for failures identified with ildasm/ilasm round-trip testing (all except one, which is addressed by #132346).


Stack created with GitHub Stacks CLIGive Feedback 💬

Note

This PR description was generated with GitHub Copilot.

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
16 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

@jkoritzinskyjkoritzinsky changed the title ilasm more testsImprove ILAssembler test coverageJul 28, 2026
@jkoritzinskyjkoritzinsky changed the title Improve ILAssembler test coverageImprove managed ilasm test coverageJul 28, 2026
@jkoritzinsky
jkoritzinsky marked this pull request as ready for review July 28, 2026 23:33
CopilotAI lite review requested due to automatic review settings July 28, 2026 23:33
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
16 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 significantly expands the managed ilasm unit test suite to validate emitted metadata/PE structures (exports, resources, PDBs, signatures, marshalling, etc.), and adjusts the managed ilasm emitter/parser to satisfy the newly-covered scenarios.

Changes:

  • Add many new ILAssembler.Tests cases that decode emitted metadata/PE/PDB and validate specific directives and operand forms.
  • Fix/extend ilasm implementation details in GrammarVisitor (e.g., custom attribute serialization, .module handling, sequence points, callconv explicit/instance) and VTableExportPEBuilder (vtable fixup directory offset + export table layout).
  • Improve test infra helpers to compile IL text and decode IL token operands/signatures more easily.

Reviewed changes

Copilot reviewed 32 out of 32 changed files in this pull request and generated 2 comments.

Show a summary per file
FileDescription
src/tools/ilasm/tests/ILAssembler.Tests/VTableTests.csMinor formatting-only change.
src/tools/ilasm/tests/ILAssembler.Tests/TypeSignatureTests.csAdd tests for multidimensional array local signature shapes.
src/tools/ilasm/tests/ILAssembler.Tests/TypeReferenceTests.csAdd tests for .this/.base/.nester/mdtoken type refs, module-scoped refs, typelist parsing.
src/tools/ilasm/tests/ILAssembler.Tests/TypedefTests.csAdd tests for .typedef aliases for fields and custom attributes.
src/tools/ilasm/tests/ILAssembler.Tests/TypeDefinitionTests.csAdd tests for type name splitting, class flags/attributes, nested types, interface impl metadata.
src/tools/ilasm/tests/ILAssembler.Tests/SourceDirectiveTests.csStrengthen .line/.language coverage and validate emitted embedded PDB details + string escape correctness.
src/tools/ilasm/tests/ILAssembler.Tests/SecurityTests.csAdd extensive .permissionset emission/shape tests (incl. tolerant-mode behavior).
src/tools/ilasm/tests/ILAssembler.Tests/PropertyTests.csAdd property attribute/accessor/signature metadata validation.
src/tools/ilasm/tests/ILAssembler.Tests/PropertyEventTests.csNew test file covering PropertyMap/EventMap + MethodSemantics emission.
src/tools/ilasm/tests/ILAssembler.Tests/PreprocessorIntegrationTests.csNew integration tests for nested includes, conditional compilation, multi-token macros.
src/tools/ilasm/tests/ILAssembler.Tests/ParameterTests.csAdd tests for parameter attribute forms and raw flag parsing.
src/tools/ilasm/tests/ILAssembler.Tests/NativeExportTests.csNew tests validating when exports are (not) emitted and verifying export directory/stubs.
src/tools/ilasm/tests/ILAssembler.Tests/ModuleTests.csAdd tests for .file, .module extern, bare .module, and global method/module metadata + PDB.
src/tools/ilasm/tests/ILAssembler.Tests/MethodTests.csAdd tests for method attributes/impl flags, method body directives, entrypoint token, override forms.
src/tools/ilasm/tests/ILAssembler.Tests/MemberReferenceTests.csAdd tests for vararg MemberRef signatures, generic-instantiation MemberRefs, method spec emission.
src/tools/ilasm/tests/ILAssembler.Tests/ManifestResourceTests.csNew tests for embedded/assembly/file-backed manifest resources + tolerant/deterministic behaviors.
src/tools/ilasm/tests/ILAssembler.Tests/InteropTests.csAdd marshalling and P/Invoke import metadata tests (incl. complex native type payloads).
src/tools/ilasm/tests/ILAssembler.Tests/InstructionTests.csAdd coverage for float bit-pattern literals, calli sigs, ldstr forms, switch table forms, token operands.
src/tools/ilasm/tests/ILAssembler.Tests/GenericTests.csAdd generic parameter name/bounds/variance/custom attribute/constraint metadata tests.
src/tools/ilasm/tests/ILAssembler.Tests/FunctionPointerTests.csUpdate function pointer signature assertions to use decoded signatures; add vararg fnptr test.
src/tools/ilasm/tests/ILAssembler.Tests/FieldTests.csAdd tests for field attribute flags, volatile/literal/nullref constant emission.
src/tools/ilasm/tests/ILAssembler.Tests/ExportedTypeTests.csAdd tests for exported type attributes/implementations + custom attributes.
src/tools/ilasm/tests/ILAssembler.Tests/ExceptionHandlingTests.csAdd tests validating EH region bounds/kinds for multiple clause forms.
src/tools/ilasm/tests/ILAssembler.Tests/EventTests.csAdd tests for event raise accessor, event “other” accessor, and attribute emission.
src/tools/ilasm/tests/ILAssembler.Tests/DocumentCompilerTests.csNew test validating diagnostics pathing across multi-document compilation in tolerant mode.
src/tools/ilasm/tests/ILAssembler.Tests/DocumentCompilerTestHelpers.csAdd decoder + richer compile helpers and IL token operand extraction.
src/tools/ilasm/tests/ILAssembler.Tests/DataTests.csAdd tests for .data directive typed byte emission, repeats, and class-scoped .data.
src/tools/ilasm/tests/ILAssembler.Tests/CustomAttributeTests.csAdd broad structured custom attribute decoding tests (arrays, boxed values, owner targeting, type args).
src/tools/ilasm/tests/ILAssembler.Tests/CompilerOptionsTests.csNew tests validating Options-driven PE/header/corflags/debug/pdb/determinism/keyfile behaviors.
src/tools/ilasm/tests/ILAssembler.Tests/AssemblyTests.csAdd tests for assembly reference identity metadata and aliased reference/assembly attributes.
src/tools/ilasm/src/ILAssembler/VTableExportPEBuilder.csFix COR header vtable fixup directory offset; refactor vtable slot serialization and export table layout.
src/tools/ilasm/src/ILAssembler/GrammarVisitor.csNumerous parser/emitter fixes to support new metadata/PDB/custom-attribute/directive scenarios.
Comments suppressed due to low confidence (1)

src/tools/ilasm/src/ILAssembler/GrammarVisitor.cs:2924

  • Same as above: ToImmutable() copies; MoveToImmutable() can transfer the backing array without allocating, which is preferable in a potentially hot parsing path.
 return new(builder.ToImmutable().SerializeSequence());

Comment threadsrc/tools/ilasm/src/ILAssembler/GrammarVisitor.cs Outdated
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

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

CopilotAI review requested due to automatic review settings July 29, 2026 00:01

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 32 out of 32 changed files in this pull request and generated no new comments.

CopilotAI review requested due to automatic review settings July 29, 2026 00:07

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 32 out of 32 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (3)

src/tools/ilasm/tests/ILAssembler.Tests/TypeSignatureTests.cs:92

  • This test assumes the locals signature is always StandAloneSig row 1. Using the method body's LocalSignature handle avoids tying the assertion to metadata row ordering.
 var signature = reader.GetStandaloneSignature(MetadataTokens.StandaloneSignatureHandle(1));

src/tools/ilasm/tests/ILAssembler.Tests/TypeSignatureTests.cs:125

  • Hard-coding StandaloneSignatureHandle(1) here couples the test to metadata emission order. Use the method body's LocalSignature to make the test robust against unrelated StandAloneSig additions.
 var signature = reader.GetStandaloneSignature(MetadataTokens.StandaloneSignatureHandle(1));

src/tools/ilasm/tests/ILAssembler.Tests/TypeSignatureTests.cs:66

  • This test hard-codes StandaloneSignatureHandle(1), which makes it brittle if the compiler ever emits another StandAloneSig row before the locals signature. Prefer using the method body's LocalSignature handle so the test is resilient to unrelated metadata changes.

This issue also appears in the following locations of the same file:

  • line 92
  • line 125
 var signature = reader.GetStandaloneSignature(MetadataTokens.StandaloneSignatureHandle(1));

CopilotAI review requested due to automatic review settings July 29, 2026 00:34

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 32 out of 32 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (1)

src/tools/ilasm/src/ILAssembler/GrammarVisitor.cs:5573

  • In structured custom attribute encoding, a boxed object(...) value must include the SerializationTypeCode.TaggedObject (0x51) prefix, followed by the embedded value’s FieldOrPropType and value bytes. The current object(...) branch writes only the embedded type/value and omits the TaggedObject prefix, which will make decoding object arguments invalid (and can break object[] element encoding too).
 if (context.serInit() is CILParser.SerInitContext serInit)
{
Debug.Assert(context.OBJECT() is not null);
BlobBuilder taggedObjectBlob = new();
WriteCustomAttributeFieldOrPropType(taggedObjectBlob, serInit);
taggedObjectBlob.LinkSuffix(VisitSerInit(serInit).Value);
return new(taggedObjectBlob);

Comment threadsrc/tools/ilasm/src/ILAssembler/GrammarVisitor.cs
CopilotAI review requested due to automatic review settings July 29, 2026 00:44

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 32 out of 32 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (1)

src/tools/ilasm/tests/ILAssembler.Tests/DocumentCompilerTestHelpers.cs:123

  • GetTokenOperands reads the method body without validating RelativeVirtualAddress > 0, so callers get an exception from PEReader.GetMethodBody instead of a clear test failure message when the target method has no body (e.g., runtime/abstract methods). This helper already has a good pattern in GetFirstTokenOperand; it should mirror that assert for consistency and debuggability.
 var method = reader.MethodDefinitions
.Select(reader.GetMethodDefinition)
.First(definition => reader.GetString(definition.Name) == methodName);
byte[] il = pe.GetMethodBody(method.RelativeVirtualAddress).GetILBytes()!;
var operands = ImmutableArray.CreateBuilder<int>();

CopilotAI review requested due to automatic review settings July 29, 2026 19:00
CopilotAI review requested due to automatic review settings August 24, 2026 21:28

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 44 out of 48 changed files in this pull request and generated 4 comments.

Comment threadsrc/tools/ilasm/src/ILAssembler/DocumentCompiler.cs Outdated
Comment threadsrc/tools/ilasm/src/ILAssembler/Options.cs
Comment threadsrc/tools/ilasm/src/ILAssembler/CompilationResult.cs
Comment threadsrc/tools/ilasm/src/ILAssembler/DocumentCompiler.cs
CopilotAI review requested due to automatic review settings August 26, 2026 20:30

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 41 out of 45 changed files in this pull request and generated 3 comments.

Suppressed comments (1)

src/tools/ilasm/src/ILAssembler/EntityRegistry.cs:418

  • The fallback AddMethodBody(...) paths also OR in MethodBodyAttributes.InitLocals when forceFatHeader is true. For the same reason as the main path, this can set InitLocals even when it wasn’t requested; it should be sufficient to pass the existing attributes and use hasDynamicStackAllocation to prevent a tiny header.
 localsSigHandle,
forceFatHeader ? methodDef.BodyAttributes | MethodBodyAttributes.InitLocals : methodDef.BodyAttributes,
hasDynamicStackAllocation: methodDef.HasDynamicStackAllocation || forceFatHeader);

Comment on lines +393 to +404
MethodBodyAttributes encodingAttributes = methodDef.BodyAttributes;
if (forceFatHeader)
{
encodingAttributes |= MethodBodyAttributes.InitLocals;
}

bodyOffset = bodyStreamEncoder.AddMethodBody(
methodDef.MethodBody,
methodDef.MaxStack,
localsSigHandle,
methodDef.BodyAttributes);
encodingAttributes,
methodDef.HasDynamicStackAllocation || forceFatHeader);
Comment threadsrc/tools/ilasm/tests/ILAssembler.Tests/GenericTests.cs
Comment on lines +18 to +29
<PropertyGroup>
<!-- Keep these NativeAOT runtime settings in sync with the first PropertyGroup in AotCompilerCommon.props. -->
<ServerGarbageCollection>true</ServerGarbageCollection>
<TieredCompilation>false</TieredCompilation>
<EventSourceSupport>true</EventSourceSupport>
<OptimizationPreference>Speed</OptimizationPreference>
<ControlFlowGuard>Guard</ControlFlowGuard>
<InvariantGlobalization>true</InvariantGlobalization>
<StripSymbols Condition="'$(KeepNativeSymbols)' == 'true'">false</StripSymbols>
<XmlResolverIsNetworkingEnabledByDefault>false</XmlResolverIsNetworkingEnabledByDefault>
<StackTraceLineNumberSupport>true</StackTraceLineNumberSupport>
</PropertyGroup>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This looks like valid feedback to me. Why do we need to have this copy?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

AotCompilerCommon.props also copies all of the JITs, which was exacerbating some of the CI failures I was seeing on the ilasm pipeline. I'll refactor out AotCompilerCommon.props into an "AotTool.props" that contains the AOT config settings and keep the original file for the info to copy JITs.

CopilotAI review requested due to automatic review settings August 26, 2026 20:46

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 41 out of 45 changed files in this pull request and generated 1 comment.

Comment on lines +524 to 528
for (int ordinal = baseOrdinal; ordinal <= maxOrdinal; ordinal++)
{
int stubIndex = Array.FindIndex(exportsArray, e => e.Ordinal == export.Ordinal);
builder.WriteInt32(exportStubRvas[stubIndex]);
int stubIndex = Array.FindIndex(exportsArray, export => export.Ordinal == ordinal);
builder.WriteInt32(stubIndex >= 0 ? exportStubRvas[stubIndex] : 0);
}
jkoritzinskyand others added 14 commits August 26, 2026 14:31
Use content-based portable PDB IDs for deterministic builds and add in-process coverage for byte-identical PDB output and non-empty PDB ID GUIDs.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2fb9f1ef-f721-49e0-bf48-4a7a9458d53a
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2fb9f1ef-f721-49e0-bf48-4a7a9458d53a
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2fb9f1ef-f721-49e0-bf48-4a7a9458d53a
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2fb9f1ef-f721-49e0-bf48-4a7a9458d53a
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2fb9f1ef-f721-49e0-bf48-4a7a9458d53a
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 106f96fe-da32-41d4-8aa5-7431edb36fc6
…ompiler, it's a compiler that's AOT compiled)
Add feature-focused metadata and PE validation tests and fix emitter issues exposed by them.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 4307156b-37a7-495d-9af6-fe9174c05b0b
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
… attribute encoding
When an object(...) element in an object[] custom attribute had nested
object() wrappers (e.g. object(object(bool(true)))), VisitSerInit's
object() branch would call WriteCustomAttributeFieldOrPropType on the
inner object() context, producing TaggedObject (0x51) as the element
type code. The .NET metadata decoder does not accept 0x51 as a
FieldOrPropType for object[] elements and throws BadImageFormatException.
Fix VisitObjSeq to fully unwrap any object(...) nesting using a while
loop, so that WriteCustomAttributeFieldOrPropType is always called with
the innermost concrete typed element (bool, int32, string, etc.). This
also makes type-byte handling uniform - always done by VisitObjSeq
rather than split between caller and callee.
Add a regression test CustomAttribute_ObjectArrayWithNestedObjectWrapper
_DecodesProperly that exercises object[](object(bool(true)) object(int32
(42))) and verifies the attribute decodes correctly.
Use comma separators between double-quoted GUID arguments so the tests match the supported .language grammar.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: adc580d5-8f1c-4772-bfc2-7a943aa0959d
Pre-size floating-point sequence builders and transfer their arrays without copying. Handle empty floating-point and string sequences and cover their custom attribute encoding.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: adc580d5-8f1c-4772-bfc2-7a943aa0959d
foreach (GenericParameterEntity genericParam in GetSeenEntities(TableIndex.GenericParam))
{
// GenericParam index is stored as a 2-byte value; skip params beyond the limit
// COMPAT: Native ilasm ignores generic parameters whose indices exceed the 2-byte metadata limit.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should this fail with an error instead?

I do not think we need to preserve every native ilasm bug. We should fix these bugs as we run into them.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

My goal was to get us to a clean ilasm round trip run without adding support for a "managed ilasm incompatible" flag. I'll add such a flag for the test case that fails because of this (and revert this compat quirk) so we can review if the test is interesting as-is.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

4 participants

@jkoritzinsky@jkotas@JulieLeeMSFT