Skip to content

Convert more COM interop MethodDescCallSite to UCO#125508

Open
am11 wants to merge 19 commits intodotnet:mainfrom
am11:feature/MDCS-to-UCOA-pattern
Open

Convert more COM interop MethodDescCallSite to UCO#125508
am11 wants to merge 19 commits intodotnet:mainfrom
am11:feature/MDCS-to-UCOA-pattern

Conversation

@am11
Copy link
Member

@am11 am11 commented Mar 12, 2026

Contributes to #123864 (group 5: except dispatchinfo.cpp)

@dotnet-policy-service dotnet-policy-service bot added the community-contribution Indicates that the PR has been added by a community member label Mar 12, 2026
@am11
Copy link
Member Author

am11 commented Mar 14, 2026

Failures are unrelated (iOS dead-lettered).

Copy link
Member

@AaronRobinsonMSFT AaronRobinsonMSFT left a comment

Choose a reason for hiding this comment

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

One minor request for an assert. Other than that, :shipit:

: ByReference.Create(ref arg);
}

return RuntimeMethodHandle.InvokeMethod(target, (void**)pByRefFixedStorage, signature, isConstructor: false);
Copy link
Member

Choose a reason for hiding this comment

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

RuntimeMethodHandle.InvokeMethod is a wrapper around CallDescrWorker that we will need to get rid of to get rid of CallDescrWorker. This change is not helping with that - this code will need to be redone.

It would be better to wait with converting these after we have eliminated CallDescrWorker use in RuntimeMethodHandle.InvokeMethod

Copy link
Member Author

Choose a reason for hiding this comment

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

One approach is to avoid InvokeMethod like this am11@e5fc85e. Is this enough or do we want to keep using InvokeMethod and replace CallDescrWorkerWithHandler machinery from it?

Copy link
Member

Choose a reason for hiding this comment

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

InvokeDelegateConstructor and InvokeVoidMethodWithOneArg looks good.

For InvokeArgSlotMethodWithOneArg, do we really need the full set of types for this COM interop path? Do we have test coverage for all the cases?

Copy link
Member Author

Choose a reason for hiding this comment

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

I kept InvokeDelegateConstructor and InvokeVoidMethodWithOneArg as-is.

For InvokeArgSlotMethodWithOneArg, I reduced the supported return types to a narrower COM-event-oriented set (void, bool, int/uint, long/ulong, IntPtr/UIntPtr) and removed the broader primitive/reference conversion matrix. Not sure about the test coverage status. Perhaps, @AaronRobinsonMSFT might have an idea? I ran a few interop tests under src/tests/Interop and they seem to be passing.

Copy link
Member

Choose a reason for hiding this comment

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

I ran a few interop tests under src/tests/Interop and they seem to be passing.

Do they hit this method?

InvokeArgSlotMethodWithOneArg

Maybe leave this out from this PR so the rest can be merged?

Copy link
Member Author

Choose a reason for hiding this comment

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

At least void-return seems to be exercised by COM event tests in src/tests/Interop/COM/NETClients/Events/Program.cs (both OnEvent +=/-= and the ComAwareEventInfo add/remove flow). Those calls go through the COM event interface wiring in src/tests/Interop/COM/ServerContracts/Server.Events.cs, then into CLRToCOMEventCallWorker in src/coreclr/vm/clrtocomcall.cpp, which invokes StubHelpers.InvokeClrToComEventProviderMethod, and that calls InvokeArgSlotMethodWithOneArg.

The current test shape here is still void-return (FireEvent and OnEvent are void in src/tests/Interop/COM/ServerContracts/Server.Contracts.cs), so this confirms the helper is hit and the void branch is covered, but this test alone does not go to all non-void branches of the type-dispatch logic. There are other tests as well.

Copy link
Member

Choose a reason for hiding this comment

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

this test alone does not go to all non-void branches of the type-dispatch logic

Do we have tests that go to any of the non-void branches?

Copy link
Member

@AaronRobinsonMSFT AaronRobinsonMSFT Mar 15, 2026

Choose a reason for hiding this comment

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

The COM events tests are a bit sparse. We only added in what was obviously needed for events leveaged by Office PIAs.

((delegate*<object, object?, nint, void>)delegateCtorMethodEntryPoint)(*pDelegate, *pSubscriber, (nint)pEventMethodCodePtr);
}

nint providerMethodEntryPoint = (nint)pProviderMethodPtr;
Copy link
Member

Choose a reason for hiding this comment

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

nint and IntPtr are the same type. Are these casts really needed?

&gc.ThisObj,
&gc.EventProviderTypeObj,
(INT_PTR)pEvProvMD,
(INT_PTR)pEvProvMD->GetMultiCallableAddrOfCode(),
Copy link
Member

Choose a reason for hiding this comment

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

These can use GetSingleCallableAddrOfCode() since the function pointer is used exactly once.

return 0;
}

if (returnType == typeof(bool))
Copy link
Member

Choose a reason for hiding this comment

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

How did you come up with this list of supported return types?

Copy link
Member Author

Choose a reason for hiding this comment

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

The return-type list was not based on a separate runtime contract; it was a conservative subset of ARG_SLOT-sized primitives chosen while removing InvokeMethod from this path.

Copy link
Member

@jkotas jkotas Mar 16, 2026

Choose a reason for hiding this comment

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

I am not following. Why are byte, double or enums missing in the list? is it not possible for COM events to return these types? It looks suspect to me that there is nint in the list, but no byte.

Copy link
Member Author

Choose a reason for hiding this comment

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

I reduced the full set of types after your comment: #125508 (comment). I think we need some test coverage for non-void types under src/test/Inerop/COM before modifying it further.

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

Labels

area-VM-coreclr community-contribution Indicates that the PR has been added by a community member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants