Add type ref updater base class
This commit is contained in:
parent
03a27110e7
commit
9d08a7fe34
|
@ -25,19 +25,11 @@ using Mono.Cecil;
|
|||
using de4dot.blocks;
|
||||
|
||||
namespace de4dot.blocks {
|
||||
public abstract class RefInstance {
|
||||
protected bool modified = false;
|
||||
|
||||
protected void checkModified(object a, object b) {
|
||||
if (!ReferenceEquals(a, b))
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
|
||||
public class TypeReferenceInstance : RefInstance {
|
||||
public class TypeReferenceInstance : TypeReferenceUpdaterBase {
|
||||
TypeReference typeReference;
|
||||
GenericInstanceType git;
|
||||
IGenericInstance gim;
|
||||
bool modified;
|
||||
|
||||
public static TypeReference make(TypeReference typeReference, GenericInstanceType git, IGenericInstance gim = null) {
|
||||
if (git == null && gim == null)
|
||||
|
@ -51,75 +43,25 @@ namespace de4dot.blocks {
|
|||
this.gim = gim;
|
||||
}
|
||||
|
||||
void checkModified(object a, object b) {
|
||||
if (!ReferenceEquals(a, b))
|
||||
modified = true;
|
||||
}
|
||||
|
||||
// Returns same one if nothing was modified
|
||||
TypeReference makeInstance() {
|
||||
var rv = makeInstance(typeReference);
|
||||
var rv = update(typeReference);
|
||||
return modified ? rv : typeReference;
|
||||
}
|
||||
|
||||
TypeReference makeInstance(TypeReference a) {
|
||||
if (a == null)
|
||||
return null;
|
||||
|
||||
var type = MemberReferenceHelper.getMemberReferenceType(a);
|
||||
switch (type) {
|
||||
case CecilType.ArrayType:
|
||||
return makeInstanceArrayType((ArrayType)a);
|
||||
case CecilType.ByReferenceType:
|
||||
return makeInstanceByReferenceType((ByReferenceType)a);
|
||||
case CecilType.FunctionPointerType:
|
||||
return makeInstanceFunctionPointerType((FunctionPointerType)a);
|
||||
case CecilType.GenericInstanceType:
|
||||
return makeInstanceGenericInstanceType((GenericInstanceType)a);
|
||||
case CecilType.GenericParameter:
|
||||
return makeInstanceGenericParameter((GenericParameter)a);
|
||||
case CecilType.OptionalModifierType:
|
||||
return makeInstanceOptionalModifierType((OptionalModifierType)a);
|
||||
case CecilType.PinnedType:
|
||||
return makeInstancePinnedType((PinnedType)a);
|
||||
case CecilType.PointerType:
|
||||
return makeInstancePointerType((PointerType)a);
|
||||
case CecilType.RequiredModifierType:
|
||||
return makeInstanceRequiredModifierType((RequiredModifierType)a);
|
||||
case CecilType.SentinelType:
|
||||
return makeInstanceSentinelType((SentinelType)a);
|
||||
case CecilType.TypeDefinition:
|
||||
return makeInstanceTypeDefinition((TypeDefinition)a);
|
||||
case CecilType.TypeReference:
|
||||
return makeInstanceTypeReference((TypeReference)a);
|
||||
default:
|
||||
throw new ApplicationException(string.Format("Unknown cecil type {0}", type));
|
||||
}
|
||||
}
|
||||
|
||||
ArrayType makeInstanceArrayType(ArrayType a) {
|
||||
var rv = new ArrayType(makeInstance(a.ElementType));
|
||||
if (!a.IsVector) {
|
||||
foreach (var dim in a.Dimensions)
|
||||
rv.Dimensions.Add(dim);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
ByReferenceType makeInstanceByReferenceType(ByReferenceType a) {
|
||||
return new ByReferenceType(makeInstance(a.ElementType));
|
||||
}
|
||||
|
||||
FunctionPointerType makeInstanceFunctionPointerType(FunctionPointerType a) {
|
||||
protected override FunctionPointerType updateFunctionPointerType(FunctionPointerType a) {
|
||||
var rv = new FunctionPointerType();
|
||||
rv.function = MethodReferenceInstance.make(a.function, git, gim);
|
||||
checkModified(a.function, rv.function);
|
||||
return rv;
|
||||
}
|
||||
|
||||
GenericInstanceType makeInstanceGenericInstanceType(GenericInstanceType a) {
|
||||
var rv = new GenericInstanceType(makeInstance(a.ElementType));
|
||||
foreach (var arg in a.GenericArguments)
|
||||
rv.GenericArguments.Add(makeInstance(arg));
|
||||
return rv;
|
||||
}
|
||||
|
||||
TypeReference makeInstanceGenericParameter(GenericParameter a) {
|
||||
protected override TypeReference updateGenericParameter(GenericParameter a) {
|
||||
switch (a.Type) {
|
||||
case GenericParameterType.Type:
|
||||
if (git == null || a.Position >= git.GenericArguments.Count ||
|
||||
|
@ -127,57 +69,35 @@ namespace de4dot.blocks {
|
|||
return a;
|
||||
}
|
||||
modified = true;
|
||||
return makeInstance(git.GenericArguments[a.Position]);
|
||||
return update(git.GenericArguments[a.Position]);
|
||||
|
||||
case GenericParameterType.Method:
|
||||
if (gim == null || a.Position >= gim.GenericArguments.Count)
|
||||
return a;
|
||||
modified = true;
|
||||
return makeInstance(gim.GenericArguments[a.Position]);
|
||||
return update(gim.GenericArguments[a.Position]);
|
||||
|
||||
default:
|
||||
return a;
|
||||
}
|
||||
}
|
||||
|
||||
OptionalModifierType makeInstanceOptionalModifierType(OptionalModifierType a) {
|
||||
return new OptionalModifierType(makeInstance(a.ModifierType), makeInstance(a.ElementType));
|
||||
}
|
||||
|
||||
PinnedType makeInstancePinnedType(PinnedType a) {
|
||||
return new PinnedType(makeInstance(a.ElementType));
|
||||
}
|
||||
|
||||
PointerType makeInstancePointerType(PointerType a) {
|
||||
return new PointerType(makeInstance(a.ElementType));
|
||||
}
|
||||
|
||||
RequiredModifierType makeInstanceRequiredModifierType(RequiredModifierType a) {
|
||||
return new RequiredModifierType(makeInstance(a.ModifierType), makeInstance(a.ElementType));
|
||||
}
|
||||
|
||||
SentinelType makeInstanceSentinelType(SentinelType a) {
|
||||
return new SentinelType(makeInstance(a.ElementType));
|
||||
}
|
||||
|
||||
TypeReference makeInstanceTypeDefinition(TypeDefinition a) {
|
||||
return makeInstanceTypeReference(a);
|
||||
}
|
||||
|
||||
TypeReference makeInstanceTypeReference(TypeReference a) {
|
||||
return a;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class MultiTypeRefInstance : RefInstance {
|
||||
public abstract class MultiTypeRefInstance {
|
||||
GenericInstanceType git;
|
||||
IGenericInstance gim;
|
||||
bool modified;
|
||||
|
||||
public MultiTypeRefInstance(GenericInstanceType git, IGenericInstance gim = null) {
|
||||
this.git = git;
|
||||
this.gim = gim;
|
||||
}
|
||||
|
||||
void checkModified(object a, object b) {
|
||||
if (!ReferenceEquals(a, b))
|
||||
modified = true;
|
||||
}
|
||||
|
||||
protected TypeReference makeInstance(TypeReference tr) {
|
||||
var type = TypeReferenceInstance.make(tr, git, gim);
|
||||
checkModified(type, tr);
|
||||
|
|
118
blocks/TypeReferenceUpdaterBase.cs
Normal file
118
blocks/TypeReferenceUpdaterBase.cs
Normal file
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
Copyright (C) 2011 de4dot@gmail.com
|
||||
|
||||
This file is part of de4dot.
|
||||
|
||||
de4dot is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
de4dot is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using Mono.Cecil;
|
||||
|
||||
namespace de4dot.blocks {
|
||||
public abstract class TypeReferenceUpdaterBase {
|
||||
public TypeReference update(TypeReference a) {
|
||||
if (a == null)
|
||||
return null;
|
||||
|
||||
var type = MemberReferenceHelper.getMemberReferenceType(a);
|
||||
switch (type) {
|
||||
case CecilType.ArrayType:
|
||||
return updateArrayType((ArrayType)a);
|
||||
case CecilType.ByReferenceType:
|
||||
return updateByReferenceType((ByReferenceType)a);
|
||||
case CecilType.FunctionPointerType:
|
||||
return updateFunctionPointerType((FunctionPointerType)a);
|
||||
case CecilType.GenericInstanceType:
|
||||
return updateGenericInstanceType((GenericInstanceType)a);
|
||||
case CecilType.GenericParameter:
|
||||
return updateGenericParameter((GenericParameter)a);
|
||||
case CecilType.OptionalModifierType:
|
||||
return updateOptionalModifierType((OptionalModifierType)a);
|
||||
case CecilType.PinnedType:
|
||||
return updatePinnedType((PinnedType)a);
|
||||
case CecilType.PointerType:
|
||||
return updatePointerType((PointerType)a);
|
||||
case CecilType.RequiredModifierType:
|
||||
return updateRequiredModifierType((RequiredModifierType)a);
|
||||
case CecilType.SentinelType:
|
||||
return updateSentinelType((SentinelType)a);
|
||||
case CecilType.TypeDefinition:
|
||||
return updateTypeDefinition((TypeDefinition)a);
|
||||
case CecilType.TypeReference:
|
||||
return updateTypeReference((TypeReference)a);
|
||||
default:
|
||||
throw new ApplicationException(string.Format("Unknown cecil type {0}", type));
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual ArrayType updateArrayType(ArrayType a) {
|
||||
var rv = new ArrayType(update(a.ElementType));
|
||||
if (!a.IsVector) {
|
||||
foreach (var dim in a.Dimensions)
|
||||
rv.Dimensions.Add(dim);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
protected virtual ByReferenceType updateByReferenceType(ByReferenceType a) {
|
||||
return new ByReferenceType(update(a.ElementType));
|
||||
}
|
||||
|
||||
protected virtual FunctionPointerType updateFunctionPointerType(FunctionPointerType a) {
|
||||
var rv = new FunctionPointerType();
|
||||
rv.function = a.function;
|
||||
return rv;
|
||||
}
|
||||
|
||||
protected virtual GenericInstanceType updateGenericInstanceType(GenericInstanceType a) {
|
||||
var rv = new GenericInstanceType(update(a.ElementType));
|
||||
foreach (var arg in a.GenericArguments)
|
||||
rv.GenericArguments.Add(update(arg));
|
||||
return rv;
|
||||
}
|
||||
|
||||
protected virtual TypeReference updateGenericParameter(GenericParameter a) {
|
||||
return a;
|
||||
}
|
||||
|
||||
protected virtual OptionalModifierType updateOptionalModifierType(OptionalModifierType a) {
|
||||
return new OptionalModifierType(update(a.ModifierType), update(a.ElementType));
|
||||
}
|
||||
|
||||
protected virtual PinnedType updatePinnedType(PinnedType a) {
|
||||
return new PinnedType(update(a.ElementType));
|
||||
}
|
||||
|
||||
protected virtual PointerType updatePointerType(PointerType a) {
|
||||
return new PointerType(update(a.ElementType));
|
||||
}
|
||||
|
||||
protected virtual RequiredModifierType updateRequiredModifierType(RequiredModifierType a) {
|
||||
return new RequiredModifierType(update(a.ModifierType), update(a.ElementType));
|
||||
}
|
||||
|
||||
protected virtual SentinelType updateSentinelType(SentinelType a) {
|
||||
return new SentinelType(update(a.ElementType));
|
||||
}
|
||||
|
||||
protected virtual TypeReference updateTypeDefinition(TypeDefinition a) {
|
||||
return updateTypeReference(a);
|
||||
}
|
||||
|
||||
protected virtual TypeReference updateTypeReference(TypeReference a) {
|
||||
return a;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -68,6 +68,7 @@
|
|||
<Compile Include="ScopeBlock.cs" />
|
||||
<Compile Include="TryBlock.cs" />
|
||||
<Compile Include="TryHandlerBlock.cs" />
|
||||
<Compile Include="TypeReferenceUpdaterBase.cs" />
|
||||
<Compile Include="Utils.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
Loading…
Reference in New Issue
Block a user