Skip to content

Commit

Permalink
#2 Silence a few more warnings
Browse files Browse the repository at this point in the history
  • Loading branch information
sguldmund committed Jan 12, 2024
1 parent be98705 commit e614fd9
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 152 deletions.
6 changes: 3 additions & 3 deletions src/Pose/Extensions/ILGeneratorExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
using System;
using System.Reflection;
using System.Reflection.Emit;

namespace Pose.Extensions
{
// ReSharper disable once InconsistentNaming
internal static class ILGeneratorExtensions
{
// ReSharper disable once InconsistentNaming
public static byte[] GetILBytes(this ILGenerator ilGenerator)
{
var bakeByteArray = typeof(ILGenerator).GetMethod("BakeByteArray", BindingFlags.Instance | BindingFlags.NonPublic);
var bakeByteArray = typeof(ILGenerator).GetMethod("BakeByteArray", BindingFlags.Instance | BindingFlags.NonPublic)
?? throw new Exception($"Cannot get method BakeByteArray from type {nameof(ILGenerator)}");
var ilBytes = (byte[])bakeByteArray.Invoke(ilGenerator, null);
return ilBytes;
}
Expand Down
4 changes: 2 additions & 2 deletions src/Pose/Helpers/ShimHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,10 @@ public static void ValidateReplacementMethodSignature(MethodBase original, Metho
if ((isValueType && !isStaticOrConstructor ? validOwningType.MakeByRefType() : validOwningType) != shimOwningType)
throw new InvalidShimSignatureException("Mismatched instance types");

if (validParameterTypes.Count() != shimParameterTypes.Count())
if (validParameterTypes.Length != shimParameterTypes.Length)
throw new InvalidShimSignatureException("Parameters count do not match");

for (var i = 0; i < validParameterTypes.Count(); i++)
for (var i = 0; i < validParameterTypes.Length; i++)
{
if (validParameterTypes.ElementAt(i) != shimParameterTypes.ElementAt(i))
throw new InvalidShimSignatureException($"Parameter types at {i} do not match");
Expand Down
1 change: 0 additions & 1 deletion src/Pose/IL/MethodDisassembler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ public MethodDisassembler(MethodBase method)
_method = method ?? throw new ArgumentNullException(nameof(method));
}

// ReSharper disable once InconsistentNaming
public IEnumerable<Instruction> GetILInstructions()
{
return _method.GetInstructions().ToList();
Expand Down
169 changes: 23 additions & 146 deletions src/Pose/IL/Stubs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,157 +5,26 @@
using System.Reflection.Emit;
#if NETSTANDARD2_1_OR_GREATER
using System.Runtime.CompilerServices;
#endif
#else
using System.Runtime.Serialization;
#endif
using Pose.Extensions;
using Pose.Helpers;

// ReSharper disable RedundantExplicitArrayCreation

namespace Pose.IL
{
internal static class Stubs
{
private static MethodInfo s_devirtualizeMethodMethod;

static Stubs()
{
s_devirtualizeMethodMethod = typeof(StubHelper).GetMethod(nameof(StubHelper.DevirtualizeMethod), new Type[] { typeof(object), typeof(MethodInfo) });
typeof(Type).GetMethod(nameof(Type.GetTypeFromHandle));
}

public static DynamicMethod GenerateStubForConstructor(ConstructorInfo constructorInfo, OpCode opCode, bool forValueType)
{
var parameters = constructorInfo.GetParameters();

var signatureParamTypes = new List<Type>();
var parameterTypes = new List<Type>();

if (forValueType)
signatureParamTypes.Add(constructorInfo.DeclaringType.MakeByRefType());
else
signatureParamTypes.Add(constructorInfo.DeclaringType);

signatureParamTypes.AddRange(parameters.Select(p => p.ParameterType));

if (opCode == OpCodes.Newobj)
parameterTypes.AddRange(parameters.Select(p => p.ParameterType));
else
parameterTypes.AddRange(signatureParamTypes);
parameterTypes.Add(typeof(RuntimeMethodHandle));
parameterTypes.Add(typeof(RuntimeTypeHandle));

var stub = new DynamicMethod(
string.Format("stub_ctor_{0}_{1}", constructorInfo.DeclaringType, constructorInfo.Name),
opCode == OpCodes.Newobj ? constructorInfo.DeclaringType : typeof(void),
parameterTypes.ToArray(),
StubHelper.GetOwningModule(),
true);

var ilGenerator = stub.GetILGenerator();

ilGenerator.DeclareLocal(constructorInfo.DeclaringType);
ilGenerator.DeclareLocal(typeof(ConstructorInfo));
ilGenerator.DeclareLocal(typeof(MethodInfo));
ilGenerator.DeclareLocal(typeof(int));
ilGenerator.DeclareLocal(typeof(IntPtr));

var rewriteLabel = ilGenerator.DefineLabel();
var returnLabel = ilGenerator.DefineLabel();

ilGenerator.Emit(OpCodes.Ldarg, parameterTypes.Count - 2);
ilGenerator.Emit(OpCodes.Ldarg, parameterTypes.Count - 1);
ilGenerator.Emit(OpCodes.Call, typeof(MethodBase).GetMethod(nameof(MethodBase.GetMethodFromHandle), new Type[] { typeof(RuntimeMethodHandle), typeof(RuntimeTypeHandle) }));
ilGenerator.Emit(OpCodes.Castclass, typeof(ConstructorInfo));
ilGenerator.Emit(OpCodes.Stloc_1);

ilGenerator.Emit(OpCodes.Ldloc_1);
ilGenerator.Emit(OpCodes.Ldnull);
ilGenerator.Emit(OpCodes.Call, typeof(StubHelper).GetMethod(nameof(StubHelper.GetIndexOfMatchingShim), new []{typeof(MethodBase), typeof(object)}));
ilGenerator.Emit(OpCodes.Stloc_3);
ilGenerator.Emit(OpCodes.Ldloc_3);
ilGenerator.Emit(OpCodes.Ldc_I4_M1);
ilGenerator.Emit(OpCodes.Ceq);
ilGenerator.Emit(OpCodes.Brtrue_S, rewriteLabel);
ilGenerator.Emit(OpCodes.Ldloc_3);
ilGenerator.Emit(OpCodes.Call, typeof(StubHelper).GetMethod(nameof(StubHelper.GetShimReplacementMethod)));
ilGenerator.Emit(OpCodes.Stloc_2);
ilGenerator.Emit(OpCodes.Ldloc_2);
ilGenerator.Emit(OpCodes.Call, typeof(StubHelper).GetMethod(nameof(StubHelper.GetMethodPointer)));
ilGenerator.Emit(OpCodes.Stloc, 4);
ilGenerator.Emit(OpCodes.Ldloc_3);
ilGenerator.Emit(OpCodes.Call, typeof(StubHelper).GetMethod(nameof(StubHelper.GetShimDelegateTarget)));
for (var i = 0; i < signatureParamTypes.Count - 1; i++)
ilGenerator.Emit(OpCodes.Ldarg, i);
ilGenerator.Emit(OpCodes.Ldloc, 4);
ilGenerator.EmitCalli(OpCodes.Calli, CallingConventions.HasThis, constructorInfo.DeclaringType, signatureParamTypes.Skip(1).ToArray(), null);
ilGenerator.Emit(OpCodes.Stloc_0);
if (opCode == OpCodes.Call)
{
if (forValueType)
{
ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.Emit(OpCodes.Ldloc_0);
ilGenerator.Emit(OpCodes.Stobj, constructorInfo.DeclaringType);
}
else
{
ilGenerator.Emit(OpCodes.Ldloc_0);
ilGenerator.Emit(OpCodes.Starg, 0);
}
}
ilGenerator.Emit(OpCodes.Br_S, returnLabel);

ilGenerator.MarkLabel(rewriteLabel);
if (opCode == OpCodes.Newobj)
{
if (forValueType)
{
ilGenerator.Emit(OpCodes.Ldloca, 0);
ilGenerator.Emit(OpCodes.Initobj, constructorInfo.DeclaringType);
}
else
{
ilGenerator.Emit(OpCodes.Ldarg, parameterTypes.Count - 1);
ilGenerator.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle"));
ilGenerator.Emit(OpCodes.Call, typeof(FormatterServices).GetMethod("GetUninitializedObject"));
ilGenerator.Emit(OpCodes.Stloc_0);
}
}

ilGenerator.Emit(OpCodes.Ldloc_1);
ilGenerator.Emit(OpCodes.Call, typeof(MethodRewriter).GetMethod(nameof(MethodRewriter.CreateRewriter), new Type[] { typeof(MethodBase), typeof(bool) }));
ilGenerator.Emit(OpCodes.Call, typeof(MethodRewriter).GetMethod(nameof(MethodRewriter.Rewrite)));
ilGenerator.Emit(OpCodes.Castclass, typeof(MethodInfo));
ilGenerator.Emit(OpCodes.Stloc_2);

var count = signatureParamTypes.Count;
if (opCode == OpCodes.Newobj)
{
if (forValueType)
ilGenerator.Emit(OpCodes.Ldloca, 0);
else
ilGenerator.Emit(OpCodes.Ldloc_0);
count = count - 1;
}
for (var i = 0; i < count; i++)
ilGenerator.Emit(OpCodes.Ldarg, i);

ilGenerator.Emit(OpCodes.Ldloc_2);
ilGenerator.Emit(OpCodes.Call, typeof(StubHelper).GetMethod(nameof(StubHelper.GetMethodPointer)));
ilGenerator.EmitCalli(OpCodes.Calli, CallingConventions.Standard, typeof(void), signatureParamTypes.ToArray(), null);
ilGenerator.MarkLabel(returnLabel);
if (opCode == OpCodes.Newobj)
ilGenerator.Emit(OpCodes.Ldloc_0);
ilGenerator.Emit(OpCodes.Ret);
return stub;
}

public static DynamicMethod GenerateStubForDirectCall(MethodBase method)
{
var returnType = method.IsConstructor ? typeof(void) : (method as MethodInfo).ReturnType;
var signatureParamTypes = new List<Type>();

if (!method.IsStatic)
{
var thisType = method.DeclaringType;
var thisType = method.DeclaringType ?? throw new Exception($"Method {method.Name} does not have a {nameof(MethodBase.DeclaringType)}");
if (thisType.IsValueType)
{
thisType = thisType.MakeByRefType();
Expand Down Expand Up @@ -354,7 +223,10 @@ public static DynamicMethod GenerateStubForVirtualCall(MethodInfo method, TypeIn

public static DynamicMethod GenerateStubForVirtualCall(MethodInfo method)
{
var thisType = method.DeclaringType.IsInterface ? typeof(object) : method.DeclaringType;
if (method == null) throw new ArgumentNullException(nameof(method));

var declaringType = method.DeclaringType ?? throw new Exception($"Method {method.Name} does not have a {nameof(MethodBase.DeclaringType)}");
var thisType = declaringType.IsInterface ? typeof(object) : declaringType;

var signatureParamTypes = new List<Type>();
signatureParamTypes.Add(thisType);
Expand Down Expand Up @@ -394,7 +266,7 @@ public static DynamicMethod GenerateStubForVirtualCall(MethodInfo method)

// Inject method info into instruction stream
ilGenerator.Emit(OpCodes.Ldtoken, method);
ilGenerator.Emit(OpCodes.Ldtoken, method.DeclaringType);
ilGenerator.Emit(OpCodes.Ldtoken, declaringType);
ilGenerator.Emit(OpCodes.Call, typeof(MethodBase).GetMethod(nameof(MethodBase.GetMethodFromHandle), new Type[] { typeof(RuntimeMethodHandle), typeof(RuntimeTypeHandle) }));
ilGenerator.Emit(OpCodes.Castclass, typeof(MethodInfo));
ilGenerator.Emit(OpCodes.Stloc_0);
Expand Down Expand Up @@ -430,7 +302,7 @@ public static DynamicMethod GenerateStubForVirtualCall(MethodInfo method)
// Rewrite resolved method
ilGenerator.MarkLabel(rewriteLabel);
ilGenerator.Emit(OpCodes.Ldloc_0);
ilGenerator.Emit(method.DeclaringType.IsInterface ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0);
ilGenerator.Emit(declaringType.IsInterface ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0);
ilGenerator.Emit(OpCodes.Call, typeof(MethodRewriter).GetMethod(nameof(MethodRewriter.CreateRewriter), new Type[] { typeof(MethodBase), typeof(bool) }));
ilGenerator.Emit(OpCodes.Call, typeof(MethodRewriter).GetMethod(nameof(MethodRewriter.Rewrite)));
ilGenerator.Emit(OpCodes.Castclass, typeof(MethodInfo));
Expand Down Expand Up @@ -459,7 +331,8 @@ public static DynamicMethod GenerateStubForVirtualCall(MethodInfo method)

public static DynamicMethod GenerateStubForObjectInitialization(ConstructorInfo constructor)
{
var thisType = constructor.DeclaringType;
var thisType = constructor.DeclaringType ?? throw new Exception($"Method {constructor.Name} does not have a {nameof(MethodBase.DeclaringType)}");

if (thisType.IsValueType)
{
thisType = thisType.MakeByRefType();
Expand Down Expand Up @@ -537,7 +410,7 @@ public static DynamicMethod GenerateStubForObjectInitialization(ConstructorInfo
ilGenerator.MarkLabel(rewriteLabel);

// ++
if (constructor.DeclaringType.IsValueType)
if (thisType.IsValueType)
{
ilGenerator.Emit(OpCodes.Ldloca_S, (byte)1);
// ilGenerator.Emit(OpCodes.Dup);
Expand Down Expand Up @@ -755,10 +628,14 @@ public static DynamicMethod GenerateStubForDirectLoad(MethodBase method)

public static DynamicMethod GenerateStubForVirtualLoad(MethodInfo method)
{
if (method == null) throw new ArgumentNullException(nameof(method));

var declaringType = method.DeclaringType ?? throw new Exception($"Method {method.Name} does not have a {nameof(MethodBase.DeclaringType)}");

var stub = new DynamicMethod(
StubHelper.CreateStubNameFromMethod("stub_ldvirtftn", method),
typeof(IntPtr),
new Type[] { method.DeclaringType.IsInterface ? typeof(object) : method.DeclaringType },
new Type[] { declaringType.IsInterface ? typeof(object) : declaringType },
StubHelper.GetOwningModule(),
true);

Expand All @@ -781,19 +658,19 @@ public static DynamicMethod GenerateStubForVirtualLoad(MethodInfo method)

// Inject method info into instruction stream
ilGenerator.Emit(OpCodes.Ldtoken, method);
ilGenerator.Emit(OpCodes.Ldtoken, method.DeclaringType);
ilGenerator.Emit(OpCodes.Ldtoken, declaringType);
ilGenerator.Emit(OpCodes.Call, typeof(MethodBase).GetMethod(nameof(MethodBase.GetMethodFromHandle), new Type[] { typeof(RuntimeMethodHandle), typeof(RuntimeTypeHandle) }));
ilGenerator.Emit(OpCodes.Castclass, typeof(MethodInfo));
ilGenerator.Emit(OpCodes.Stloc_0);

// Resolve virtual method to object type
ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.Emit(OpCodes.Ldloc_0);
ilGenerator.Emit(OpCodes.Call, s_devirtualizeMethodMethod);
ilGenerator.Emit(OpCodes.Call, typeof(StubHelper).GetMethod(nameof(StubHelper.DevirtualizeMethod), new Type[] { typeof(object), typeof(MethodInfo) }));

// Rewrite resolved method
ilGenerator.MarkLabel(rewriteLabel);
ilGenerator.Emit(method.DeclaringType.IsInterface ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0);
ilGenerator.Emit(declaringType.IsInterface ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0);
ilGenerator.Emit(OpCodes.Call, typeof(MethodRewriter).GetMethod(nameof(MethodRewriter.CreateRewriter), new Type[] { typeof(MethodBase), typeof(bool) }));
ilGenerator.Emit(OpCodes.Call, typeof(MethodRewriter).GetMethod(nameof(MethodRewriter.Rewrite)));

Expand Down

0 comments on commit e614fd9

Please sign in to comment.