diff --git a/AsmResolver.sln b/AsmResolver.sln
index 1fac52b35..0cf5601e0 100644
--- a/AsmResolver.sln
+++ b/AsmResolver.sln
@@ -90,6 +90,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AsmResolver.Symbols.Pdb", "
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AsmResolver.Symbols.Pdb.Tests", "test\AsmResolver.Symbols.Pdb.Tests\AsmResolver.Symbols.Pdb.Tests.csproj", "{AAD604B6-ABE5-4DBC-A2D9-4EF8E815B2EE}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AsmResolver.DotNet.Dynamic.Tests", "test\AsmResolver.DotNet.Dynamic.Tests\AsmResolver.DotNet.Dynamic.Tests.csproj", "{C089D0AB-B428-4136-89CC-7974CB590513}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AsmResolver.DotNet.Dynamic", "src\AsmResolver.DotNet.Dynamic\AsmResolver.DotNet.Dynamic.csproj", "{62420213-67AD-40FC-B451-BD05C2437CE3}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -452,6 +456,30 @@ Global
{AAD604B6-ABE5-4DBC-A2D9-4EF8E815B2EE}.Release|x64.Build.0 = Release|Any CPU
{AAD604B6-ABE5-4DBC-A2D9-4EF8E815B2EE}.Release|x86.ActiveCfg = Release|Any CPU
{AAD604B6-ABE5-4DBC-A2D9-4EF8E815B2EE}.Release|x86.Build.0 = Release|Any CPU
+ {C089D0AB-B428-4136-89CC-7974CB590513}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C089D0AB-B428-4136-89CC-7974CB590513}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C089D0AB-B428-4136-89CC-7974CB590513}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {C089D0AB-B428-4136-89CC-7974CB590513}.Debug|x64.Build.0 = Debug|Any CPU
+ {C089D0AB-B428-4136-89CC-7974CB590513}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {C089D0AB-B428-4136-89CC-7974CB590513}.Debug|x86.Build.0 = Debug|Any CPU
+ {C089D0AB-B428-4136-89CC-7974CB590513}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C089D0AB-B428-4136-89CC-7974CB590513}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C089D0AB-B428-4136-89CC-7974CB590513}.Release|x64.ActiveCfg = Release|Any CPU
+ {C089D0AB-B428-4136-89CC-7974CB590513}.Release|x64.Build.0 = Release|Any CPU
+ {C089D0AB-B428-4136-89CC-7974CB590513}.Release|x86.ActiveCfg = Release|Any CPU
+ {C089D0AB-B428-4136-89CC-7974CB590513}.Release|x86.Build.0 = Release|Any CPU
+ {62420213-67AD-40FC-B451-BD05C2437CE3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {62420213-67AD-40FC-B451-BD05C2437CE3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {62420213-67AD-40FC-B451-BD05C2437CE3}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {62420213-67AD-40FC-B451-BD05C2437CE3}.Debug|x64.Build.0 = Debug|Any CPU
+ {62420213-67AD-40FC-B451-BD05C2437CE3}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {62420213-67AD-40FC-B451-BD05C2437CE3}.Debug|x86.Build.0 = Debug|Any CPU
+ {62420213-67AD-40FC-B451-BD05C2437CE3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {62420213-67AD-40FC-B451-BD05C2437CE3}.Release|Any CPU.Build.0 = Release|Any CPU
+ {62420213-67AD-40FC-B451-BD05C2437CE3}.Release|x64.ActiveCfg = Release|Any CPU
+ {62420213-67AD-40FC-B451-BD05C2437CE3}.Release|x64.Build.0 = Release|Any CPU
+ {62420213-67AD-40FC-B451-BD05C2437CE3}.Release|x86.ActiveCfg = Release|Any CPU
+ {62420213-67AD-40FC-B451-BD05C2437CE3}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -491,6 +519,8 @@ Global
{2D1DF5DA-7367-4490-B3F0-B996348E150B} = {B3AF102B-ABE1-41B2-AE48-C40702F45AB0}
{9E311832-D0F2-42CA-84DD-9A91B88F0287} = {34A95168-A162-4F6A-803B-B6F221FE9EA6}
{AAD604B6-ABE5-4DBC-A2D9-4EF8E815B2EE} = {786C1732-8C96-45DD-97BB-639C9AA7F45B}
+ {C089D0AB-B428-4136-89CC-7974CB590513} = {786C1732-8C96-45DD-97BB-639C9AA7F45B}
+ {62420213-67AD-40FC-B451-BD05C2437CE3} = {34A95168-A162-4F6A-803B-B6F221FE9EA6}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {3302AC79-6D23-4E7D-8C5F-C0C7261044D0}
diff --git a/src/AsmResolver.DotNet.Dynamic/AsmResolver.DotNet.Dynamic.csproj b/src/AsmResolver.DotNet.Dynamic/AsmResolver.DotNet.Dynamic.csproj
new file mode 100644
index 000000000..1f4ff4172
--- /dev/null
+++ b/src/AsmResolver.DotNet.Dynamic/AsmResolver.DotNet.Dynamic.csproj
@@ -0,0 +1,32 @@
+
+
+
+ AsmResolver.DotNet.Dynamic
+ Dynamic method support for the AsmResolver executable file inspection toolsuite.
+ exe pe directories imports exports resources dotnet cil inspection manipulation assembly disassembly dynamic
+ true
+ 1701;1702;NU5105
+ net6.0;netcoreapp3.1;netstandard2.0
+ enable
+
+
+
+ bin\Debug\AsmResolver.DotNet.xml
+
+
+
+ bin\Release\AsmResolver.DotNet.xml
+
+
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
diff --git a/src/AsmResolver.DotNet/Code/Cil/DynamicCilOperandResolver.cs b/src/AsmResolver.DotNet.Dynamic/DynamicCilOperandResolver.cs
similarity index 92%
rename from src/AsmResolver.DotNet/Code/Cil/DynamicCilOperandResolver.cs
rename to src/AsmResolver.DotNet.Dynamic/DynamicCilOperandResolver.cs
index d3244f8e2..6cfa15b76 100644
--- a/src/AsmResolver.DotNet/Code/Cil/DynamicCilOperandResolver.cs
+++ b/src/AsmResolver.DotNet.Dynamic/DynamicCilOperandResolver.cs
@@ -1,13 +1,14 @@
using System;
using System.Collections.Generic;
using System.Reflection;
+using AsmResolver.DotNet.Code.Cil;
using AsmResolver.DotNet.Serialized;
using AsmResolver.DotNet.Signatures;
using AsmResolver.IO;
using AsmResolver.PE.DotNet.Cil;
using AsmResolver.PE.DotNet.Metadata.Tables;
-namespace AsmResolver.DotNet.Code.Cil
+namespace AsmResolver.DotNet.Dynamic
{
///
/// Provides an implementation of that resolves operands based on
@@ -34,13 +35,13 @@ public DynamicCilOperandResolver(SerializedModuleDefinition contextModule, CilMe
switch (token.Table)
{
case TableIndex.TypeDef:
- object? type = _tokens[(int) token.Rid];
+ object? type = _tokens[(int)token.Rid];
if (type is RuntimeTypeHandle runtimeTypeHandle)
return _importer.ImportType(Type.GetTypeFromHandle(runtimeTypeHandle));
break;
case TableIndex.Field:
- object? field = _tokens[(int) token.Rid];
+ object? field = _tokens[(int)token.Rid];
if (field is null)
return null;
@@ -61,7 +62,7 @@ public DynamicCilOperandResolver(SerializedModuleDefinition contextModule, CilMe
case TableIndex.Method:
case TableIndex.MemberRef:
- object? obj = _tokens[(int) token.Rid];
+ object? obj = _tokens[(int)token.Rid];
if (obj is null)
return null;
@@ -94,7 +95,7 @@ public DynamicCilOperandResolver(SerializedModuleDefinition contextModule, CilMe
break;
case TableIndex.StandAloneSig:
- var reader = ByteArrayDataSource.CreateReader((byte[]) _tokens[(int) token.Rid]!);
+ var reader = ByteArrayDataSource.CreateReader((byte[])_tokens[(int)token.Rid]!);
return CallingConventionSignature.FromReader(new BlobReadContext(_readerContext), ref reader);
}
@@ -104,7 +105,7 @@ public DynamicCilOperandResolver(SerializedModuleDefinition contextModule, CilMe
///
public override object? ResolveString(MetadataToken token)
{
- return _tokens[(int) token.Rid] as string;
+ return _tokens[(int)token.Rid] as string;
}
}
}
diff --git a/src/AsmResolver.DotNet.Dynamic/DynamicMethodDefinition.cs b/src/AsmResolver.DotNet.Dynamic/DynamicMethodDefinition.cs
new file mode 100644
index 000000000..4349d9006
--- /dev/null
+++ b/src/AsmResolver.DotNet.Dynamic/DynamicMethodDefinition.cs
@@ -0,0 +1,100 @@
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using AsmResolver.DotNet.Code.Cil;
+using AsmResolver.DotNet.Serialized;
+using AsmResolver.DotNet.Signatures;
+using AsmResolver.DotNet.Signatures.Types;
+using AsmResolver.IO;
+using AsmResolver.PE.DotNet.Cil;
+using AsmResolver.PE.DotNet.Metadata.Tables;
+using MethodAttributes = AsmResolver.PE.DotNet.Metadata.Tables.Rows.MethodAttributes;
+
+namespace AsmResolver.DotNet.Dynamic
+{
+ ///
+ /// Represents a single method in a type definition of a .NET module.
+ ///
+ public class DynamicMethodDefinition : MethodDefinition
+ {
+ ///
+ /// Create a Dynamic Method Definition
+ ///
+ /// Target Module
+ /// Dynamic Method / Delegate / DynamicResolver
+ public DynamicMethodDefinition(ModuleDefinition module, object dynamicMethodObj) :
+ base(new MetadataToken(TableIndex.Method, 0))
+ {
+ dynamicMethodObj = DynamicMethodHelper.ResolveDynamicResolver(dynamicMethodObj);
+ var methodBase = FieldReader.ReadField(dynamicMethodObj, "m_method");
+ if (methodBase is null)
+ {
+ throw new ArgumentException(
+ "Could not get the underlying method base in the provided dynamic method object.");
+ }
+
+ Module = module;
+ Name = methodBase.Name;
+ Attributes = (MethodAttributes)methodBase.Attributes;
+ Signature = new ReferenceImporter(module).ImportMethodSignature(ResolveSig(methodBase, module));
+ CilMethodBody = CreateDynamicMethodBody(this, dynamicMethodObj);
+ }
+
+ private MethodSignature ResolveSig(MethodBase methodBase, ModuleDefinition module)
+ {
+ var imp = new ReferenceImporter(module);
+ var returnType = methodBase is MethodInfo info
+ ? imp.ImportTypeSignature(info.ReturnType)
+ : module.CorLibTypeFactory.Void;
+
+ var parameters = methodBase.GetParameters();
+
+ var parameterTypes = new TypeSignature[parameters.Length];
+ for (int i = 0; i < parameterTypes.Length; i++)
+ parameterTypes[i] = imp.ImportTypeSignature(parameters[i].ParameterType);
+
+ return new MethodSignature(
+ methodBase.IsStatic ? 0 : CallingConventionAttributes.HasThis,
+ returnType, parameterTypes);
+ }
+
+ ///
+ public override ModuleDefinition Module { get; }
+
+ ///
+ /// Creates a CIL method body from a dynamic method.
+ ///
+ /// The method that owns the method body.
+ /// The Dynamic Method/Delegate/DynamicResolver.
+ /// The method body.
+ private static CilMethodBody CreateDynamicMethodBody(MethodDefinition method, object dynamicMethodObj)
+ {
+ if (!(method.Module is SerializedModuleDefinition module))
+ throw new ArgumentException("Method body should reference a serialized module.");
+
+ var result = new CilMethodBody(method);
+ dynamicMethodObj = DynamicMethodHelper.ResolveDynamicResolver(dynamicMethodObj);
+
+ //Get Runtime Fields
+ byte[] code = FieldReader.ReadField(dynamicMethodObj, "m_code")!;
+ object scope = FieldReader.ReadField
/// The method to import.
/// The imported method.
+ [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Calls System.Reflection.Module.ResolveMethod(int)")]
public virtual IMethodDescriptor ImportMethod(MethodBase method)
{
if (method is null)
@@ -522,6 +523,7 @@ public virtual IMethodDescriptor ImportMethod(MethodBase method)
return new MemberReference(ImportType(method.DeclaringType), method.Name, result);
}
+ [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Calls AsmResolver.DotNet.ReferenceImporter.ImportMethod(System.Reflection.MethodBase)")]
private IMethodDescriptor ImportGenericMethod(MethodInfo method)
{
var memberRef = (IMethodDefOrRef) ImportMethod(method.GetGenericMethodDefinition());
@@ -576,6 +578,7 @@ public FieldSignature ImportFieldSignature(FieldSignature signature)
/// The field to import.
/// The imported field.
/// Occurs when a field is not added to a type.
+ [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Calls System.Reflection.Module.ResolveField(int)")]
public MemberReference ImportField(FieldInfo field)
{
if (field is null)
diff --git a/src/AsmResolver.DotNet/Signatures/Types/TypeSignature.cs b/src/AsmResolver.DotNet/Signatures/Types/TypeSignature.cs
index 389411e30..7eb81bfbd 100644
--- a/src/AsmResolver.DotNet/Signatures/Types/TypeSignature.cs
+++ b/src/AsmResolver.DotNet/Signatures/Types/TypeSignature.cs
@@ -14,18 +14,6 @@ public abstract class TypeSignature : ExtendableBlobSignature, ITypeDescriptor
{
internal const string NullTypeToString = "<??>>";
- private static readonly MethodInfo GetTypeFromHandleUnsafeMethod;
-
- static TypeSignature()
- {
- GetTypeFromHandleUnsafeMethod = typeof(Type)
- .GetMethod("GetTypeFromHandleUnsafe",
- (BindingFlags) (-1),
- null,
- new[] {typeof(IntPtr)},
- null)!;
- }
-
///
public abstract string? Name
{
@@ -156,19 +144,9 @@ public static TypeSignature FromReader(in BlobReadContext context, ref BinaryStr
return new BoxedTypeSignature(FromReader(context, ref reader));
case ElementType.Internal:
- var address = IntPtr.Size switch
- {
- 4 => new IntPtr(reader.ReadInt32()),
- _ => new IntPtr(reader.ReadInt64())
- };
-
- // Let the runtime translate the address to a type and import it.
- var clrType = (Type?) GetTypeFromHandleUnsafeMethod.Invoke(null, new object[] { address });
- var asmResType = clrType is not null
- ? new ReferenceImporter(context.ReaderContext.ParentModule).ImportType(clrType)
- : InvalidTypeDefOrRef.Get(InvalidTypeSignatureError.IllegalTypeSpec);
-
- return new TypeDefOrRefSignature(asmResType);
+ throw new NotSupportedException(
+ "Encountered an COR_ELEMENT_TYPE_INTERNAL type signature which is not supported by this "
+ + " type signature reader. Use the AsmResolver.DotNet.Dynamic extension package instead.");
default:
throw new ArgumentOutOfRangeException($"Invalid or unsupported element type {elementType}.");
diff --git a/src/AsmResolver/IO/BinaryStreamReader.cs b/src/AsmResolver/IO/BinaryStreamReader.cs
index 9de2fd993..d0a101c3d 100644
--- a/src/AsmResolver/IO/BinaryStreamReader.cs
+++ b/src/AsmResolver/IO/BinaryStreamReader.cs
@@ -134,6 +134,10 @@ private void AssertCanRead(uint count)
throw new EndOfStreamException();
}
+ public int PeekByte() => CanRead(1)
+ ? DataSource[Offset]
+ : -1;
+
///
/// Reads a single byte from the input stream, and advances the current offset by one.
///
diff --git a/test/AsmResolver.DotNet.Dynamic.Tests/AsmResolver.DotNet.Dynamic.Tests.csproj b/test/AsmResolver.DotNet.Dynamic.Tests/AsmResolver.DotNet.Dynamic.Tests.csproj
new file mode 100644
index 000000000..9a814bd0f
--- /dev/null
+++ b/test/AsmResolver.DotNet.Dynamic.Tests/AsmResolver.DotNet.Dynamic.Tests.csproj
@@ -0,0 +1,26 @@
+
+
+
+ net6.0
+ disable
+
+ false
+
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
+
+
diff --git a/test/AsmResolver.DotNet.Dynamic.Tests/DynamicMethodDefinitionTest.cs b/test/AsmResolver.DotNet.Dynamic.Tests/DynamicMethodDefinitionTest.cs
new file mode 100644
index 000000000..7d3f91e09
--- /dev/null
+++ b/test/AsmResolver.DotNet.Dynamic.Tests/DynamicMethodDefinitionTest.cs
@@ -0,0 +1,76 @@
+using System.Linq;
+using System.Reflection;
+using System.Reflection.Emit;
+using AsmResolver.DotNet.Signatures.Types;
+using AsmResolver.DotNet.TestCases.Methods;
+using AsmResolver.PE.DotNet.Cil;
+using Xunit;
+
+namespace AsmResolver.DotNet.Dynamic.Tests
+{
+ public class DynamicMethodDefinitionTest
+ {
+ [Fact]
+ public void ReadDynamicMethod()
+ {
+ var module = ModuleDefinition.FromFile(typeof(TDynamicMethod).Assembly.Location);
+ var generatedDynamicMethod = TDynamicMethod.GenerateDynamicMethod();
+ var dynamicMethodDef = new DynamicMethodDefinition(module, generatedDynamicMethod);
+
+ Assert.NotNull(dynamicMethodDef);
+ Assert.NotEmpty(dynamicMethodDef.CilMethodBody!.Instructions);
+ Assert.Equal(new[]
+ {
+ CilCode.Ldarg_0,
+ CilCode.Stloc_0,
+ CilCode.Ldloc_0,
+ CilCode.Call,
+ CilCode.Ldarg_1,
+ CilCode.Ret
+ }, dynamicMethodDef.CilMethodBody.Instructions.Select(q => q.OpCode.Code));
+ Assert.Equal(new TypeSignature[]
+ {
+ module.CorLibTypeFactory.String,
+ module.CorLibTypeFactory.Int32
+ }, dynamicMethodDef.Parameters.Select(q => q.ParameterType));
+ Assert.Equal(new TypeSignature[]
+ {
+ module.CorLibTypeFactory.String,
+ }, dynamicMethodDef.CilMethodBody.LocalVariables.Select(v => v.VariableType));
+ }
+
+ [Fact]
+ public void RtDynamicMethod()
+ {
+ var module = ModuleDefinition.FromFile(typeof(TDynamicMethod).Assembly.Location);
+
+ var generatedDynamicMethod = TDynamicMethod.GenerateDynamicMethod();
+ object rtDynamicMethod = generatedDynamicMethod
+ .GetType()
+ .GetField("m_dynMethod", (BindingFlags) (-1))?
+ .GetValue(generatedDynamicMethod);
+ var dynamicMethod = new DynamicMethodDefinition(module, rtDynamicMethod!);
+
+ Assert.NotNull(dynamicMethod);
+ Assert.NotEmpty(dynamicMethod.CilMethodBody!.Instructions);
+ Assert.Equal(new[]
+ {
+ CilCode.Ldarg_0,
+ CilCode.Stloc_0,
+ CilCode.Ldloc_0,
+ CilCode.Call,
+ CilCode.Ldarg_1,
+ CilCode.Ret
+ }, dynamicMethod.CilMethodBody.Instructions.Select(q => q.OpCode.Code));
+ Assert.Equal(new TypeSignature[]
+ {
+ module.CorLibTypeFactory.String,
+ module.CorLibTypeFactory.Int32
+ }, dynamicMethod.Parameters.Select(q => q.ParameterType));
+ Assert.Equal(new TypeSignature[]
+ {
+ module.CorLibTypeFactory.String,
+ }, dynamicMethod.CilMethodBody.LocalVariables.Select(v => v.VariableType));
+ }
+ }
+}
diff --git a/test/AsmResolver.DotNet.Tests/Code/Cil/CilMethodBodyTest.cs b/test/AsmResolver.DotNet.Tests/Code/Cil/CilMethodBodyTest.cs
index 8dda5be9e..f13198d60 100644
--- a/test/AsmResolver.DotNet.Tests/Code/Cil/CilMethodBodyTest.cs
+++ b/test/AsmResolver.DotNet.Tests/Code/Cil/CilMethodBodyTest.cs
@@ -124,33 +124,6 @@ public void ReadFatMethodWithExceptionHandler()
Assert.Single(body.ExceptionHandlers);
}
- [Fact]
- public void ReadDynamicMethod()
- {
- var module = ModuleDefinition.FromFile(typeof(TDynamicMethod).Assembly.Location);
-
- var type = module.TopLevelTypes.First(t => t.Name == nameof(TDynamicMethod));
-
- var method = type.Methods.FirstOrDefault(m => m.Name == nameof(TDynamicMethod.GenerateDynamicMethod));
-
- DynamicMethod generateDynamicMethod = TDynamicMethod.GenerateDynamicMethod();
-
- //Dynamic method => CilMethodBody
- var body = CilMethodBody.FromDynamicMethod(method, generateDynamicMethod);
-
- Assert.NotNull(body);
-
- Assert.NotEmpty(body.Instructions);
-
- Assert.Equal(body.Instructions.Select(q=>q.OpCode),new CilOpCode[]
- {
- CilOpCodes.Ldarg_0,
- CilOpCodes.Call,
- CilOpCodes.Ldarg_1,
- CilOpCodes.Ret
- });
- }
-
private static CilMethodBody CreateDummyBody(bool isVoid)
{
var module = new ModuleDefinition("DummyModule");
diff --git a/test/AsmResolver.DotNet.Tests/DynamicMethodDefinitionTest.cs b/test/AsmResolver.DotNet.Tests/DynamicMethodDefinitionTest.cs
deleted file mode 100644
index f8f203513..000000000
--- a/test/AsmResolver.DotNet.Tests/DynamicMethodDefinitionTest.cs
+++ /dev/null
@@ -1,69 +0,0 @@
-using System.Linq;
-using System.Reflection;
-using System.Reflection.Emit;
-using AsmResolver.DotNet.Signatures.Types;
-using AsmResolver.DotNet.TestCases.Methods;
-using AsmResolver.PE.DotNet.Cil;
-using Xunit;
-
-namespace AsmResolver.DotNet.Tests
-{
- public class DynamicMethodDefinitionTest
- {
- [Fact]
- public void ReadDynamicMethod()
- {
- var module = ModuleDefinition.FromFile(typeof(TDynamicMethod).Assembly.Location);
-
- DynamicMethod generateDynamicMethod = TDynamicMethod.GenerateDynamicMethod();
-
- var dynamicMethodDefinition = new DynamicMethodDefinition(module, generateDynamicMethod);
-
- Assert.NotNull(dynamicMethodDefinition);
-
- Assert.NotEmpty(dynamicMethodDefinition.CilMethodBody.Instructions);
-
- Assert.Equal(dynamicMethodDefinition.CilMethodBody.Instructions.Select(q=>q.OpCode),new []
- {
- CilOpCodes.Ldarg_0,
- CilOpCodes.Call,
- CilOpCodes.Ldarg_1,
- CilOpCodes.Ret
- });
- Assert.Equal(dynamicMethodDefinition.Parameters.Select(q=>q.ParameterType),new TypeSignature[]
- {
- module.CorLibTypeFactory.String,
- module.CorLibTypeFactory.Int32
- });
- }
-
- [Fact]
- public void RtDynamicMethod()
- {
- var module = ModuleDefinition.FromFile(typeof(TDynamicMethod).Assembly.Location);
-
- DynamicMethod generateDynamicMethod = TDynamicMethod.GenerateDynamicMethod();
-
- var rtDynamicMethod = generateDynamicMethod.GetType().GetField("m_dynMethod", (BindingFlags) (-1))?.GetValue(generateDynamicMethod);
-
- var dynamicMethodDefinition = new DynamicMethodDefinition(module, rtDynamicMethod);
-
- Assert.NotNull(dynamicMethodDefinition);
-
- Assert.NotEmpty(dynamicMethodDefinition.CilMethodBody.Instructions);
-
- Assert.Equal(dynamicMethodDefinition.CilMethodBody.Instructions.Select(q=>q.OpCode),new []
- {
- CilOpCodes.Ldarg_0,
- CilOpCodes.Call,
- CilOpCodes.Ldarg_1,
- CilOpCodes.Ret
- });
- Assert.Equal(dynamicMethodDefinition.Parameters.Select(q=>q.ParameterType),new TypeSignature[]
- {
- module.CorLibTypeFactory.String,
- module.CorLibTypeFactory.Int32
- });
- }
- }
-}
\ No newline at end of file
diff --git a/test/TestBinaries/DotNet/AsmResolver.DotNet.TestCases.Methods/TDynamicMethod.cs b/test/TestBinaries/DotNet/AsmResolver.DotNet.TestCases.Methods/TDynamicMethod.cs
index 3cd849478..9890d227b 100644
--- a/test/TestBinaries/DotNet/AsmResolver.DotNet.TestCases.Methods/TDynamicMethod.cs
+++ b/test/TestBinaries/DotNet/AsmResolver.DotNet.TestCases.Methods/TDynamicMethod.cs
@@ -14,7 +14,7 @@ public static DynamicMethod GenerateDynamicMethod()
// of Integer, and two parameters whose types are specified by
// the array helloArgs. Create the method in the module that
// defines the String class.
- DynamicMethod hello = new DynamicMethod("Hello",
+ var hello = new DynamicMethod("Hello",
typeof(int),
helloArgs,
typeof(string).Module);
@@ -24,15 +24,18 @@ public static DynamicMethod GenerateDynamicMethod()
Type[] writeStringArgs = {typeof(string)};
// Get the overload of Console.WriteLine that has one
// String parameter.
- MethodInfo writeString = typeof(Console).GetMethod("WriteLine",
+ var writeString = typeof(Console).GetMethod("WriteLine",
writeStringArgs);
// Get an ILGenerator and emit a body for the dynamic method,
// using a stream size larger than the IL that will be
// emitted.
- ILGenerator il = hello.GetILGenerator(256);
+ var il = hello.GetILGenerator(256);
+ il.DeclareLocal(typeof(string));
// Load the first argument, which is a string, onto the stack.
il.Emit(OpCodes.Ldarg_0);
+ il.Emit(OpCodes.Stloc_0);
+ il.Emit(OpCodes.Ldloc_0);
// Call the overload of Console.WriteLine that prints a string.
il.EmitCall(OpCodes.Call, writeString, null);
// The Hello method returns the value of the second argument;
@@ -50,4 +53,4 @@ public static DynamicMethod GenerateDynamicMethod()
}
}
-}
\ No newline at end of file
+}