Skip to content

Commit

Permalink
Revert "Add IL Emit support for MethodInfo.Invoke() and friends" (#69373
Browse files Browse the repository at this point in the history
)

* Revert "Fix Assembly.GetCallingAssembly() (#69225)"

This reverts commit 8420dae.

* Revert "Add IL Emit support for MethodInfo.Invoke() and friends (#67917)"

This reverts commit 5195418.
  • Loading branch information
jkotas authored May 15, 2022
1 parent f63c10a commit fa71ffa
Show file tree
Hide file tree
Showing 45 changed files with 656 additions and 1,197 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<EnableDefaultItems>false</EnableDefaultItems>
Expand Down Expand Up @@ -155,12 +155,12 @@
<Compile Include="$(BclSourcesRoot)\System\Reflection\AssemblyName.CoreCLR.cs" />
<Compile Include="$(BclSourcesRoot)\System\Reflection\Associates.cs" />
<Compile Include="$(BclSourcesRoot)\System\Reflection\ConstructorInfo.CoreCLR.cs" />
<Compile Include="$(BclSourcesRoot)\System\Reflection\ConstructorInvoker.CoreCLR.cs" />
<Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\AssemblyBuilder.cs" />
<Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\ConstructorBuilder.cs" />
<Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\CustomAttributeBuilder.cs" />
<Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\DynamicILGenerator.cs" />
<Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\DynamicMethod.cs" />
<Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\DynamicMethodInvoker.cs" />
<Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\EnumBuilder.cs" />
<Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\EventBuilder.cs" />
<Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\FieldBuilder.cs" />
Expand All @@ -187,7 +187,6 @@
<Compile Include="$(BclSourcesRoot)\System\Reflection\Metadata\AssemblyExtensions.cs" />
<Compile Include="$(BclSourcesRoot)\System\Reflection\Metadata\MetadataUpdater.cs" />
<Compile Include="$(BclSourcesRoot)\System\Reflection\MethodBase.CoreCLR.cs" />
<Compile Include="$(BclSourcesRoot)\System\Reflection\MethodInvoker.CoreCLR.cs" />
<Compile Include="$(BclSourcesRoot)\System\Reflection\RtFieldInfo.cs" />
<Compile Include="$(BclSourcesRoot)\System\Reflection\RuntimeAssembly.cs" />
<Compile Include="$(BclSourcesRoot)\System\Reflection\RuntimeConstructorInfo.CoreCLR.cs" />
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public sealed class DynamicMethod : MethodInfo
private RuntimeModule m_module = null!;
internal bool m_skipVisibility;
internal RuntimeType? m_typeOwner; // can be null
private MethodInvoker? _invoker;
private DynamicMethodInvoker? _invoker;
private Signature? _signature;

// We want the creator of the DynamicMethod to control who has access to the
Expand Down Expand Up @@ -434,12 +434,13 @@ internal RuntimeMethodHandle GetMethodDescriptor()

public override bool IsSecurityTransparent => false;

private MethodInvoker Invoker
private DynamicMethodInvoker Invoker
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
_invoker ??= new MethodInvoker(this, Signature);
_invoker ??= new DynamicMethodInvoker(this);

return _invoker;
}
}
Expand Down Expand Up @@ -489,7 +490,7 @@ Signature LazyCreateSignature()
{
if (argCount == 0)
{
retValue = Invoker.InlinedInvoke(obj, args: default, invokeAttr);
retValue = Invoker.InvokeUnsafe(obj, args: default, invokeAttr);
}
else if (argCount > MaxStackAllocArgCount)
{
Expand All @@ -500,8 +501,8 @@ Signature LazyCreateSignature()
{
Debug.Assert(parameters != null);
StackAllocedArguments argStorage = default;
Span<object?> copyOfParameters = new(ref argStorage._arg0, argCount);
Span<ParameterCopyBackAction> shouldCopyBackParameters = new(ref argStorage._copyBack0, argCount);
Span<object?> copyOfParameters = new Span<object?>(ref argStorage._arg0, argCount);
Span<bool> shouldCopyBackParameters = new Span<bool>(ref argStorage._copyBack0, argCount);

StackAllocatedByRefs byrefStorage = default;
IntPtr* pByRefStorage = (IntPtr*)&byrefStorage;
Expand All @@ -516,25 +517,14 @@ Signature LazyCreateSignature()
culture,
invokeAttr);

retValue = Invoker.InlinedInvoke(obj, pByRefStorage, invokeAttr);
retValue = Invoker.InvokeUnsafe(obj, pByRefStorage, invokeAttr);

// Copy modified values out. This should be done only with ByRef or Type.Missing parameters.
for (int i = 0; i < argCount; i++)
{
ParameterCopyBackAction action = shouldCopyBackParameters[i];
if (action != ParameterCopyBackAction.None)
if (shouldCopyBackParameters[i])
{
if (action == ParameterCopyBackAction.Copy)
{
parameters[i] = copyOfParameters[i];
}
else
{
Debug.Assert(action == ParameterCopyBackAction.CopyNullable);
Debug.Assert(copyOfParameters[i] != null);
Debug.Assert(((RuntimeType)copyOfParameters[i]!.GetType()).IsNullableOfT);
parameters[i] = RuntimeMethodHandle.ReboxFromNullable(copyOfParameters[i]);
}
parameters[i] = copyOfParameters[i];
}
}
}
Expand All @@ -556,15 +546,15 @@ Signature LazyCreateSignature()
CultureInfo? culture)
{
object[] objHolder = new object[argCount];
Span<object?> copyOfParameters = new(objHolder, 0, argCount);
Span<object?> copyOfParameters = new Span<object?>(objHolder, 0, argCount);

// We don't check a max stack size since we are invoking a method which
// naturally requires a stack size that is dependent on the arg count\size.
IntPtr* pByRefStorage = stackalloc IntPtr[argCount];
Buffer.ZeroMemory((byte*)pByRefStorage, (uint)(argCount * sizeof(IntPtr)));

ParameterCopyBackAction* copyBackActions = stackalloc ParameterCopyBackAction[argCount];
Span<ParameterCopyBackAction> shouldCopyBackParameters = new(copyBackActions, argCount);
bool* boolHolder = stackalloc bool[argCount];
Span<bool> shouldCopyBackParameters = new Span<bool>(boolHolder, argCount);

GCFrameRegistration reg = new(pByRefStorage, (uint)argCount, areByRefs: true);

Expand All @@ -582,7 +572,7 @@ Signature LazyCreateSignature()
culture,
invokeAttr);

retValue = mi.Invoker.InlinedInvoke(obj, pByRefStorage, invokeAttr);
retValue = mi.Invoker.InvokeUnsafe(obj, pByRefStorage, invokeAttr);
}
finally
{
Expand All @@ -592,26 +582,36 @@ Signature LazyCreateSignature()
// Copy modified values out. This should be done only with ByRef or Type.Missing parameters.
for (int i = 0; i < argCount; i++)
{
ParameterCopyBackAction action = shouldCopyBackParameters[i];
if (action != ParameterCopyBackAction.None)
if (shouldCopyBackParameters[i])
{
if (action == ParameterCopyBackAction.Copy)
{
parameters[i] = copyOfParameters[i];
}
else
{
Debug.Assert(action == ParameterCopyBackAction.CopyNullable);
Debug.Assert(copyOfParameters[i] != null);
Debug.Assert(((RuntimeType)copyOfParameters[i]!.GetType()).IsNullableOfT);
parameters[i] = RuntimeMethodHandle.ReboxFromNullable(copyOfParameters[i]);
}
parameters[i] = copyOfParameters[i];
}
}

return retValue;
}

[DebuggerHidden]
[DebuggerStepThrough]
internal unsafe object? InvokeNonEmitUnsafe(object? obj, IntPtr* arguments, BindingFlags invokeAttr)
{
if ((invokeAttr & BindingFlags.DoNotWrapExceptions) == 0)
{
try
{
return RuntimeMethodHandle.InvokeMethod(obj, (void**)arguments, Signature, isConstructor: false);
}
catch (Exception e)
{
throw new TargetInvocationException(e);
}
}
else
{
return RuntimeMethodHandle.InvokeMethod(obj, (void**)arguments, Signature, isConstructor: false);
}
}

public override object[] GetCustomAttributes(Type attributeType, bool inherit)
{
return m_dynMethod.GetCustomAttributes(attributeType, inherit);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Diagnostics;
using System.Runtime.CompilerServices;

namespace System.Reflection.Emit
{
internal sealed partial class DynamicMethodInvoker
{
private readonly DynamicMethod _dynamicMethod;

public DynamicMethodInvoker(DynamicMethod dynamicMethod)
{
_dynamicMethod = dynamicMethod;
}

public unsafe object? InvokeUnsafe(object? obj, IntPtr* args, BindingFlags invokeAttr)
{
// Todo: add strategy for calling IL Emit-based version
return _dynamicMethod.InvokeNonEmitUnsafe(obj, args, invokeAttr);
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ public override void SetValue(object? obj, object? value, BindingFlags invokeAtt

CheckConsistency(obj);

ParameterCopyBackAction _ref = default;
bool _ref = false;
RuntimeType fieldType = (RuntimeType)FieldType;
if (value is null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,27 @@ Signature LazyCreateSignature()

internal BindingFlags BindingFlags => m_bindingFlags;


[DebuggerStepThrough]
[DebuggerHidden]
internal unsafe object InvokeNonEmitUnsafe(object? obj, IntPtr* args, Span<object?> argsForTemporaryMonoSupport, BindingFlags invokeAttr)
{
if ((invokeAttr & BindingFlags.DoNotWrapExceptions) == 0)
{
try
{
return RuntimeMethodHandle.InvokeMethod(obj, (void**)args, Signature, isConstructor: obj is null)!;
}
catch (Exception ex)
{
throw new TargetInvocationException(ex);
}
}
else
{
return RuntimeMethodHandle.InvokeMethod(obj, (void**)args, Signature, isConstructor: obj is null)!;
}
}
#endregion

#region Object Overrides
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ private MethodInvoker Invoker
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
m_invoker ??= new MethodInvoker(this, Signature);
m_invoker ??= new MethodInvoker(this);
return m_invoker;
}
}
Expand Down Expand Up @@ -351,7 +351,7 @@ public override MethodImplAttributes GetMethodImplementationFlags()
StackAllocedArguments argStorage = default;
Span<object?> copyOfParameters = new(ref argStorage._arg0, 1);
ReadOnlySpan<object?> parameters = new(in parameter);
Span<ParameterCopyBackAction> shouldCopyBackParameters = new(ref argStorage._copyBack0, 1);
Span<bool> shouldCopyBackParameters = new(ref argStorage._copyBack0, 1);

StackAllocatedByRefs byrefStorage = default;
IntPtr* pByRefStorage = (IntPtr*)&byrefStorage;
Expand All @@ -366,16 +366,33 @@ public override MethodImplAttributes GetMethodImplementationFlags()
culture,
invokeAttr);

#if MONO // Temporary until Mono is updated.
retValue = Invoker.InlinedInvoke(obj, copyOfParameters, invokeAttr);
#else
retValue = Invoker.InlinedInvoke(obj, pByRefStorage, invokeAttr);
#endif
retValue = Invoker.InvokeUnsafe(obj, pByRefStorage, copyOfParameters, invokeAttr);
}

return retValue;
}

[DebuggerHidden]
[DebuggerStepThrough]
internal unsafe object? InvokeNonEmitUnsafe(object? obj, IntPtr* arguments, Span<object?> argsForTemporaryMonoSupport, BindingFlags invokeAttr)
{
if ((invokeAttr & BindingFlags.DoNotWrapExceptions) == 0)
{
try
{
return RuntimeMethodHandle.InvokeMethod(obj, (void**)arguments, Signature, isConstructor: false);
}
catch (Exception e)
{
throw new TargetInvocationException(e);
}
}
else
{
return RuntimeMethodHandle.InvokeMethod(obj, (void**)arguments, Signature, isConstructor: false);
}
}

#endregion

#region MethodInfo Overrides
Expand Down
19 changes: 0 additions & 19 deletions src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs
Original file line number Diff line number Diff line change
Expand Up @@ -138,19 +138,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);
Expand Down Expand Up @@ -994,12 +981,6 @@ internal static MdUtf8String GetUtf8Name(RuntimeMethodHandleInternal method)
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern object? InvokeMethod(object? target, void** arguments, Signature sig, bool isConstructor);

[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern object? ReboxFromNullable(object? src);

[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern object ReboxToNullable(object? src, RuntimeType destNullableType);

[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeMethodHandle_GetMethodInstantiation")]
private static partial void GetMethodInstantiation(RuntimeMethodHandleInternal method, ObjectHandleOnStack types, Interop.BOOL fAsRuntimeTypeArray);

Expand Down
Loading

0 comments on commit fa71ffa

Please sign in to comment.