Port more code

This commit is contained in:
de4dot 2012-11-03 22:49:52 +01:00
parent 4559939162
commit db6875859a
2 changed files with 178 additions and 28 deletions

View File

@ -23,35 +23,185 @@ using dot10.DotNet;
using de4dot.blocks; using de4dot.blocks;
namespace de4dot.code.renamer.asmmodules { namespace de4dot.code.renamer.asmmodules {
//TODO: struct GenericArgsSubstitutor {
class TypeRefInstantiator { IList<TypeSig> genericArgs;
public static ITypeDefOrRef Create(ITypeDefOrRef type, GenericInstSig git) { bool updated;
public static ITypeDefOrRef create(ITypeDefOrRef type, GenericInstSig git) {
if (git == null) if (git == null)
return type; return type;
return Create(type, git.GenericArguments); return create(type, git.GenericArguments);
} }
public static ITypeDefOrRef Create(ITypeDefOrRef type, IList<TypeSig> genericArgs) { public static ITypeDefOrRef create(ITypeDefOrRef type, IList<TypeSig> genericArgs) {
if (genericArgs == null || genericArgs.Count == 0) if (genericArgs == null || genericArgs.Count == 0)
return type; return type;
var ts = type as TypeSpec;
return type;//TODO: if (ts == null)
return type;
var newSig = create(ts.TypeSig, genericArgs);
return newSig == ts.TypeSig ? type : new TypeSpecUser(newSig);
} }
}
//TODO: public static TypeSig create(TypeSig type, IList<TypeSig> genericArgs) {
class MethodRefInstantiator { if (type == null || genericArgs == null || genericArgs.Count == 0)
public static IMethod Create(IMethod method, GenericInstSig git) { return type;
return new GenericArgsSubstitutor(genericArgs).create(type);
}
public static IMethodDefOrRef create(IMethodDefOrRef method, GenericInstSig git) {
if (git == null) if (git == null)
return method; return method;
return Create(method, git.GenericArguments); return create(method, git.GenericArguments);
} }
public static IMethod Create(IMethod method, IList<TypeSig> genericArgs) { // Creates a new method but keeps declaring type as is
if (genericArgs == null || genericArgs.Count == 0) public static IMethodDefOrRef create(IMethodDefOrRef method, IList<TypeSig> genericArgs) {
if (method == null || genericArgs == null || genericArgs.Count == 0)
return method; return method;
return method;//TODO: var sig = method.MethodSig;
if (sig == null)
return method;
var newSig = new GenericArgsSubstitutor(genericArgs).create(sig);
if (newSig == sig)
return method;
return new MemberRefUser(method.DeclaringType.OwnerModule, method.Name, newSig, method.DeclaringType);
}
GenericArgsSubstitutor(IList<TypeSig> genericArgs) {
this.genericArgs = genericArgs;
this.updated = false;
}
TypeSig create(TypeSig type) {
var newType = create2(type);
return updated ? newType : type;
}
TypeSig create2(TypeSig type) {
if (type == null)
return type;
TypeSig result;
switch (type.ElementType) {
case ElementType.Void:
case ElementType.Boolean:
case ElementType.Char:
case ElementType.I1:
case ElementType.U1:
case ElementType.I2:
case ElementType.U2:
case ElementType.I4:
case ElementType.U4:
case ElementType.I8:
case ElementType.U8:
case ElementType.R4:
case ElementType.R8:
case ElementType.String:
case ElementType.TypedByRef:
case ElementType.I:
case ElementType.U:
case ElementType.Object:
result = type;
break;
case ElementType.Ptr:
result = new PtrSig(create2(type.Next));
break;
case ElementType.ByRef:
result = new ByRefSig(create2(type.Next));
break;
case ElementType.Array:
var ary = (ArraySig)type;
result = new ArraySig(ary.Next, ary.Rank, ary.Sizes, ary.LowerBounds);
break;
case ElementType.SZArray:
result = new SZArraySig(create2(type.Next));
break;
case ElementType.Pinned:
result = new PinnedSig(create2(type.Next));
break;
case ElementType.ValueType:
case ElementType.Class:
result = type;
break;
case ElementType.Var:
var varSig = (GenericSig)type;
if (varSig.Number < (uint)genericArgs.Count) {
result = genericArgs[(int)varSig.Number];
updated = true;
}
else
result = type;
break;
case ElementType.MVar:
result = type;
break;
case ElementType.GenericInst:
var gis = (GenericInstSig)type;
var newGis = new GenericInstSig(create2(gis.GenericType) as ClassOrValueTypeSig, gis.GenericArguments.Count);
for (int i = 0; i < gis.GenericArguments.Count; i++)
newGis.GenericArguments.Add(create2(gis.GenericArguments[i]));
result = newGis;
break;
case ElementType.ValueArray:
result = new ValueArraySig(type.Next, ((ValueArraySig)type).Size);
break;
case ElementType.Module:
result = new ModuleSig(((ModuleSig)type).Index, type.Next);
break;
case ElementType.CModReqd:
result = new CModReqdSig(((ModifierSig)type).Modifier, type.Next);
break;
case ElementType.CModOpt:
result = new CModOptSig(((ModifierSig)type).Modifier, type.Next);
break;
case ElementType.FnPtr:
result = new FnPtrSig(create(((FnPtrSig)type).MethodSig));
break;
case ElementType.End:
case ElementType.R:
case ElementType.Sentinel:
case ElementType.Internal:
default:
result = type;
break;
}
return result;
}
MethodSig create(MethodSig sig) {
if (sig == null)
return sig;
var newSig = new MethodSig(sig.GetCallingConvention());
newSig.RetType = create2(sig.RetType);
for (int i = 0; i < sig.Params.Count; i++)
newSig.Params.Add(create2(sig.Params[i]));
newSig.GenParamCount = sig.GenParamCount;
if (sig.ParamsAfterSentinel != null) {
newSig.ParamsAfterSentinel = new List<TypeSig>();
for (int i = 0; i < sig.ParamsAfterSentinel.Count; i++)
newSig.ParamsAfterSentinel.Add(create2(sig.ParamsAfterSentinel[i]));
}
return updated ? newSig : sig;
} }
} }
@ -64,7 +214,7 @@ namespace de4dot.code.renamer.asmmodules {
} }
public TypeInfo(TypeInfo other, GenericInstSig git) { public TypeInfo(TypeInfo other, GenericInstSig git) {
this.typeReference = TypeRefInstantiator.Create(other.typeReference, git); this.typeReference = GenericArgsSubstitutor.create(other.typeReference, git);
this.typeDef = other.typeDef; this.typeDef = other.typeDef;
} }
@ -107,9 +257,9 @@ namespace de4dot.code.renamer.asmmodules {
class MethodInst { class MethodInst {
public MMethodDef origMethodDef; public MMethodDef origMethodDef;
public IMethod methodReference; public IMethodDefOrRef methodReference;
public MethodInst(MMethodDef origMethodDef, IMethod methodReference) { public MethodInst(MMethodDef origMethodDef, IMethodDefOrRef methodReference) {
this.origMethodDef = origMethodDef; this.origMethodDef = origMethodDef;
this.methodReference = methodReference; this.methodReference = methodReference;
} }
@ -120,12 +270,12 @@ namespace de4dot.code.renamer.asmmodules {
} }
class MethodInstances { class MethodInstances {
Dictionary<IMethod, List<MethodInst>> methodInstances = new Dictionary<IMethod, List<MethodInst>>(MethodEqualityComparer.DontCompareDeclaringTypes); Dictionary<IMethodDefOrRef, List<MethodInst>> methodInstances = new Dictionary<IMethodDefOrRef, List<MethodInst>>(MethodEqualityComparer.DontCompareDeclaringTypes);
public void initializeFrom(MethodInstances other, GenericInstSig git) { public void initializeFrom(MethodInstances other, GenericInstSig git) {
foreach (var list in other.methodInstances.Values) { foreach (var list in other.methodInstances.Values) {
foreach (var methodInst in list) { foreach (var methodInst in list) {
var newMethod = MethodRefInstantiator.Create(methodInst.methodReference, git); var newMethod = GenericArgsSubstitutor.create(methodInst.methodReference, git);
add(new MethodInst(methodInst.origMethodDef, newMethod)); add(new MethodInst(methodInst.origMethodDef, newMethod));
} }
} }
@ -139,7 +289,7 @@ namespace de4dot.code.renamer.asmmodules {
list.Add(methodInst); list.Add(methodInst);
} }
public List<MethodInst> lookup(IMethod methodReference) { public List<MethodInst> lookup(IMethodDefOrRef methodReference) {
List<MethodInst> list; List<MethodInst> list;
methodInstances.TryGetValue(methodReference, out list); methodInstances.TryGetValue(methodReference, out list);
return list; return list;
@ -545,7 +695,7 @@ namespace de4dot.code.renamer.asmmodules {
//--- virtual functions. //--- virtual functions.
// Done. See initializeAllInterfaces(). // Done. See initializeAllInterfaces().
var methodsDict = new Dictionary<IMethod, MMethodDef>(MethodEqualityComparer.DontCompareDeclaringTypes); var methodsDict = new Dictionary<IMethodDefOrRef, MMethodDef>(MethodEqualityComparer.DontCompareDeclaringTypes);
//--- * If this class explicitly specifies that it implements the interface (i.e., the //--- * If this class explicitly specifies that it implements the interface (i.e., the
//--- interfaces that appear in this class InterfaceImpl table, §22.23) //--- interfaces that appear in this class InterfaceImpl table, §22.23)
@ -568,7 +718,7 @@ namespace de4dot.code.renamer.asmmodules {
var ifaceMethod = methodInst.origMethodDef; var ifaceMethod = methodInst.origMethodDef;
if (!ifaceMethod.isVirtual()) if (!ifaceMethod.isVirtual())
continue; continue;
var ifaceMethodReference = MethodRefInstantiator.Create(methodInst.methodReference, ifaceInfo.typeReference.ToGenericInstSig()); var ifaceMethodReference = GenericArgsSubstitutor.create(methodInst.methodReference, ifaceInfo.typeReference.ToGenericInstSig());
MMethodDef classMethod; MMethodDef classMethod;
if (!methodsDict.TryGetValue(ifaceMethodReference, out classMethod)) if (!methodsDict.TryGetValue(ifaceMethodReference, out classMethod))
continue; continue;
@ -602,7 +752,7 @@ namespace de4dot.code.renamer.asmmodules {
var ifaceMethod = methodsList[0].origMethodDef; var ifaceMethod = methodsList[0].origMethodDef;
if (!ifaceMethod.isVirtual()) if (!ifaceMethod.isVirtual())
continue; continue;
var ifaceMethodRef = MethodRefInstantiator.Create(ifaceMethod.MethodDef, ifaceInfo.typeReference.ToGenericInstSig()); var ifaceMethodRef = GenericArgsSubstitutor.create(ifaceMethod.MethodDef, ifaceInfo.typeReference.ToGenericInstSig());
MMethodDef classMethod; MMethodDef classMethod;
if (!methodsDict.TryGetValue(ifaceMethodRef, out classMethod)) if (!methodsDict.TryGetValue(ifaceMethodRef, out classMethod))
continue; continue;
@ -614,11 +764,11 @@ namespace de4dot.code.renamer.asmmodules {
//--- explicitly specified virtual methods into the interface in preference to those //--- explicitly specified virtual methods into the interface in preference to those
//--- inherited or chosen by name matching. //--- inherited or chosen by name matching.
methodsDict.Clear(); methodsDict.Clear();
var ifaceMethodsDict = new Dictionary<IMethod, MMethodDef>(MethodEqualityComparer.CompareDeclaringTypes); var ifaceMethodsDict = new Dictionary<IMethodDefOrRef, MMethodDef>(MethodEqualityComparer.CompareDeclaringTypes);
foreach (var ifaceInfo in allImplementedInterfaces.Keys) { foreach (var ifaceInfo in allImplementedInterfaces.Keys) {
var git = ifaceInfo.typeReference.ToGenericInstSig(); var git = ifaceInfo.typeReference.ToGenericInstSig();
foreach (var ifaceMethod in ifaceInfo.typeDef.methods.getValues()) { foreach (var ifaceMethod in ifaceInfo.typeDef.methods.getValues()) {
IMethod ifaceMethodReference = ifaceMethod.MethodDef; IMethodDefOrRef ifaceMethodReference = ifaceMethod.MethodDef;
if (git != null) if (git != null)
ifaceMethodReference = simpleClone(ifaceMethod.MethodDef, ifaceInfo.typeReference); ifaceMethodReference = simpleClone(ifaceMethod.MethodDef, ifaceInfo.typeReference);
ifaceMethodsDict[ifaceMethodReference] = ifaceMethod; ifaceMethodsDict[ifaceMethodReference] = ifaceMethod;
@ -675,7 +825,7 @@ namespace de4dot.code.renamer.asmmodules {
bool hasAttribute(string name) { bool hasAttribute(string name) {
foreach (var attr in TypeDef.CustomAttributes) { foreach (var attr in TypeDef.CustomAttributes) {
if (attr.AttributeType.FullName == name) if (attr.TypeFullName == name)
return true; return true;
} }
return false; return false;

2
dot10

@ -1 +1 @@
Subproject commit 5e38e6ffb1a33d25d48a5487dc47a14e2cb2583c Subproject commit 4616892cf93d280c16be2c8b49dd4de7a9d0c92e