diff --git a/src/DotNet/Emit/DynamicMethodBodyReader.cs b/src/DotNet/Emit/DynamicMethodBodyReader.cs
index a90ff326c..ae70f102c 100644
--- a/src/DotNet/Emit/DynamicMethodBodyReader.cs
+++ b/src/DotNet/Emit/DynamicMethodBodyReader.cs
@@ -20,9 +20,9 @@ public enum DynamicMethodBodyReaderOptions {
None = 0,
///
- /// Some fields/methods have an unknown declaring type and don't have a context with
- /// that information. If this is enabled, the reader will try to guess it but it doesn't
- /// always work. If you get an , try enabling this option.
+ /// Fields in generic type have an unknown declaring type when built by DynamicILInfo.GetTokenFor(RuntimeFieldHandle field)
+ /// rather than DynamicILInfo.GetTokenFor(RuntimeFieldHandle field, RuntimeTypeHandle contextType).
+ /// If you get an , try enabling this option.
///
UnknownDeclaringType = 0x00000001,
}
@@ -454,26 +454,19 @@ IMethod ImportMethod(uint rid) {
if (obj is null)
return null;
- if (obj is RuntimeMethodHandle) {
- if ((options & DynamicMethodBodyReaderOptions.UnknownDeclaringType) != 0) {
- // Sometimes it's a generic type but obj != `GenericMethodInfo`, so pass in 'default' and the
- // runtime will try to figure out the declaring type. https://github.com/0xd4d/dnlib/issues/298
- return importer.Import(SR.MethodBase.GetMethodFromHandle((RuntimeMethodHandle)obj, default));
- }
- else
- return importer.Import(SR.MethodBase.GetMethodFromHandle((RuntimeMethodHandle)obj));
- }
+ if (obj is RuntimeMethodHandle)
+ return importer.ImportAsOperand(SR.MethodBase.GetMethodFromHandle((RuntimeMethodHandle)obj));
if (obj.GetType().ToString() == "System.Reflection.Emit.GenericMethodInfo") {
var context = (RuntimeTypeHandle)gmiContextFieldInfo.Read(obj);
var method = SR.MethodBase.GetMethodFromHandle((RuntimeMethodHandle)gmiMethodHandleFieldInfo.Read(obj), context);
- return importer.Import(method);
+ return importer.ImportAsOperand(method);
}
if (obj.GetType().ToString() == "System.Reflection.Emit.VarArgMethod") {
var method = GetVarArgMethod(obj);
if (!(method is DynamicMethod))
- return importer.Import(method);
+ return importer.ImportAsOperand(method);
obj = method;
}
@@ -505,17 +498,17 @@ IField ImportField(uint rid) {
if (obj is RuntimeFieldHandle) {
if ((options & DynamicMethodBodyReaderOptions.UnknownDeclaringType) != 0) {
// Sometimes it's a generic type but obj != `GenericFieldInfo`, so pass in 'default' and the
- // runtime will try to figure out the declaring type. https://github.com/0xd4d/dnlib/issues/298
- return importer.Import(SR.FieldInfo.GetFieldFromHandle((RuntimeFieldHandle)obj, default));
+ // runtime will try to figure out the declaring type. https://github.com/0xd4d/dnlib/issues/552
+ return importer.ImportAsOperand(SR.FieldInfo.GetFieldFromHandle((RuntimeFieldHandle)obj, default));
}
else
- return importer.Import(SR.FieldInfo.GetFieldFromHandle((RuntimeFieldHandle)obj));
+ return importer.ImportAsOperand(SR.FieldInfo.GetFieldFromHandle((RuntimeFieldHandle)obj));
}
if (obj.GetType().ToString() == "System.Reflection.Emit.GenericFieldInfo") {
var context = (RuntimeTypeHandle)gfiContextFieldInfo.Read(obj);
var field = SR.FieldInfo.GetFieldFromHandle((RuntimeFieldHandle)gfiFieldHandleFieldInfo.Read(obj), context);
- return importer.Import(field);
+ return importer.ImportAsOperand(field);
}
return null;
@@ -524,7 +517,7 @@ IField ImportField(uint rid) {
ITypeDefOrRef ImportType(uint rid) {
var obj = Resolve(rid);
if (obj is RuntimeTypeHandle)
- return importer.Import(Type.GetTypeFromHandle((RuntimeTypeHandle)obj));
+ return importer.ImportAsOperand(Type.GetTypeFromHandle((RuntimeTypeHandle)obj));
return null;
}
diff --git a/src/DotNet/Importer.cs b/src/DotNet/Importer.cs
index de37e66b6..f4cff7d82 100644
--- a/src/DotNet/Importer.cs
+++ b/src/DotNet/Importer.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using System.Reflection;
+using dnlib.DotNet.Emit;
namespace dnlib.DotNet {
///
@@ -167,14 +168,14 @@ public Importer(ModuleDef module, ImporterOptions options, GenericParamContext g
}
///
- /// Imports a as a .
+ /// Imports a as an .
///
/// The type
/// The imported type or null if is invalid
public ITypeDefOrRef Import(Type type) => module.UpdateRowId(ImportAsTypeSig(type).ToTypeDefOrRef());
///
- /// Imports a as a . See also
+ /// Imports a as an . See also
///
/// The type
///
@@ -182,7 +183,7 @@ public Importer(ModuleDef module, ImporterOptions options, GenericParamContext g
public ITypeDefOrRef ImportDeclaringType(Type type) => Import(type);
///
- /// Imports a as a
+ /// Imports a as an
///
/// The type
/// A list of all required modifiers or null
@@ -399,7 +400,7 @@ IResolutionScope CreateScopeReference(Type type) {
}
///
- /// Imports a as a
+ /// Imports a as an
///
/// The type
/// A list of all required modifiers or null
@@ -437,8 +438,7 @@ TypeSig ImportAsTypeSig(Type type, IList requiredModifiers, IList op
static bool IsEmpty(IList list) => list is null || list.Count == 0;
///
- /// Imports a as a . This will be either
- /// a or a .
+ /// Imports a as an .
///
/// The method
/// The imported method or null if is invalid
@@ -446,8 +446,7 @@ TypeSig ImportAsTypeSig(Type type, IList requiredModifiers, IList op
public IMethod Import(MethodBase methodBase) => Import(methodBase, false);
///
- /// Imports a as a . This will be either
- /// a or a .
+ /// Imports a as an .
///
/// The method
/// Always verify method signature to make sure the
@@ -459,9 +458,7 @@ public IMethod Import(MethodBase methodBase, bool forceFixSignature) {
return ImportInternal(methodBase, forceFixSignature);
}
- IMethod ImportInternal(MethodBase methodBase) => ImportInternal(methodBase, false);
-
- IMethod ImportInternal(MethodBase methodBase, bool forceFixSignature) {
+ IMethod ImportInternal(MethodBase methodBase, bool forceFixSignature, bool asOperand = false) {
if (methodBase is null)
return null;
@@ -484,13 +481,13 @@ IMethod ImportInternal(MethodBase methodBase, bool forceFixSignature) {
if (methodBase.DeclaringType.GetElementType2() == ElementType.GenericInst)
method = module.UpdateRowId(new MemberRefUser(module, methodBase.Name, CreateMethodSig(origMethod), Import(methodBase.DeclaringType)));
else
- method = ImportInternal(origMethod) as IMethodDefOrRef;
+ method = ImportInternal(origMethod, forceFixSignature, asOperand) as IMethodDefOrRef;
method = TryResolveMethod(method);
- if (methodBase.ContainsGenericParameters)
+ if (!asOperand && methodBase.ContainsGenericParameters)
return method; // Declaring type is instantiated but method itself is not
- var gim = CreateGenericInstMethodSig(methodBase);
+ var gim = CreateGenericInstMethodSig(methodBase, asOperand);
var methodSpec = module.UpdateRowId(new MethodSpecUser(method, gim));
if (FixSignature && !forceFixSignature) {
//TODO:
@@ -504,7 +501,7 @@ IMethod ImportInternal(MethodBase methodBase, bool forceFixSignature) {
parent = GetModuleParent(methodBase.Module);
}
else
- parent = Import(methodBase.DeclaringType);
+ parent = asOperand ? ImportAsOperand(methodBase.DeclaringType) : Import(methodBase.DeclaringType);
if (parent is null)
return null;
@@ -583,11 +580,11 @@ CallingConvention GetCallingConvention(MethodBase mb) {
return cc;
}
- GenericInstMethodSig CreateGenericInstMethodSig(MethodBase mb) {
+ GenericInstMethodSig CreateGenericInstMethodSig(MethodBase mb, bool asOperand) {
var genMethodArgs = mb.GetGenericArguments();
var gim = new GenericInstMethodSig(CallingConvention.GenericInst, (uint)genMethodArgs.Length);
foreach (var gma in genMethodArgs)
- gim.GenericArguments.Add(ImportAsTypeSig(gma));
+ gim.GenericArguments.Add(asOperand ? ImportAsTypeSig(gma, null, gma.IsGenericType) : ImportAsTypeSig(gma));
return gim;
}
@@ -604,7 +601,7 @@ bool IsThisAssembly(Module module2) {
}
///
- /// Imports a as a
+ /// Imports a as an
///
/// The field
/// The imported field or null if is invalid
@@ -612,14 +609,16 @@ bool IsThisAssembly(Module module2) {
public IField Import(FieldInfo fieldInfo) => Import(fieldInfo, false);
///
- /// Imports a as a
+ /// Imports a as an
///
/// The field
/// Always verify field signature to make sure the
/// returned reference matches the metadata in the source assembly
/// The imported field or null if is invalid
/// or if we failed to import the field
- public IField Import(FieldInfo fieldInfo, bool forceFixSignature) {
+ public IField Import(FieldInfo fieldInfo, bool forceFixSignature) => ImportInternal(fieldInfo, forceFixSignature, false);
+
+ IField ImportInternal(FieldInfo fieldInfo, bool forceFixSignature, bool asOperand = false) {
FixSignature = false;
if (fieldInfo is null)
return null;
@@ -642,7 +641,7 @@ public IField Import(FieldInfo fieldInfo, bool forceFixSignature) {
parent = GetModuleParent(fieldInfo.Module);
}
else
- parent = Import(fieldInfo.DeclaringType);
+ parent = asOperand ? ImportAsOperand(fieldInfo.DeclaringType) : Import(fieldInfo.DeclaringType);
if (parent is null)
return null;
@@ -1190,5 +1189,28 @@ IMemberRefParent Import(IMemberRefParent parent) {
return null;
}
+
+ ///
+ /// Imports a as an used for .
+ ///
+ /// The type
+ /// The imported type or null if is invalid
+ public ITypeDefOrRef ImportAsOperand(Type type) => module.UpdateRowId(ImportAsTypeSig(type, null, type.IsGenericType).ToTypeDefOrRef());
+
+ ///
+ /// Imports a as an used for .
+ ///
+ /// The method
+ /// The imported method or null if is invalid
+ /// or if we failed to import the method
+ public IMethod ImportAsOperand(MethodBase methodBase) => ImportInternal(methodBase, false, true);
+
+ ///
+ /// Imports a as an used for .
+ ///
+ /// The field
+ /// The imported field or null if is invalid
+ /// or if we failed to import the field
+ public IField ImportAsOperand(FieldInfo fieldInfo) => ImportInternal(fieldInfo, false, true);
}
}