diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs
index 1959209bd7cc4..f1dfa36b70237 100644
--- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs
+++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs
@@ -141,19 +141,6 @@ internal static bool IsByRef(RuntimeType type)
return corElemType == CorElementType.ELEMENT_TYPE_BYREF;
}
- internal static bool TryGetByRefElementType(RuntimeType type, [NotNullWhen(true)] out RuntimeType? elementType)
- {
- CorElementType corElemType = GetCorElementType(type);
- if (corElemType == CorElementType.ELEMENT_TYPE_BYREF)
- {
- elementType = GetElementType(type);
- return true;
- }
-
- elementType = null;
- return false;
- }
-
internal static bool IsPointer(RuntimeType type)
{
CorElementType corElemType = GetCorElementType(type);
diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs
index fdfc88b419e4a..a60920aa83c20 100644
--- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs
+++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs
@@ -3582,180 +3582,10 @@ public override Type MakeArrayType(int rank)
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern object AllocateValueType(RuntimeType type, object? value);
- private enum CheckValueStatus
- {
- Success = 0,
- ArgumentException,
- NotSupported_ByRefLike
- }
-
- ///
- /// Verify and optionally convert the value for special cases.
- ///
- /// True if is a value type, False otherwise
- internal bool CheckValue(
- ref object? value,
- ref ParameterCopyBackAction copyBack,
- Binder? binder,
- CultureInfo? culture,
- BindingFlags invokeAttr)
- {
- // Already fast-pathed by the caller.
- Debug.Assert(!ReferenceEquals(value?.GetType(), this));
-
- // Since this cannot be a generic parameter, we use RuntimeTypeHandle.IsValueType here
- // because it is faster than IsValueType
- Debug.Assert(!IsGenericParameter);
-
- // Fast path to whether a value can be assigned without conversion.
- if (IsInstanceOfType(value))
- {
- if (IsNullableOfT)
- {
- // Pass as a true boxed Nullable, not as a T or null.
- value = RuntimeMethodHandle.ReboxToNullable(value, this);
- return true;
- }
-
- // Other value types won't get here since Type equality was previous checked.
- Debug.Assert(!RuntimeTypeHandle.IsValueType(this));
-
- return false;
- }
-
- bool isValueType;
- CheckValueStatus result = TryChangeType(ref value, ref copyBack, out isValueType);
- if (result == CheckValueStatus.Success)
- {
- return isValueType;
- }
-
- if (result == CheckValueStatus.ArgumentException && (invokeAttr & BindingFlags.ExactBinding) == 0)
- {
- Debug.Assert(value != null);
-
- // Use the binder
- if (binder != null && binder != DefaultBinder)
- {
- value = binder.ChangeType(value, this, culture);
- if (IsInstanceOfType(value))
- {
- if (IsNullableOfT)
- {
- // Pass as a true boxed Nullable, not as a T or null.
- value = RuntimeMethodHandle.ReboxToNullable(value, this);
- copyBack = ParameterCopyBackAction.CopyNullable;
- }
- else
- {
- copyBack = ParameterCopyBackAction.Copy;
- }
-
- return IsValueType; // Note the call to IsValueType, not the variable.
- }
-
- result = TryChangeType(ref value, ref copyBack, out isValueType);
- if (result == CheckValueStatus.Success)
- {
- return isValueType;
- }
- }
- }
-
- switch (result)
- {
- case CheckValueStatus.ArgumentException:
- throw new ArgumentException(SR.Format(SR.Arg_ObjObjEx, value?.GetType(), this));
- case CheckValueStatus.NotSupported_ByRefLike:
- throw new NotSupportedException(SR.NotSupported_ByRefLike);
- }
-
- Debug.Fail("Error result not expected");
- return false;
- }
-
- private CheckValueStatus TryChangeType(
- ref object? value,
- ref ParameterCopyBackAction copyBack,
+ private CheckValueStatus TryChangeTypeSpecial(
+ ref object value,
out bool isValueType)
{
- RuntimeType? sigElementType;
- if (RuntimeTypeHandle.TryGetByRefElementType(this, out sigElementType))
- {
- copyBack = ParameterCopyBackAction.Copy;
- Debug.Assert(!sigElementType.IsGenericParameter);
-
- if (sigElementType.IsInstanceOfType(value))
- {
- isValueType = RuntimeTypeHandle.IsValueType(sigElementType);
- if (isValueType)
- {
- if (sigElementType.IsNullableOfT)
- {
- // Pass as a true boxed Nullable, not as a T or null.
- value = RuntimeMethodHandle.ReboxToNullable(value, sigElementType);
- copyBack = ParameterCopyBackAction.CopyNullable;
- }
- else
- {
- // Make a copy to prevent the boxed instance from being directly modified by the method.
- value = AllocateValueType(sigElementType, value);
- }
- }
-
- return CheckValueStatus.Success;
- }
-
- if (value == null)
- {
- isValueType = RuntimeTypeHandle.IsValueType(sigElementType);
- if (!isValueType)
- {
- // Normally we don't get here since 'null' was previosuly checked, but due to binders we can.
- return CheckValueStatus.Success;
- }
-
- if (sigElementType.IsByRefLike)
- {
- return CheckValueStatus.NotSupported_ByRefLike;
- }
-
- // Allocate default.
- value = AllocateValueType(sigElementType, value: null);
- copyBack = sigElementType.IsNullableOfT ? ParameterCopyBackAction.CopyNullable : ParameterCopyBackAction.Copy;
- return CheckValueStatus.Success;
- }
-
- isValueType = false;
- return CheckValueStatus.ArgumentException;
- }
-
- if (value == null)
- {
- isValueType = RuntimeTypeHandle.IsValueType(this);
- if (!isValueType)
- {
- // Normally we don't get here since 'null' was previosuly checked, but due to binders we can.
- return CheckValueStatus.Success;
- }
-
- if (IsByRefLike)
- {
- return CheckValueStatus.NotSupported_ByRefLike;
- }
-
- // Allocate default.
- value = AllocateValueType(this, value: null);
- return CheckValueStatus.Success;
- }
-
- // Check the strange ones courtesy of reflection:
- // - Implicit cast between primitives
- // - Enum treated as underlying type
- // - Pointer (*) types to IntPtr (if dest is IntPtr)
- // - System.Reflection.Pointer to appropriate pointer (*) type (if dest is pointer type)
- if (IsPointer || IsEnum || IsPrimitive)
- {
Pointer? pointer = value as Pointer;
RuntimeType srcType = pointer != null ? pointer.GetPointerType() : (RuntimeType)value.GetType();
@@ -3781,38 +3611,6 @@ private CheckValueStatus TryChangeType(
isValueType = true;
return CheckValueStatus.Success;
- }
-
- isValueType = false;
- return CheckValueStatus.ArgumentException;
- }
-
- internal bool TryByRefFastPath(ref object arg, ref bool isValueType)
- {
- if (RuntimeTypeHandle.TryGetByRefElementType(this, out RuntimeType? sigElementType) &&
- ReferenceEquals(sigElementType, arg.GetType()))
- {
- isValueType = sigElementType.IsValueType;
- if (isValueType)
- {
- // Make a copy to prevent the boxed instance from being directly modified by the method.
- arg = AllocateValueType(sigElementType, arg);
- }
-
- return true;
- }
-
- return false;
- }
-
- internal static CorElementType GetUnderlyingType(RuntimeType type)
- {
- if (type.IsActualEnum)
- {
- type = (RuntimeType)Enum.GetUnderlyingType(type);
- }
-
- return RuntimeTypeHandle.GetCorElementType(type);
}
#endregion
diff --git a/src/libraries/Common/tests/System/Reflection/InvokeEmitTests.cs b/src/libraries/Common/tests/System/Reflection/InvokeEmitTests.cs
index c81da708294f1..d6345d3e92314 100644
--- a/src/libraries/Common/tests/System/Reflection/InvokeEmitTests.cs
+++ b/src/libraries/Common/tests/System/Reflection/InvokeEmitTests.cs
@@ -35,8 +35,7 @@ public static void VerifyInvokeIsUsingEmit_Constructor()
private static bool IsEmitInvokeSupported()
{
// Emit is only used for Invoke when RuntimeFeature.IsDynamicCodeCompiled is true.
- return RuntimeFeature.IsDynamicCodeCompiled
- && !PlatformDetection.IsMonoRuntime; // Temporary until Mono is updated.
+ return RuntimeFeature.IsDynamicCodeCompiled;
}
private static string InterpretedMethodName => PlatformDetection.IsMonoRuntime ?
diff --git a/src/libraries/Common/tests/System/Reflection/InvokeInterpretedTests.cs b/src/libraries/Common/tests/System/Reflection/InvokeInterpretedTests.cs
index 5d4347e82d885..a197da333f16d 100644
--- a/src/libraries/Common/tests/System/Reflection/InvokeInterpretedTests.cs
+++ b/src/libraries/Common/tests/System/Reflection/InvokeInterpretedTests.cs
@@ -8,6 +8,7 @@ namespace System.Reflection.Tests
public class InvokeInterpretedTests
{
[Fact]
+ [ActiveIssue("https://github.com/dotnet/runtime/issues/50957", typeof(PlatformDetection), nameof(PlatformDetection.IsBrowser), nameof(PlatformDetection.IsMonoAOT))]
public static void VerifyInvokeIsUsingEmit_Method()
{
MethodInfo method = typeof(TestClassThatThrows).GetMethod(nameof(TestClassThatThrows.Throw))!;
@@ -24,6 +25,7 @@ string InterpretedMethodName() => PlatformDetection.IsMonoRuntime ?
}
[Fact]
+ [ActiveIssue("https://github.com/dotnet/runtime/issues/50957", typeof(PlatformDetection), nameof(PlatformDetection.IsBrowser), nameof(PlatformDetection.IsMonoAOT))]
public static void VerifyInvokeIsUsingEmit_Constructor()
{
ConstructorInfo ctor = typeof(TestClassThatThrows).GetConstructor(Type.EmptyTypes)!;
diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/ConstructorInvoker.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/ConstructorInvoker.cs
index d5f173eac1870..9b581a305afde 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Reflection/ConstructorInvoker.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/ConstructorInvoker.cs
@@ -10,17 +10,14 @@ internal sealed partial class ConstructorInvoker
{
private readonly RuntimeConstructorInfo _method;
-#if !MONO // Temporary until Mono is updated.
private bool _invoked;
private bool _strategyDetermined;
private InvokerEmitUtil.InvokeFunc? _invokeFunc;
-#endif
public ConstructorInvoker(RuntimeConstructorInfo constructorInfo)
{
_method = constructorInfo;
-#if !MONO // Temporary until Mono is updated.
if (LocalAppContextSwitches.ForceInterpretedInvoke && !LocalAppContextSwitches.ForceEmitInvoke)
{
// Always use the native invoke; useful for testing.
@@ -31,13 +28,9 @@ public ConstructorInvoker(RuntimeConstructorInfo constructorInfo)
// Always use emit invoke (if IsDynamicCodeCompiled == true); useful for testing.
_invoked = true;
}
-#endif
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
-#if MONO // Temporary until Mono is updated.
- public unsafe object? InlinedInvoke(object? obj, Span