-
Notifications
You must be signed in to change notification settings - Fork 128
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
Support RunClassConstructor in the linker #1121
Conversation
…_RunClassConstructor -Add Support for RuntimeHelpers.RunClassConstructor -Add test for RunClassConstructor -Change MarkStaticConstructor to internal in order to be able to call it from ReflectionMethodBodyScanner
test/Mono.Linker.Tests.Cases/Reflection/RunClassConstructorUsedViaReflection.cs
Show resolved
Hide resolved
test/Mono.Linker.Tests.Cases/Reflection/RunClassConstructorUsedViaReflection.cs
Show resolved
Hide resolved
var parameters = calledMethod.Parameters; | ||
foreach (var TypeHandleValue in methodParams [0].UniqueValues ()) { | ||
if (TypeHandleValue is RuntimeTypeHandleValue runtimeTypeHandleValue) { | ||
_markStep.MarkStaticConstructor (runtimeTypeHandleValue.TypeRepresented, new DependencyInfo (DependencyKind.AccessedViaReflection, reflectionContext.MethodCalling)); |
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.
Should this really be in DependencyKind.AccessedViaReflection
category?
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.
We could create a new one I guess. But it's not that different from something like type.GetConstructor().Invoke()
. I do think it's still reflection, even if the method/type is not in the reflection namespace.
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.
If we made a new category for this, it would set a precedent and we'll need yet another category for e.g. FormatterServices.GetUninitializedObject
- these are all reflection-like APIs...
for RunClassConstructor -Indent default for calledMethod.Name switch -IntrinsicId.Type_get_TypeHandle needs to handle MergePointValues -Handle NullValue inside IntrinsicId.Type_get_TypeHandle for MergePointValues -Change RequireDynamicallyAccessedMembers call si MergePointVallyAccessedMemberKinds.DefaultConstructor does not mantain static .cctor and implement a way to handle Null values and unrecognized patterns -Add more information into test, Recognized and Unrecognized patterns -Differentiate test that use a Type from the ones that use a RuntimeTypeHandle
-Add test of unknown value in conditional
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.
Except for the couple comments this looks good.
test/Mono.Linker.Tests.Cases/Reflection/RunClassConstructorUsedViaReflection.cs
Outdated
Show resolved
Hide resolved
-Edit error message to give more information to the user
var parameters = calledMethod.Parameters; | ||
foreach (var TypeHandleValue in methodParams [0].UniqueValues ()) { | ||
if (TypeHandleValue is RuntimeTypeHandleValue runtimeTypeHandleValue) { | ||
_markStep.MarkStaticConstructor (runtimeTypeHandleValue.TypeRepresented, new DependencyInfo (DependencyKind.AccessedViaReflection, reflectionContext.MethodCalling)); |
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.
If we made a new category for this, it would set a precedent and we'll need yet another category for e.g. FormatterServices.GetUninitializedObject
- these are all reflection-like APIs...
} else if (typeHandleValue == NullValue.Instance) | ||
reflectionContext.RecordHandledPattern (); | ||
else { | ||
reflectionContext.RecordUnrecognizedPattern ($"A {GetValueDescriptionForErrorMessage (typeHandleValue)} " + |
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.
Nit/not really necessary: If we really wanted - the MemberKinds.Constructors
dataflow annotation keeps static constructors because they can be accessed with typeof(Foo).GetConstructors(BindingFlags.NonPublic | BindingFlags.Static)
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.
Good point. For now I would leave it as is. Supporting the annotation would mean to flow it through the get_TypeHandle call as well. Until we hit a use case I'm perfectly fine supporting just the simple constant cases.
…lassConstructor
-Update to master
Support RunClassConstructor in the linker Commit migrated from dotnet/linker@17b3c01
This fixes #970
-Add Support for RuntimeHelpers.RunClassConstructor
-Add test for RunClassConstructor
-Change MarkStaticConstructor to internal in order to be able to call it
from ReflectionMethodBodyScanner