-
Notifications
You must be signed in to change notification settings - Fork 123
Fix some native parameter two-pass rewriting in 'cswinrtgen' #2213
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: staging/3.0
Are you sure you want to change the base?
Conversation
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.
There was a problem hiding this 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
Disposeon unmanaged ABI value types. - Emit a dedicated
try/finallyregion forstringandTypepin/unpin so unpinning doesn’t end up after aleave.swithin 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
methodparameter is not used insideRewriteBodyForTypeOfString. 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
methodparameter is not used insideRewriteBodyForTypeOfType. 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.
src/WinRT.Interop.Generator/Rewriters/InteropMethodRewriter.NativeParameter.cs
Show resolved
Hide resolved
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.
Title. This fixes two issues:
stringandTypeparametersDisposefor unmanaged value types