Skip to content

Commit dc34018

Browse files
Maybe we don't need #92994
Reverts #92994 (manually since there were many merge conflicts due to EETypePtr deletion.)
1 parent b728c83 commit dc34018

File tree

3 files changed

+40
-70
lines changed

3 files changed

+40
-70
lines changed

src/coreclr/nativeaot/System.Private.CoreLib/src/System/InvokeUtils.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -409,11 +409,8 @@ private static Exception CreateChangeTypeException(MethodTable* srcEEType, Metho
409409
}
410410

411411
internal static ArgumentException CreateChangeTypeArgumentException(MethodTable* srcEEType, MethodTable* dstEEType, bool destinationIsByRef = false)
412-
=> CreateChangeTypeArgumentException(srcEEType, Type.GetTypeFromHandle(new RuntimeTypeHandle(dstEEType)), destinationIsByRef);
413-
414-
internal static ArgumentException CreateChangeTypeArgumentException(MethodTable* srcEEType, Type dstType, bool destinationIsByRef = false)
415412
{
416-
object? destinationTypeName = dstType;
413+
object? destinationTypeName = Type.GetTypeFromHandle(new RuntimeTypeHandle(dstEEType));
417414
if (destinationIsByRef)
418415
destinationTypeName += "&";
419416
return new ArgumentException(SR.Format(SR.Arg_ObjObjEx, Type.GetTypeFromHandle(new RuntimeTypeHandle(srcEEType)), destinationTypeName));

src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/DynamicInvokeInfo.cs

Lines changed: 36 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -74,37 +74,36 @@ public unsafe DynamicInvokeInfo(MethodBase method, IntPtr invokeThunk)
7474
{
7575
Transform transform = default;
7676

77-
var argumentType = (RuntimeType)parameters[i].ParameterType;
77+
Type argumentType = parameters[i].ParameterType;
7878
if (argumentType.IsByRef)
7979
{
8080
_needsCopyBack = true;
8181
transform |= Transform.ByRef;
82-
argumentType = (RuntimeType)argumentType.GetElementType()!;
82+
argumentType = argumentType.GetElementType()!;
8383
}
8484
Debug.Assert(!argumentType.IsByRef);
8585

86-
// This can return a null MethodTable for reference types.
87-
// The compiler makes sure it returns a non-null MT for everything else.
88-
MethodTable* eeArgumentType = argumentType.ToMethodTableMayBeNull();
89-
if (argumentType.IsValueType)
86+
MethodTable* eeArgumentType = argumentType.TypeHandle.ToMethodTable();
87+
88+
if (eeArgumentType->IsValueType)
9089
{
91-
Debug.Assert(eeArgumentType->IsValueType);
90+
Debug.Assert(argumentType.IsValueType);
9291

9392
if (eeArgumentType->IsByRefLike)
9493
_argumentCount = ArgumentCount_NotSupported_ByRefLike;
9594

9695
if (eeArgumentType->IsNullable)
9796
transform |= Transform.Nullable;
9897
}
99-
else if (argumentType.IsPointer)
98+
else if (eeArgumentType->IsPointer)
10099
{
101-
Debug.Assert(eeArgumentType->IsPointer);
100+
Debug.Assert(argumentType.IsPointer);
102101

103102
transform |= Transform.Pointer;
104103
}
105-
else if (argumentType.IsFunctionPointer)
104+
else if (eeArgumentType->IsFunctionPointer)
106105
{
107-
Debug.Assert(eeArgumentType->IsFunctionPointer);
106+
Debug.Assert(argumentType.IsFunctionPointer);
108107

109108
transform |= Transform.FunctionPointer;
110109
}
@@ -122,18 +121,19 @@ public unsafe DynamicInvokeInfo(MethodBase method, IntPtr invokeThunk)
122121
{
123122
Transform transform = default;
124123

125-
var returnType = (RuntimeType)methodInfo.ReturnType;
124+
Type returnType = methodInfo.ReturnType;
126125
if (returnType.IsByRef)
127126
{
128127
transform |= Transform.ByRef;
129-
returnType = (RuntimeType)returnType.GetElementType()!;
128+
returnType = returnType.GetElementType()!;
130129
}
131130
Debug.Assert(!returnType.IsByRef);
132131

133-
MethodTable* eeReturnType = returnType.ToMethodTableMayBeNull();
134-
if (returnType.IsValueType)
132+
MethodTable* eeReturnType = returnType.TypeHandle.ToMethodTable();
133+
134+
if (eeReturnType->IsValueType)
135135
{
136-
Debug.Assert(eeReturnType->IsValueType);
136+
Debug.Assert(returnType.IsValueType);
137137

138138
if (returnType != typeof(void))
139139
{
@@ -152,17 +152,17 @@ public unsafe DynamicInvokeInfo(MethodBase method, IntPtr invokeThunk)
152152
_argumentCount = ArgumentCount_NotSupported; // ByRef to void return
153153
}
154154
}
155-
else if (returnType.IsPointer)
155+
else if (eeReturnType->IsPointer)
156156
{
157-
Debug.Assert(eeReturnType->IsPointer);
157+
Debug.Assert(returnType.IsPointer);
158158

159159
transform |= Transform.Pointer;
160160
if ((transform & Transform.ByRef) == 0)
161161
transform |= Transform.AllocateReturnBox;
162162
}
163-
else if (returnType.IsFunctionPointer)
163+
else if (eeReturnType->IsFunctionPointer)
164164
{
165-
Debug.Assert(eeReturnType->IsFunctionPointer);
165+
Debug.Assert(returnType.IsFunctionPointer);
166166

167167
transform |= Transform.FunctionPointer;
168168
if ((transform & Transform.ByRef) == 0)
@@ -585,12 +585,6 @@ private unsafe ref byte InvokeDirectWithFewArguments(
585585
return defaultValue;
586586
}
587587

588-
private void ThrowForNeverValidNonNullArgument(MethodTable* srcEEType, int index)
589-
{
590-
Debug.Assert(index != 0 || _isStatic);
591-
throw InvokeUtils.CreateChangeTypeArgumentException(srcEEType, Method.GetParametersAsSpan()[index - (_isStatic ? 0 : 1)].ParameterType, destinationIsByRef: false);
592-
}
593-
594588
private unsafe void CheckArguments(
595589
Span<object?> copyOfParameters,
596590
void* byrefParameters,
@@ -630,25 +624,16 @@ private unsafe void CheckArguments(
630624
MethodTable* srcEEType = arg.GetMethodTable();
631625
MethodTable* dstEEType = argumentInfo.Type;
632626

633-
if (srcEEType != dstEEType)
634-
{
635-
// Destination type can be null if we don't have a MethodTable for this type. This means one cannot
636-
// possibly pass a valid non-null object instance here.
637-
if (dstEEType == null)
638-
{
639-
ThrowForNeverValidNonNullArgument(srcEEType, i);
640-
}
641-
642-
if (!(RuntimeImports.AreTypesAssignable(srcEEType, dstEEType) ||
643-
(dstEEType->IsInterface && arg is System.Runtime.InteropServices.IDynamicInterfaceCastable castable
627+
if (!(srcEEType == dstEEType ||
628+
RuntimeImports.AreTypesAssignable(srcEEType, dstEEType) ||
629+
(dstEEType->IsInterface && arg is System.Runtime.InteropServices.IDynamicInterfaceCastable castable
644630
&& castable.IsInterfaceImplemented(new RuntimeTypeHandle(dstEEType), throwIfNotImplemented: false))))
645-
{
646-
// ByRefs have to be exact match
647-
if ((argumentInfo.Transform & Transform.ByRef) != 0)
648-
throw InvokeUtils.CreateChangeTypeArgumentException(srcEEType, argumentInfo.Type, destinationIsByRef: true);
631+
{
632+
// ByRefs have to be exact match
633+
if ((argumentInfo.Transform & Transform.ByRef) != 0)
634+
throw InvokeUtils.CreateChangeTypeArgumentException(srcEEType, argumentInfo.Type, destinationIsByRef: true);
649635

650-
arg = InvokeUtils.CheckArgumentConversions(arg, argumentInfo.Type, InvokeUtils.CheckArgumentSemantics.DynamicInvoke, binderBundle);
651-
}
636+
arg = InvokeUtils.CheckArgumentConversions(arg, argumentInfo.Type, InvokeUtils.CheckArgumentSemantics.DynamicInvoke, binderBundle);
652637
}
653638

654639
if ((argumentInfo.Transform & Transform.Reference) == 0)
@@ -707,25 +692,16 @@ private unsafe void CheckArguments(
707692
MethodTable* srcEEType = arg.GetMethodTable();
708693
MethodTable* dstEEType = argumentInfo.Type;
709694

710-
if (srcEEType != dstEEType)
711-
{
712-
// Destination type can be null if we don't have a MethodTable for this type. This means one cannot
713-
// possibly pass a valid non-null object instance here.
714-
if (dstEEType == null)
715-
{
716-
ThrowForNeverValidNonNullArgument(srcEEType, i);
717-
}
718-
719-
if (!(RuntimeImports.AreTypesAssignable(srcEEType, dstEEType) ||
720-
(dstEEType->IsInterface && arg is System.Runtime.InteropServices.IDynamicInterfaceCastable castable
695+
if (!(srcEEType == dstEEType ||
696+
RuntimeImports.AreTypesAssignable(srcEEType, dstEEType) ||
697+
(dstEEType->IsInterface && arg is System.Runtime.InteropServices.IDynamicInterfaceCastable castable
721698
&& castable.IsInterfaceImplemented(new RuntimeTypeHandle(dstEEType), throwIfNotImplemented: false))))
722-
{
723-
// ByRefs have to be exact match
724-
if ((argumentInfo.Transform & Transform.ByRef) != 0)
725-
throw InvokeUtils.CreateChangeTypeArgumentException(srcEEType, argumentInfo.Type, destinationIsByRef: true);
699+
{
700+
// ByRefs have to be exact match
701+
if ((argumentInfo.Transform & Transform.ByRef) != 0)
702+
throw InvokeUtils.CreateChangeTypeArgumentException(srcEEType, argumentInfo.Type, destinationIsByRef: true);
726703

727-
arg = InvokeUtils.CheckArgumentConversions(arg, argumentInfo.Type, InvokeUtils.CheckArgumentSemantics.DynamicInvoke, binderBundle: null);
728-
}
704+
arg = InvokeUtils.CheckArgumentConversions(arg, argumentInfo.Type, InvokeUtils.CheckArgumentSemantics.DynamicInvoke, binderBundle: null);
729705
}
730706

731707
if ((argumentInfo.Transform & Transform.Reference) == 0)

src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ReflectionInvokeMapNode.cs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -112,12 +112,9 @@ internal static void AddSignatureDependency(ref DependencyList dependencies, Nod
112112
if (type.IsPrimitive || type.IsVoid)
113113
return;
114114

115-
// Reflection doesn't need the ability to generate MethodTables out of thin air for reference types.
116-
// Skip generating the dependencies.
117-
if (type.IsGCPointer)
118-
return;
119-
120-
if (isOut)
115+
// Reflection might need to create boxed instances of valuetypes as part of reflection invocation.
116+
// Non-valuetypes are only needed for the purposes of casting/type checks.
117+
if (isOut && !type.IsGCPointer)
121118
dependencies.Add(factory.MaximallyConstructableType(type.NormalizeInstantiation()), reason);
122119
else
123120
dependencies.Add(factory.NecessaryTypeSymbol(type.NormalizeInstantiation()), reason);

0 commit comments

Comments
 (0)