Skip to content
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

Add reflection introspection support for function pointers #81006

Merged
merged 24 commits into from
Feb 16, 2023

Conversation

steveharter
Copy link
Member

@steveharter steveharter commented Jan 22, 2023

Function pointers are now supported via reflection introspection in both the runtime (CoreClr) and MetadataLoadContext. This closes a reflection introspection functionality gap that has existed since the beginning of .NET but has become more prevalent since .NET 5.0 with the C# support for function pointers. It is now possible to fully enumerate function pointers parameters and the return value to find all of the referenced types as well as inspect calling conventions.

Fixes #69273
Fixes #43791

See the Design for details and previous discussions.

Mono and Native support will come later. The managed code and tests are designed to be shared. Tests are also shared between runtime and MetadataLoadContext.

@steveharter steveharter added this to the 8.0.0 milestone Jan 22, 2023
@steveharter steveharter self-assigned this Jan 22, 2023
@ghost
Copy link

ghost commented Jan 22, 2023

Tagging subscribers to this area: @dotnet/area-system-reflection
See info in area-owners.md if you want to be subscribed.

Issue Details

[WIP]

Author: steveharter
Assignees: steveharter
Labels:

area-System.Reflection

Milestone: 8.0.0

@dotnet-issue-labeler
Copy link

Note regarding the new-api-needs-documentation label:

This serves as a reminder for when your PR is modifying a ref *.cs file and adding/modifying public APIs, to please make sure the API implementation in the src *.cs file is documented with triple slash comments, so the PR reviewers can sign off that change.

src/coreclr/vm/typekey.h Outdated Show resolved Hide resolved
@steveharter steveharter marked this pull request as ready for review January 24, 2023 01:01
@steveharter steveharter added the breaking-change Issue or PR that represents a breaking API or functional change over a prerelease. label Jan 24, 2023
@ghost ghost added the needs-breaking-change-doc-created Breaking changes need an issue opened with https://github.com/dotnet/docs/issues/new?template=dotnet label Jan 24, 2023
@ghost
Copy link

ghost commented Jan 24, 2023

Added needs-breaking-change-doc-created label because this PR has the breaking-change label.

When you commit this breaking change:

  1. Create and link to this PR and the issue a matching issue in the dotnet/docs repo using the breaking change documentation template, then remove this needs-breaking-change-doc-created label.
  2. Ask a committer to mail the .NET Breaking Change Notification DL.

Tagging @dotnet/compat for awareness of the breaking change.

Copy link
Contributor

@buyaa-n buyaa-n left a comment

Choose a reason for hiding this comment

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

Left a few NITs, overall LGTM thanks!

src/coreclr/utilcode/sigparser.cpp Show resolved Hide resolved
src/libraries/Common/tests/System/FunctionPointerTests.cs Outdated Show resolved Hide resolved
return GetCustomModifiers(required: false);
}

// Modified types do not support Equals other than when references are equal.
Copy link
Member

Choose a reason for hiding this comment

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

I am wondering whether it would be better to throw from Equals and GetHashCode instead.

I do not think that this Equals implementation can be ever used for anything useful, and it is not what one would expect. Throwing would make it obvious.

Copy link
Member Author

Choose a reason for hiding this comment

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

Copy link
Member Author

Choose a reason for hiding this comment

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

It turns out MetadataLoadContext does use Equals\GetHashCode for caching; determining options.

Copy link
Member

Choose a reason for hiding this comment

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

Does it mean that the cache is broken or ineffective in the current version of the PR?

Copy link
Member Author

Choose a reason for hiding this comment

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

Ineffective; changing code to not cache for modified types and ensuring test coverage.

@jkotas
Copy link
Member

jkotas commented Feb 15, 2023

/azp run runtime-extra-platforms

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@steveharter
Copy link
Member Author

/azp run runtime-extra-platforms

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@steveharter
Copy link
Member Author

steveharter commented Feb 15, 2023

OSX errors due to #82240

Mono source gen errors due to #81249

Below are various runtime-extra-platform CI errors that appear unrelated:

RestApiException`1: The response contained an invalid status code 500 Internal Server Error
Body: {"Message":"An error occured.","ActivityId":"7faed39a15b124fd31a066b17c04b2c8"}
   at Microsoft.DotNet.Helix.Client.Storage.OnNewFailed(Request req, Response res) in /_/src/Microsoft.DotNet.Helix/Client/CSharp/generated-code/Storage.cs:line 202
   at Microsoft.DotNet.Helix.Client.Storage.NewAsync(ContainerCreationRequest body, CancellationToken cancellationToken) in /_/src/Microsoft.DotNet.Helix/Client/CSharp/generated-code/Storage.cs:line 164
   at Microsoft.DotNet.Helix.Client.ApiBlobHelper.GetContainerAsync(String requestedName, String targetQueue, CancellationToken cancellationToken) in /_/src/Microsoft.DotNet.Helix/JobSender/StorageHelpers/ApiBlobHelper.cs:line 25
   at Microsoft.DotNet.Helix.Client.JobDefinition.SendAsync(Action`1 log, CancellationToken cancellationToken) in /_/src/Microsoft.DotNet.Helix/JobSender/JobDefinition.cs:line 174
   at Microsoft.DotNet.Helix.Sdk.SendHelixJob.ExecuteCore(CancellationToken cancellationToken) in /_/src/Microsoft.DotNet.Helix/Sdk/SendHelixJob.cs:line 267
   at Microsoft.DotNet.Helix.Sdk.HelixTask.Execute() in /_/src/Microsoft.DotNet.Helix/Sdk/HelixTask.cs:line 58

Issue #80976:

Metadata file '/Users/runner/work/1/s/artifacts/bin/StartupHookForFunctionalTest/Release/net8.0/iossimulator-x64/StartupHookForFunctionalTest.dll' could not be found

Issue #82141:

    MonoTests.System.Drawing.GraphicsTest.Rotate [FAIL]
      Microsoft.DotNet.XUnitExtensions.SkipTestException : Precision on float numbers
      Stack Trace:
        /_/src/libraries/System.Drawing.Common/tests/mono/System.Drawing/GraphicsTests.cs(2385,0): at MonoTests.System.Drawing.GraphicsTest.Rotate()
           at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
        /_/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodInvoker.cs(59,0): at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)
    MonoTests.System.Drawing.GraphicsTest.VisibleClipBound_BigClip [FAIL]
      Microsoft.DotNet.XUnitExtensions.SkipTestException : Precision on float numbers
      Stack Trace:
        /_/src/libraries/System.Drawing.Common/tests/mono/System.Drawing/GraphicsTests.cs(2338,0): at MonoTests.System.Drawing.GraphicsTest.VisibleClipBound_BigClip()
           at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
        /_/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodInvoker.cs(59,0): at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)
    MonoTests.System.Drawing.GraphicsTest.VisibleClipBound [FAIL]
      Microsoft.DotNet.XUnitExtensions.SkipTestException : Precision on float numbers
      Stack Trace:
        /_/src/libraries/System.Drawing.Common/tests/mono/System.Drawing/GraphicsTests.cs(2302,0): at MonoTests.System.Drawing.GraphicsTest.VisibleClipBound()
           at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
        /_/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodInvoker.cs(59,0): at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)

Issue #82022; NativeAOT failures in Caching and EventSource; this PR did not change NativeAOT)

----- start Wed 02/15/2023 22:51:58.16 ===============  To repro directly: ===================================================== 
pushd C:\h\w\AB95098E\w\AEBC094D\e\
Microsoft.Extensions.Logging.EventSource.Tests.exe -notrait category=IgnoreForCI -notrait category=OuterLoop -notrait category=failing -xml testResults.xml 
popd
===========================================================================================================

C:\h\w\AB95098E\w\AEBC094D\e>Microsoft.Extensions.Logging.EventSource.Tests.exe -notrait category=IgnoreForCI -notrait category=OuterLoop -notrait category=failing -xml testResults.xml  
Running assembly:Microsoft.Extensions.Logging.EventSource.Tests, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60
----- end Wed 02/15/2023 22:52:03.43 ----- exit code -2147483645 ----------------------------------------------------------
2023-02-15T22:52:05.777Z	INFO   	run.py	run(48)	main	Beginning reading of test results.
2023-02-15T22:52:05.777Z	INFO   	run.py	__init__(42)	read_results	Searching 'C:\h\w\AB95098E\w\AEBC094D\e' for test results files
2023-02-15T22:52:05.777Z	INFO   	run.py	__init__(42)	read_results	Searching 'C:\h\w\AB95098E\w\AEBC094D\uploads' for test results files
2023-02-15T22:52:05.793Z	WARNING	run.py	__init__(55)	read_results	No results file found in any of the following formats: xunit, junit, trx
2023-02-15T22:52:05.793Z	INFO   	run.py	packing_test_reporter(30)	report_results	Packing 0 test reports to 'C:\h\w\AB95098E\w\AEBC094D\e\__test_report.json'
2023-02-15T22:52:05.793Z	INFO   	run.py	packing_test_reporter(33)	report_results	Packed 1543 bytes
ERROR: The process "corerun.exe" not found.
read file: C:\h\w\AB95098E\p\debug-dump-template.md
writing output file: C:\h\w\AB95098E\w\AEBC094D\uploads\how-to-debug-dump.md
done writing debug dump information
['Microsoft.Extensions.Logging.EventSource.Tests' END OF WORK ITEM LOG: Command exited with -2147483645]

Copy link
Member

@jkotas jkotas left a comment

Choose a reason for hiding this comment

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

LGTM!

@steveharter
Copy link
Member Author

Breaking change doc: dotnet/docs#34623

@steveharter steveharter removed the needs-breaking-change-doc-created Breaking changes need an issue opened with https://github.com/dotnet/docs/issues/new?template=dotnet label Mar 16, 2023
MichalStrehovsky added a commit to MichalStrehovsky/runtime that referenced this pull request Apr 14, 2023
After dotnet#81006, the calling convention is no longer part of the type system identity of a function pointer type - it serves more like a modopt as far as the type system is concerned. The type system only cares whether the pointer is managed or not. Adjust the managed type system accordingly:

* If we're reading/representing a standalone method signature, read it as usual. Calling convention is available in flags/modopts.
* If we're reading/representing a function pointer type, collapse the calling convention information into the managed/unmanaged bit only.
@ghost ghost locked as resolved and limited conversation to collaborators Apr 15, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.Reflection blog-candidate Completed PRs that are candidate topics for blog post coverage breaking-change Issue or PR that represents a breaking API or functional change over a prerelease. new-api-needs-documentation
Projects
None yet
7 participants