Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Why importing generic field should use assembly resolver to resolve original FieldDef #445

Closed
wwh1004 opened this issue Dec 30, 2021 · 1 comment

Comments

@wwh1004
Copy link
Contributor

wwh1004 commented Dec 30, 2021

public IField Import(FieldInfo fieldInfo, bool forceFixSignature) {

if (origField.FieldType.ContainsGenericParameters) {
	var origDeclType = origField.DeclaringType;
	var asm = module.Context.AssemblyResolver.Resolve(origDeclType.Module.Assembly.GetName(), module);
	if (asm is null || asm.FullName != origDeclType.Assembly.FullName)
		throw new Exception("Couldn't resolve the correct assembly");
	var mod = asm.FindModule(origDeclType.Module.ScopeName) as ModuleDefMD;
	if (mod is null)
		throw new Exception("Couldn't resolve the correct module");
	var fieldDef = mod.ResolveField((uint)(origField.MetadataToken & 0x00FFFFFF));
	if (fieldDef is null)
		throw new Exception("Couldn't resolve the correct field");

	var fieldSig = new FieldSig(Import(fieldDef.FieldSig.GetFieldType()));
	fieldRef = module.UpdateRowId(new MemberRefUser(module, fieldInfo.Name, fieldSig, parent));
}

Sometimes it is difficult to resolve assembly and importer will throw if AssemblyResolver is null.
e.g. Target assembly is memory loaded.

I don't know why generic field should be treated differently. I find it is changed in a old commit 4ebebc1
I've tested many cases of generic field and the old code (same behavior as importing generic method) can return the same result.

Test code:

static class G<T1, T2> where T1 : class {
 static volatile T1 Value1;
 static volatile IDictionary<T1, T2> Value2;

 static void MethodToImport<T3>() where T3 : class {
  Value1 = null;
  Value2 = null;
  G<string, string>.Value1 = null;
  G<string, string>.Value2 = null;
  G<string, T3>.Value1 = null;
  G<string, T3>.Value2 = null;
  G<T3, T3>.Value1 = null;
  G<T3, T3>.Value2 = null;
 }
}
@wtfsck
Copy link
Contributor

wtfsck commented Dec 30, 2021

I don't remember why. Have you tried opening many other .NET files and checking if the original code produces the same result as code that doesn't try to resolve the assembly?

If you can't find any problems, you can send a PR with a fix!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants