Skip to content

Conversation

@Sergio0694
Copy link
Member

Title. This fixes two issues:

  • Bad IL when unpinning string and Type parameters
  • Incorrect call to Dispose for unmanaged value types

Adjust string and Type marshalling rewrites to handle unpinning correctly when earlier parameters introduce protected regions. The RewriteBodyForTypeOfString and RewriteBodyForTypeOfType helpers now take the MethodDefinition and emit either an inline unpin sequence or a separate finally-protected unpin region (matching Roslyn) depending on whether earlier parameters require a protected region. Added a nop try-start label, conditional exception handler emission, and the HasProtectedRegionBeforeParameterIndex helper to detect when a dedicated finally is needed. This prevents invalid IL layout when other parameters use leave.s and ensures pinned locals are unpinned safely.
Simplify unpinning logic in InteropMethodRewriter.NativeParameter.cs by always emitting a protected finally region for unpinning pinned locals. Introduces shared ldc_i4_0_finallyStart and nop_finallyEnd labels and moves the ExceptionHandler.Add call outside the previous conditional paths. Removes the HasProtectedRegionBeforeParameterIndex check and associated branching, as the rewriter assumes a preceding protected region (e.g. the 'this' parameter) is always present. This consolidates string and TypeReference marshalling cleanup into a single consistent flow.
Add explicit handling for KeyValuePair<> parameter types by directly looking up the marshaller from emit state (no custom disposal needed). Change the previous default branch to explicitly detect managed value types. Add a new branch for unmanaged value types that only need marshalling (no disposal): remove the try/finally ranges and replace the load sequence to call the marshaller's ConvertToUnmanaged method. These changes reduce unnecessary disposal overhead and ensure correct marshalling paths for different value-type categories.
Remove the unused MethodDefinition parameter from RewriteBodyForTypeOfString and RewriteBodyForTypeOfType in src/WinRT.Interop.Generator/Rewriters/InteropMethodRewriter.NativeParameter.cs. Update call sites to stop passing the argument and remove the related XML doc <param> lines. Minor cleanup to simplify helper signatures and remove dead parameter usage.
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes native parameter two-pass rewriting in cswinrtgen to avoid invalid IL for string/Type unpinning and to stop emitting disposal for unmanaged value-type ABI values.

Changes:

  • Split value-type handling into managed vs unmanaged to avoid calling Dispose on unmanaged ABI value types.
  • Emit a dedicated try/finally region for string and Type pin/unpin so unpinning doesn’t end up after a leave.s within another protected region.
  • Minor documentation/comment additions around the new flow.
Comments suppressed due to low confidence (2)

src/WinRT.Interop.Generator/Rewriters/InteropMethodRewriter.NativeParameter.cs:292

  • The newly added method parameter is not used inside RewriteBodyForTypeOfString. Consider removing it (and the corresponding argument at the call site) to keep the helper signature minimal, unless you plan to use it for validation/debug output.
            CilMethodBody body,
            CilInstruction tryMarker,
            CilInstruction loadMarker,
            CilInstruction finallyMarker,
            int parameterIndex,
            InteropReferences interopReferences,

src/WinRT.Interop.Generator/Rewriters/InteropMethodRewriter.NativeParameter.cs:391

  • The newly added method parameter is not used inside RewriteBodyForTypeOfType. Consider removing it (and the corresponding argument at the call site) to reduce noise unless it will be used.
            CilInstruction loadMarker,
            CilInstruction finallyMarker,
            int parameterIndex,
            InteropReferences interopReferences,
            ModuleDefinition module)
        {
            // Declare the local variables:

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Sergio0694 and others added 6 commits January 30, 2026 16:42
Corrected and clarified comment text in InteropMethodRewriter.NativeParameter.cs around HString handling and protected regions. Removed garbled words and rephrased the explanation of using a protected region to unpin the local so the 'leave.s' remains the last instruction in the inner-most region and the unpin instructions are emitted in their own finally handler. No functional code changes.
Remove the static modifier from the partial InteropMethodRewriter class (change from 'internal static partial class' to 'internal partial class') to allow instance members. Replace the file-level XML summary with an inheritdoc (<inheritdoc cref="InteropMethodRewriter"/>) so the file reuses the main type's documentation.
Introduce InteropMethodFixup, an abstract type for applying custom fixups to generated methods as a final processing step. The class resides in WindowsRuntime.InteropGenerator.Fixups and exposes an abstract Apply(MethodDefinition method) method for implementers. Includes MIT license header and reference to AsmResolver.DotNet.
Introduce a new InteropMethodFixup.RemoveLeftoverNopAfterLeave implementation that removes invalid nop instructions inside protected regions and redirects labels accordingly. Add validation helpers for exception handler and branch labels, and helper methods to detect non-fall-through instructions and ranges. Add new WellKnownInteropExceptions for fixup-related errors (IDs 75-77) and clarify the existing MethodRewriteMissingBodyError message. Make InteropMethodFixup partial to accommodate the new fixup implementation.
Add a two-pass IL fixup step that walks all generated types/methods and applies available InteropMethodFixup instances. Introduce FixupMethodDefinitions and call it during Emit, applying fixes (currently RemoveLeftoverNopAfterLeave) and reporting failures via a new WellKnownInteropExceptions.MethodFixupError helper. Also add necessary using directives.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants