Browse Source

Merge branch 'master' of git://github.com/icsharpcode/ILSpy into Debugger

pull/191/merge
Eusebiu Marcu 15 years ago
parent
commit
b21d251a6e
  1. 48
      ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs
  2. 8
      ICSharpCode.Decompiler/Ast/NameVariables.cs
  3. 13
      ICSharpCode.Decompiler/ILAst/ILAstBuilder.cs
  4. 450
      ICSharpCode.Decompiler/ILAst/TypeAnalysis.cs
  5. 1
      ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj
  6. 50
      ICSharpCode.Decompiler/Tests/PropertiesAndEvents.cs
  7. 6
      Mono.Cecil/Mono.Cecil/AssemblyDefinition.cs
  8. 7
      Mono.Cecil/Mono.Cecil/AssemblyNameReference.cs
  9. 3
      Mono.Cecil/Mono.Cecil/AssemblyReader.cs
  10. 33
      Mono.Cecil/Mono.Cecil/CustomAttribute.cs
  11. 20
      Mono.Cecil/Mono.Cecil/EventDefinition.cs
  12. 14
      Mono.Cecil/Mono.Cecil/FieldDefinition.cs
  13. 4
      Mono.Cecil/Mono.Cecil/GenericParameter.cs
  14. 11
      Mono.Cecil/Mono.Cecil/IConstantProvider.cs
  15. 6
      Mono.Cecil/Mono.Cecil/ICustomAttributeProvider.cs
  16. 5
      Mono.Cecil/Mono.Cecil/IGenericParameterProvider.cs
  17. 3
      Mono.Cecil/Mono.Cecil/IMarshalInfoProvider.cs
  18. 26
      Mono.Cecil/Mono.Cecil/MethodDefinition.cs
  19. 50
      Mono.Cecil/Mono.Cecil/ModuleDefinition.cs
  20. 14
      Mono.Cecil/Mono.Cecil/ParameterDefinition.cs
  21. 26
      Mono.Cecil/Mono.Cecil/PropertyDefinition.cs
  22. 7
      Mono.Cecil/Mono.Cecil/SecurityDeclaration.cs
  23. 18
      Mono.Cecil/Mono.Cecil/TypeDefinition.cs
  24. 61
      Mono.Cecil/Mono.Cecil/TypeSystem.cs

48
ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs

@ -616,11 +616,22 @@ namespace Decompiler @@ -616,11 +616,22 @@ namespace Decompiler
if (prop.GetMethod == cecilMethodDef)
return target.Member(prop.Name).WithAnnotation(prop);
}
} else if (cecilMethodDef.IsGetter) { // with parameters
PropertyDefinition indexer = GetIndexer(cecilMethodDef);
if (indexer != null)
return target.Indexer(methodArgs).WithAnnotation(indexer);
} else if (cecilMethodDef.IsSetter && methodArgs.Count == 1) {
foreach (var prop in cecilMethodDef.DeclaringType.Properties) {
if (prop.SetMethod == cecilMethodDef)
return new Ast.AssignmentExpression(target.Member(prop.Name).WithAnnotation(prop), methodArgs[0]);
}
} else if (cecilMethodDef.IsSetter && methodArgs.Count > 1) {
PropertyDefinition indexer = GetIndexer(cecilMethodDef);
if (indexer != null)
return new AssignmentExpression(
target.Indexer(methodArgs.GetRange(0, methodArgs.Count - 1)).WithAnnotation(indexer),
methodArgs[methodArgs.Count - 1]
);
} else if (cecilMethodDef.IsAddOn && methodArgs.Count == 1) {
foreach (var ev in cecilMethodDef.DeclaringType.Events) {
if (ev.AddMethod == cecilMethodDef) {
@ -647,6 +658,27 @@ namespace Decompiler @@ -647,6 +658,27 @@ namespace Decompiler
return target.Invoke(cecilMethod.Name, ConvertTypeArguments(cecilMethod), methodArgs).WithAnnotation(cecilMethod);
}
static PropertyDefinition GetIndexer(MethodDefinition cecilMethodDef)
{
TypeDefinition typeDef = cecilMethodDef.DeclaringType;
string indexerName = null;
foreach (CustomAttribute ca in typeDef.CustomAttributes) {
if (ca.Constructor.FullName == "System.Void System.Reflection.DefaultMemberAttribute::.ctor(System.String)") {
indexerName = ca.ConstructorArguments.Single().Value as string;
break;
}
}
if (indexerName == null)
return null;
foreach (PropertyDefinition prop in typeDef.Properties) {
if (prop.Name == indexerName) {
if (prop.GetMethod == cecilMethodDef || prop.SetMethod == cecilMethodDef)
return prop;
}
}
return null;
}
#if DEBUG
static readonly ConcurrentDictionary<ILCode, int> unhandledOpcodes = new ConcurrentDictionary<ILCode, int>();
#endif
@ -699,17 +731,19 @@ namespace Decompiler @@ -699,17 +731,19 @@ namespace Decompiler
if (reqType == null || actualType == reqType) {
return expr;
} else {
bool actualIsIntegerOrEnum = TypeAnalysis.IsIntegerOrEnum(typeSystem, actualType);
bool requiredIsIntegerOrEnum = TypeAnalysis.IsIntegerOrEnum(typeSystem, reqType);
bool actualIsIntegerOrEnum = TypeAnalysis.IsIntegerOrEnum(actualType);
bool requiredIsIntegerOrEnum = TypeAnalysis.IsIntegerOrEnum(reqType);
if (reqType == typeSystem.Boolean) {
if (TypeAnalysis.IsBoolean(reqType)) {
if (TypeAnalysis.IsBoolean(actualType))
return expr;
if (actualIsIntegerOrEnum) {
return new BinaryOperatorExpression(expr, BinaryOperatorType.InEquality, PrimitiveExpression(0, actualType));
} else {
return new BinaryOperatorExpression(expr, BinaryOperatorType.InEquality, new NullReferenceExpression());
}
}
if (actualType == typeSystem.Boolean && requiredIsIntegerOrEnum) {
if (TypeAnalysis.IsBoolean(actualType) && requiredIsIntegerOrEnum) {
return new ConditionalExpression {
Condition = expr,
TrueExpression = PrimitiveExpression(1, reqType),
@ -725,9 +759,9 @@ namespace Decompiler @@ -725,9 +759,9 @@ namespace Decompiler
Expression PrimitiveExpression(long val, TypeReference type)
{
if (type == typeSystem.Boolean && val == 0)
if (TypeAnalysis.IsBoolean(type) && val == 0)
return new Ast.PrimitiveExpression(false);
else if (type == typeSystem.Boolean && val == 1)
else if (TypeAnalysis.IsBoolean(type) && val == 1)
return new Ast.PrimitiveExpression(true);
if (type != null) { // cannot rely on type.IsValueType, it's not set for typerefs (but is set for typespecs)
TypeDefinition enumDefinition = type.Resolve();
@ -740,7 +774,7 @@ namespace Decompiler @@ -740,7 +774,7 @@ namespace Decompiler
}
}
}
TypeCode code = TypeAnalysis.GetTypeCode(typeSystem, type);
TypeCode code = TypeAnalysis.GetTypeCode(type);
if (code == TypeCode.Object)
return new Ast.PrimitiveExpression((int)val);
else

8
ICSharpCode.Decompiler/Ast/NameVariables.cs

@ -25,6 +25,7 @@ namespace Decompiler @@ -25,6 +25,7 @@ namespace Decompiler
{ "System.Decimal", "num" },
{ "System.String", "text" },
{ "System.Object", "obj" },
{ "System.Char", "c" }
};
@ -105,10 +106,13 @@ namespace Decompiler @@ -105,10 +106,13 @@ namespace Decompiler
case ILCode.Call:
case ILCode.Callvirt:
MethodReference mr = (MethodReference)expr.Operand;
if (mr.Name.StartsWith("get_", StringComparison.Ordinal))
if (mr.Name.StartsWith("get_", StringComparison.Ordinal) && mr.Parameters.Count == 0) {
// use name from properties, but not from indexers
return CleanUpVariableName(mr.Name.Substring(4));
else if (mr.Name.StartsWith("Get", StringComparison.Ordinal) && mr.Name.Length >= 4 && char.IsUpper(mr.Name[3]))
} else if (mr.Name.StartsWith("Get", StringComparison.Ordinal) && mr.Name.Length >= 4 && char.IsUpper(mr.Name[3])) {
// use name from Get-methods
return CleanUpVariableName(mr.Name.Substring(3));
}
break;
}
return null;

13
ICSharpCode.Decompiler/ILAst/ILAstBuilder.cs

@ -495,20 +495,15 @@ namespace Decompiler @@ -495,20 +495,15 @@ namespace Decompiler
bool canInline;
allowInline.TryGetValue((ILVariable)arg.Operand, out canInline);
// Assigne the ranges for optimized away instrustions somewhere
currExpr.Arguments[0].ILRanges.AddRange(currExpr.ILRanges);
currExpr.Arguments[0].ILRanges.AddRange(nextExpr.Arguments[j].ILRanges);
if (canInline) {
// Assigne the ranges for optimized away instrustions somewhere
currExpr.Arguments[0].ILRanges.AddRange(currExpr.ILRanges);
currExpr.Arguments[0].ILRanges.AddRange(nextExpr.Arguments[j].ILRanges);
ast.RemoveAt(i);
nextExpr.Arguments[j] = currExpr.Arguments[0]; // Inline the stloc body
i -= 2; // Try the same index again
break; // Found
} else {
ast.RemoveAt(i);
nextExpr.Arguments[j] = currExpr; // Inline the whole stloc
i -= 2; // Try the same index again
break; // Found
}
}
} else {

450
ICSharpCode.Decompiler/ILAst/TypeAnalysis.cs

@ -106,6 +106,7 @@ namespace Decompiler @@ -106,6 +106,7 @@ namespace Decompiler
TypeReference DoInferTypeForExpression(ILExpression expr, TypeReference expectedType, bool forceInferChildren = false)
{
switch (expr.Code) {
#region Logical operators
case ILCode.LogicNot:
if (forceInferChildren) {
InferTypeForExpression(expr.Arguments.Single(), typeSystem.Boolean);
@ -118,10 +119,9 @@ namespace Decompiler @@ -118,10 +119,9 @@ namespace Decompiler
InferTypeForExpression(expr.Arguments[0], typeSystem.Boolean);
}
return typeSystem.Boolean;
}
switch ((Code)expr.Code) {
#endregion
#region Variable load/store
case Code.Stloc:
case ILCode.Stloc:
{
ILVariable v = (ILVariable)expr.Operand;
if (forceInferChildren || v.Type == null) {
@ -131,7 +131,7 @@ namespace Decompiler @@ -131,7 +131,7 @@ namespace Decompiler
}
return v.Type;
}
case Code.Ldloc:
case ILCode.Ldloc:
{
ILVariable v = (ILVariable)expr.Operand;
if (v.Type == null) {
@ -143,20 +143,20 @@ namespace Decompiler @@ -143,20 +143,20 @@ namespace Decompiler
}
return v.Type;
}
case Code.Starg:
case ILCode.Starg:
if (forceInferChildren)
InferTypeForExpression(expr.Arguments.Single(), ((ParameterReference)expr.Operand).ParameterType);
return null;
case Code.Ldarg:
case ILCode.Ldarg:
return ((ParameterReference)expr.Operand).ParameterType;
case Code.Ldloca:
case ILCode.Ldloca:
return new ByReferenceType(((ILVariable)expr.Operand).Type);
case Code.Ldarga:
case ILCode.Ldarga:
return new ByReferenceType(((ParameterReference)expr.Operand).ParameterType);
#endregion
#region Call / NewObj
case Code.Call:
case Code.Callvirt:
case ILCode.Call:
case ILCode.Callvirt:
{
MethodReference method = (MethodReference)expr.Operand;
if (forceInferChildren) {
@ -174,7 +174,7 @@ namespace Decompiler @@ -174,7 +174,7 @@ namespace Decompiler
}
return SubstituteTypeArgs(method.ReturnType, method);
}
case Code.Newobj:
case ILCode.Newobj:
{
MethodReference ctor = (MethodReference)expr.Operand;
if (forceInferChildren) {
@ -186,139 +186,139 @@ namespace Decompiler @@ -186,139 +186,139 @@ namespace Decompiler
}
#endregion
#region Load/Store Fields
case Code.Ldfld:
case ILCode.Ldfld:
if (forceInferChildren)
InferTypeForExpression(expr.Arguments[0], ((FieldReference)expr.Operand).DeclaringType);
return GetFieldType((FieldReference)expr.Operand);
case Code.Ldsfld:
case ILCode.Ldsfld:
return GetFieldType((FieldReference)expr.Operand);
case Code.Ldflda:
case Code.Ldsflda:
case ILCode.Ldflda:
case ILCode.Ldsflda:
return new ByReferenceType(GetFieldType((FieldReference)expr.Operand));
case Code.Stfld:
case ILCode.Stfld:
if (forceInferChildren) {
InferTypeForExpression(expr.Arguments[0], ((FieldReference)expr.Operand).DeclaringType);
InferTypeForExpression(expr.Arguments[1], GetFieldType((FieldReference)expr.Operand));
}
return null;
case Code.Stsfld:
case ILCode.Stsfld:
if (forceInferChildren)
InferTypeForExpression(expr.Arguments[0], GetFieldType((FieldReference)expr.Operand));
return null;
#endregion
#region Reference/Pointer instructions
case Code.Ldind_I:
case Code.Ldind_I1:
case Code.Ldind_I2:
case Code.Ldind_I4:
case Code.Ldind_I8:
case Code.Ldind_U1:
case Code.Ldind_U2:
case Code.Ldind_U4:
case Code.Ldind_R4:
case Code.Ldind_R8:
case Code.Ldind_Ref:
case ILCode.Ldind_I:
case ILCode.Ldind_I1:
case ILCode.Ldind_I2:
case ILCode.Ldind_I4:
case ILCode.Ldind_I8:
case ILCode.Ldind_U1:
case ILCode.Ldind_U2:
case ILCode.Ldind_U4:
case ILCode.Ldind_R4:
case ILCode.Ldind_R8:
case ILCode.Ldind_Ref:
return UnpackPointer(InferTypeForExpression(expr.Arguments[0], null));
case Code.Stind_I1:
case Code.Stind_I2:
case Code.Stind_I4:
case Code.Stind_I8:
case Code.Stind_R4:
case Code.Stind_R8:
case Code.Stind_I:
case Code.Stind_Ref:
case ILCode.Stind_I1:
case ILCode.Stind_I2:
case ILCode.Stind_I4:
case ILCode.Stind_I8:
case ILCode.Stind_R4:
case ILCode.Stind_R8:
case ILCode.Stind_I:
case ILCode.Stind_Ref:
if (forceInferChildren) {
TypeReference elementType = UnpackPointer(InferTypeForExpression(expr.Arguments[0], null));
InferTypeForExpression(expr.Arguments[1], elementType);
}
return null;
case Code.Ldobj:
case ILCode.Ldobj:
return (TypeReference)expr.Operand;
case Code.Stobj:
case ILCode.Stobj:
if (forceInferChildren) {
InferTypeForExpression(expr.Arguments[1], (TypeReference)expr.Operand);
}
return null;
case Code.Initobj:
case ILCode.Initobj:
return null;
case Code.Localloc:
case ILCode.Localloc:
return typeSystem.IntPtr;
#endregion
#region Arithmetic instructions
case Code.Not: // bitwise complement
case Code.Neg:
case ILCode.Not: // bitwise complement
case ILCode.Neg:
return InferTypeForExpression(expr.Arguments.Single(), expectedType);
case Code.Add:
case Code.Sub:
case Code.Mul:
case Code.Or:
case Code.And:
case Code.Xor:
case ILCode.Add:
case ILCode.Sub:
case ILCode.Mul:
case ILCode.Or:
case ILCode.And:
case ILCode.Xor:
return InferArgumentsInBinaryOperator(expr, null);
case Code.Add_Ovf:
case Code.Sub_Ovf:
case Code.Mul_Ovf:
case Code.Div:
case Code.Rem:
case ILCode.Add_Ovf:
case ILCode.Sub_Ovf:
case ILCode.Mul_Ovf:
case ILCode.Div:
case ILCode.Rem:
return InferArgumentsInBinaryOperator(expr, true);
case Code.Add_Ovf_Un:
case Code.Sub_Ovf_Un:
case Code.Mul_Ovf_Un:
case Code.Div_Un:
case Code.Rem_Un:
case ILCode.Add_Ovf_Un:
case ILCode.Sub_Ovf_Un:
case ILCode.Mul_Ovf_Un:
case ILCode.Div_Un:
case ILCode.Rem_Un:
return InferArgumentsInBinaryOperator(expr, false);
case Code.Shl:
case Code.Shr:
case ILCode.Shl:
case ILCode.Shr:
if (forceInferChildren)
InferTypeForExpression(expr.Arguments[1], typeSystem.Int32);
return InferTypeForExpression(expr.Arguments[0], typeSystem.Int32);
case Code.Shr_Un:
case ILCode.Shr_Un:
if (forceInferChildren)
InferTypeForExpression(expr.Arguments[1], typeSystem.Int32);
return InferTypeForExpression(expr.Arguments[0], typeSystem.UInt32);
#endregion
#region Constant loading instructions
case Code.Ldnull:
case ILCode.Ldnull:
return typeSystem.Object;
case Code.Ldstr:
case ILCode.Ldstr:
return typeSystem.String;
case Code.Ldftn:
case Code.Ldvirtftn:
case ILCode.Ldftn:
case ILCode.Ldvirtftn:
return typeSystem.IntPtr;
case Code.Ldc_I4:
return (IsIntegerOrEnum(expectedType) || expectedType == typeSystem.Boolean) ? expectedType : typeSystem.Int32;
case Code.Ldc_I8:
case ILCode.Ldc_I4:
return (IsIntegerOrEnum(expectedType) || IsBoolean(expectedType)) ? expectedType : typeSystem.Int32;
case ILCode.Ldc_I8:
return (IsIntegerOrEnum(expectedType)) ? expectedType : typeSystem.Int64;
case Code.Ldc_R4:
case ILCode.Ldc_R4:
return typeSystem.Single;
case Code.Ldc_R8:
case ILCode.Ldc_R8:
return typeSystem.Double;
case Code.Ldtoken:
case ILCode.Ldtoken:
if (expr.Operand is TypeReference)
return new TypeReference("System", "RuntimeTypeHandle", module, module, true);
else if (expr.Operand is FieldReference)
return new TypeReference("System", "RuntimeFieldHandle", module, module, true);
else
return new TypeReference("System", "RuntimeMethodHandle", module, module, true);
case Code.Arglist:
case ILCode.Arglist:
return new TypeReference("System", "RuntimeArgumentHandle", module, module, true);
#endregion
#region Array instructions
case Code.Newarr:
case ILCode.Newarr:
if (forceInferChildren)
InferTypeForExpression(expr.Arguments.Single(), typeSystem.Int32);
return new ArrayType((TypeReference)expr.Operand);
case Code.Ldlen:
case ILCode.Ldlen:
return typeSystem.Int32;
case Code.Ldelem_U1:
case Code.Ldelem_U2:
case Code.Ldelem_U4:
case Code.Ldelem_I1:
case Code.Ldelem_I2:
case Code.Ldelem_I4:
case Code.Ldelem_I8:
case Code.Ldelem_I:
case Code.Ldelem_Ref:
case ILCode.Ldelem_U1:
case ILCode.Ldelem_U2:
case ILCode.Ldelem_U4:
case ILCode.Ldelem_I1:
case ILCode.Ldelem_I2:
case ILCode.Ldelem_I4:
case ILCode.Ldelem_I8:
case ILCode.Ldelem_I:
case ILCode.Ldelem_Ref:
{
ArrayType arrayType = InferTypeForExpression(expr.Arguments[0], null) as ArrayType;
if (forceInferChildren) {
@ -327,27 +327,27 @@ namespace Decompiler @@ -327,27 +327,27 @@ namespace Decompiler
}
return arrayType != null ? arrayType.ElementType : null;
}
case Code.Ldelem_Any:
case ILCode.Ldelem_Any:
if (forceInferChildren) {
InferTypeForExpression(expr.Arguments[1], typeSystem.Int32);
}
return (TypeReference)expr.Operand;
case Code.Ldelema:
case ILCode.Ldelema:
{
ArrayType arrayType = InferTypeForExpression(expr.Arguments[0], null) as ArrayType;
if (forceInferChildren)
InferTypeForExpression(expr.Arguments[1], typeSystem.Int32);
return arrayType != null ? new ByReferenceType(arrayType.ElementType) : null;
}
case Code.Stelem_I:
case Code.Stelem_I1:
case Code.Stelem_I2:
case Code.Stelem_I4:
case Code.Stelem_I8:
case Code.Stelem_R4:
case Code.Stelem_R8:
case Code.Stelem_Ref:
case Code.Stelem_Any:
case ILCode.Stelem_I:
case ILCode.Stelem_I1:
case ILCode.Stelem_I2:
case ILCode.Stelem_I4:
case ILCode.Stelem_I8:
case ILCode.Stelem_R4:
case ILCode.Stelem_R8:
case ILCode.Stelem_Ref:
case ILCode.Stelem_Any:
if (forceInferChildren) {
ArrayType arrayType = InferTypeForExpression(expr.Arguments[0], null) as ArrayType;
InferTypeForExpression(expr.Arguments[1], typeSystem.Int32);
@ -358,107 +358,107 @@ namespace Decompiler @@ -358,107 +358,107 @@ namespace Decompiler
return null;
#endregion
#region Conversion instructions
case Code.Conv_I1:
case Code.Conv_Ovf_I1:
case ILCode.Conv_I1:
case ILCode.Conv_Ovf_I1:
return (GetInformationAmount(expectedType) == 8 && IsSigned(expectedType) == true) ? expectedType : typeSystem.SByte;
case Code.Conv_I2:
case Code.Conv_Ovf_I2:
case ILCode.Conv_I2:
case ILCode.Conv_Ovf_I2:
return (GetInformationAmount(expectedType) == 16 && IsSigned(expectedType) == true) ? expectedType : typeSystem.Int16;
case Code.Conv_I4:
case Code.Conv_Ovf_I4:
case ILCode.Conv_I4:
case ILCode.Conv_Ovf_I4:
return (GetInformationAmount(expectedType) == 32 && IsSigned(expectedType) == true) ? expectedType : typeSystem.Int32;
case Code.Conv_I8:
case Code.Conv_Ovf_I8:
case ILCode.Conv_I8:
case ILCode.Conv_Ovf_I8:
return (GetInformationAmount(expectedType) == 64 && IsSigned(expectedType) == true) ? expectedType : typeSystem.Int64;
case Code.Conv_U1:
case Code.Conv_Ovf_U1:
case ILCode.Conv_U1:
case ILCode.Conv_Ovf_U1:
return (GetInformationAmount(expectedType) == 8 && IsSigned(expectedType) == false) ? expectedType : typeSystem.Byte;
case Code.Conv_U2:
case Code.Conv_Ovf_U2:
case ILCode.Conv_U2:
case ILCode.Conv_Ovf_U2:
return (GetInformationAmount(expectedType) == 16 && IsSigned(expectedType) == false) ? expectedType : typeSystem.UInt16;
case Code.Conv_U4:
case Code.Conv_Ovf_U4:
case ILCode.Conv_U4:
case ILCode.Conv_Ovf_U4:
return (GetInformationAmount(expectedType) == 32 && IsSigned(expectedType) == false) ? expectedType : typeSystem.UInt32;
case Code.Conv_U8:
case Code.Conv_Ovf_U8:
case ILCode.Conv_U8:
case ILCode.Conv_Ovf_U8:
return (GetInformationAmount(expectedType) == 64 && IsSigned(expectedType) == false) ? expectedType : typeSystem.UInt64;
case Code.Conv_I:
case Code.Conv_Ovf_I:
case ILCode.Conv_I:
case ILCode.Conv_Ovf_I:
return (GetInformationAmount(expectedType) == nativeInt && IsSigned(expectedType) == true) ? expectedType : typeSystem.IntPtr;
case Code.Conv_U:
case Code.Conv_Ovf_U:
case ILCode.Conv_U:
case ILCode.Conv_Ovf_U:
return (GetInformationAmount(expectedType) == nativeInt && IsSigned(expectedType) == false) ? expectedType : typeSystem.UIntPtr;
case Code.Conv_R4:
case ILCode.Conv_R4:
return typeSystem.Single;
case Code.Conv_R8:
case ILCode.Conv_R8:
return typeSystem.Double;
case Code.Conv_R_Un:
return (expectedType == typeSystem.Single) ? typeSystem.Single : typeSystem.Double;
case Code.Castclass:
case Code.Isinst:
case Code.Unbox_Any:
case ILCode.Conv_R_Un:
return (expectedType != null && expectedType.MetadataType == MetadataType.Single) ? typeSystem.Single : typeSystem.Double;
case ILCode.Castclass:
case ILCode.Isinst:
case ILCode.Unbox_Any:
return (TypeReference)expr.Operand;
case Code.Box:
case ILCode.Box:
if (forceInferChildren)
InferTypeForExpression(expr.Arguments.Single(), (TypeReference)expr.Operand);
return (TypeReference)expr.Operand;
#endregion
#region Comparison instructions
case Code.Ceq:
case ILCode.Ceq:
if (forceInferChildren)
InferArgumentsInBinaryOperator(expr, null);
return typeSystem.Boolean;
case Code.Clt:
case Code.Cgt:
case ILCode.Clt:
case ILCode.Cgt:
if (forceInferChildren)
InferArgumentsInBinaryOperator(expr, true);
return typeSystem.Boolean;
case Code.Clt_Un:
case Code.Cgt_Un:
case ILCode.Clt_Un:
case ILCode.Cgt_Un:
if (forceInferChildren)
InferArgumentsInBinaryOperator(expr, false);
return typeSystem.Boolean;
#endregion
#region Branch instructions
case Code.Beq:
case Code.Bne_Un:
case ILCode.Beq:
case ILCode.Bne_Un:
if (forceInferChildren)
InferArgumentsInBinaryOperator(expr, null);
return null;
case Code.Brtrue:
case Code.Brfalse:
case ILCode.Brtrue:
case ILCode.Brfalse:
if (forceInferChildren)
InferTypeForExpression(expr.Arguments.Single(), typeSystem.Boolean);
return null;
case Code.Blt:
case Code.Ble:
case Code.Bgt:
case Code.Bge:
case ILCode.Blt:
case ILCode.Ble:
case ILCode.Bgt:
case ILCode.Bge:
if (forceInferChildren)
InferArgumentsInBinaryOperator(expr, true);
return null;
case Code.Blt_Un:
case Code.Ble_Un:
case Code.Bgt_Un:
case Code.Bge_Un:
case ILCode.Blt_Un:
case ILCode.Ble_Un:
case ILCode.Bgt_Un:
case ILCode.Bge_Un:
if (forceInferChildren)
InferArgumentsInBinaryOperator(expr, false);
return null;
case Code.Br:
case Code.Leave:
case Code.Endfinally:
case Code.Switch:
case Code.Throw:
case Code.Rethrow:
case ILCode.Br:
case ILCode.Leave:
case ILCode.Endfinally:
case ILCode.Switch:
case ILCode.Throw:
case ILCode.Rethrow:
return null;
case Code.Ret:
case ILCode.Ret:
if (forceInferChildren && expr.Arguments.Count == 1)
InferTypeForExpression(expr.Arguments[0], context.CurrentMethod.ReturnType);
return null;
#endregion
case Code.Pop:
case ILCode.Pop:
return null;
case Code.Dup:
case ILCode.Dup:
return InferTypeForExpression(expr.Arguments.Single(), expectedType);
default:
Debug.WriteLine("Type Inference: Can't handle " + expr.Code.GetName());
@ -568,22 +568,17 @@ namespace Decompiler @@ -568,22 +568,17 @@ namespace Decompiler
TypeReference TypeWithMoreInformation(TypeReference leftPreferred, TypeReference rightPreferred)
{
int left = GetInformationAmount(typeSystem, leftPreferred);
int right = GetInformationAmount(typeSystem, rightPreferred);
int left = GetInformationAmount(leftPreferred);
int right = GetInformationAmount(rightPreferred);
if (left < right)
return rightPreferred;
else
return leftPreferred;
}
int GetInformationAmount(TypeReference type)
{
return GetInformationAmount(typeSystem, type);
}
const int nativeInt = 33; // treat native int as between int32 and int64
static int GetInformationAmount(TypeSystem typeSystem, TypeReference type)
static int GetInformationAmount(TypeReference type)
{
if (type == null)
return 0;
@ -592,40 +587,48 @@ namespace Decompiler @@ -592,40 +587,48 @@ namespace Decompiler
TypeDefinition typeDef = type.Resolve() as TypeDefinition;
if (typeDef != null && typeDef.IsEnum) {
TypeReference underlyingType = typeDef.Fields.Single(f => f.IsRuntimeSpecialName && !f.IsStatic).FieldType;
return GetInformationAmount(typeDef.Module.TypeSystem, underlyingType);
return GetInformationAmount(underlyingType);
}
}
if (type == typeSystem.Boolean)
return 1;
else if (type == typeSystem.Byte || type == typeSystem.SByte)
return 8;
else if (type == typeSystem.Int16 || type == typeSystem.UInt16)
return 16;
else if (type == typeSystem.Int32 || type == typeSystem.UInt32)
return 32;
else if (type == typeSystem.IntPtr || type == typeSystem.UIntPtr)
return nativeInt;
else if (type == typeSystem.Int64 || type == typeSystem.UInt64)
return 64;
return 100; // we consider structs/objects to have more information than any primitives
}
bool IsIntegerOrEnum(TypeReference type)
{
return IsIntegerOrEnum(typeSystem, type);
switch (type.MetadataType) {
case MetadataType.Void:
return 0;
case MetadataType.Boolean:
return 1;
case MetadataType.SByte:
case MetadataType.Byte:
return 8;
case MetadataType.Char:
case MetadataType.Int16:
case MetadataType.UInt16:
return 16;
case MetadataType.Int32:
case MetadataType.UInt32:
case MetadataType.Single:
return 32;
case MetadataType.Int64:
case MetadataType.UInt64:
case MetadataType.Double:
return 64;
case MetadataType.IntPtr:
case MetadataType.UIntPtr:
return nativeInt;
default:
return 100; // we consider structs/objects to have more information than any primitives
}
}
public static bool IsIntegerOrEnum(TypeSystem typeSystem, TypeReference type)
public static bool IsBoolean(TypeReference type)
{
return IsSigned(typeSystem, type) != null;
return type != null && type.MetadataType == MetadataType.Boolean;
}
bool? IsSigned(TypeReference type)
public static bool IsIntegerOrEnum(TypeReference type)
{
return IsSigned(typeSystem, type);
return IsSigned(type) != null;
}
static bool? IsSigned(TypeSystem typeSystem, TypeReference type)
static bool? IsSigned(TypeReference type)
{
if (type == null)
return null;
@ -633,47 +636,60 @@ namespace Decompiler @@ -633,47 +636,60 @@ namespace Decompiler
TypeDefinition typeDef = type.Resolve() as TypeDefinition;
if (typeDef != null && typeDef.IsEnum) {
TypeReference underlyingType = typeDef.Fields.Single(f => f.IsRuntimeSpecialName && !f.IsStatic).FieldType;
return IsSigned(typeDef.Module.TypeSystem, underlyingType);
return IsSigned(underlyingType);
}
switch (type.MetadataType) {
case MetadataType.SByte:
case MetadataType.Int16:
case MetadataType.Int32:
case MetadataType.Int64:
case MetadataType.IntPtr:
return true;
case MetadataType.Byte:
case MetadataType.UInt16:
case MetadataType.UInt32:
case MetadataType.UInt64:
case MetadataType.UIntPtr:
return false;
default:
return null;
}
if (type == typeSystem.Byte || type == typeSystem.UInt16 || type == typeSystem.UInt32 || type == typeSystem.UInt64 || type == typeSystem.UIntPtr)
return false;
if (type == typeSystem.SByte || type == typeSystem.Int16 || type == typeSystem.Int32 || type == typeSystem.Int64 || type == typeSystem.IntPtr)
return true;
return null;
}
public static TypeCode GetTypeCode(TypeSystem typeSystem, TypeReference type)
public static TypeCode GetTypeCode(TypeReference type)
{
if (type == typeSystem.Boolean)
return TypeCode.Boolean;
else if (type == typeSystem.Byte)
return TypeCode.Byte;
else if (type == typeSystem.Char)
return TypeCode.Char;
else if (type == typeSystem.Double)
return TypeCode.Double;
else if (type == typeSystem.Int16)
return TypeCode.Int16;
else if (type == typeSystem.Int32)
return TypeCode.Int32;
else if (type == typeSystem.Int64)
return TypeCode.Int64;
else if (type == typeSystem.Single)
return TypeCode.Single;
else if (type == typeSystem.Double)
return TypeCode.Double;
else if (type == typeSystem.SByte)
return TypeCode.SByte;
else if (type == typeSystem.UInt16)
return TypeCode.UInt16;
else if (type == typeSystem.UInt32)
return TypeCode.UInt32;
else if (type == typeSystem.UInt64)
return TypeCode.UInt64;
else if (type == typeSystem.String)
return TypeCode.String;
else
return TypeCode.Object;
if (type == null)
return TypeCode.Empty;
switch (type.MetadataType) {
case MetadataType.Boolean:
return TypeCode.Boolean;
case MetadataType.Char:
return TypeCode.Char;
case MetadataType.SByte:
return TypeCode.SByte;
case MetadataType.Byte:
return TypeCode.Byte;
case MetadataType.Int16:
return TypeCode.Int16;
case MetadataType.UInt16:
return TypeCode.UInt16;
case MetadataType.Int32:
return TypeCode.Int32;
case MetadataType.UInt32:
return TypeCode.UInt32;
case MetadataType.Int64:
return TypeCode.Int64;
case MetadataType.UInt64:
return TypeCode.UInt64;
case MetadataType.Single:
return TypeCode.Single;
case MetadataType.Double:
return TypeCode.Double;
case MetadataType.String:
return TypeCode.String;
default:
return TypeCode.Object;
}
}
}
}

1
ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj

@ -50,6 +50,7 @@ @@ -50,6 +50,7 @@
<ItemGroup>
<Compile Include="DelegateConstruction.cs" />
<Compile Include="Loops.cs" />
<Compile Include="PropertiesAndEvents.cs" />
<Compile Include="TestRunner.cs" />
</ItemGroup>
<ItemGroup>

50
ICSharpCode.Decompiler/Tests/PropertiesAndEvents.cs

@ -0,0 +1,50 @@ @@ -0,0 +1,50 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
using System;
using System.Text;
public class PropertiesAndEvents
{
public int Getter(StringBuilder b)
{
return b.Length;
}
public void Setter(StringBuilder b)
{
b.Capacity = 100;
}
public char IndexerGetter(StringBuilder b)
{
return b[50];
}
public void IndexerSetter(StringBuilder b)
{
b[42] = 'b';
}
public int AutomaticProperty { get; set; }
public int CustomProperty {
get {
return this.AutomaticProperty;
}
set {
this.AutomaticProperty = value;
}
}
public event EventHandler AutomaticEvent;
public event EventHandler CustomEvent {
add {
this.AutomaticEvent += value;
}
remove {
this.AutomaticEvent -= value;
}
}
}

6
Mono.Cecil/Mono.Cecil/AssemblyDefinition.cs

@ -62,7 +62,7 @@ namespace Mono.Cecil { @@ -62,7 +62,7 @@ namespace Mono.Cecil {
return modules;
if (main_module.HasImage)
return modules = main_module.Read (this, (_, reader) => reader.ReadModules ());
return main_module.Read (ref modules, this, (_, reader) => reader.ReadModules ());
return modules = new Collection<ModuleDefinition> { main_module };
}
@ -87,7 +87,7 @@ namespace Mono.Cecil { @@ -87,7 +87,7 @@ namespace Mono.Cecil {
}
public Collection<CustomAttribute> CustomAttributes {
get { return custom_attributes ?? (custom_attributes = this.GetCustomAttributes (main_module)); }
get { return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, main_module)); }
}
public bool HasSecurityDeclarations {
@ -100,7 +100,7 @@ namespace Mono.Cecil { @@ -100,7 +100,7 @@ namespace Mono.Cecil {
}
public Collection<SecurityDeclaration> SecurityDeclarations {
get { return security_declarations ?? (security_declarations = this.GetSecurityDeclarations (main_module)); }
get { return security_declarations ?? (this.GetSecurityDeclarations (ref security_declarations, main_module)); }
}
internal AssemblyDefinition ()

7
Mono.Cecil/Mono.Cecil/AssemblyNameReference.cs

@ -107,9 +107,10 @@ namespace Mono.Cecil { @@ -107,9 +107,10 @@ namespace Mono.Cecil {
if (public_key_token.IsNullOrEmpty () && !public_key.IsNullOrEmpty ()) {
var hash = HashPublicKey ();
// we need the last 8 bytes in reverse order
public_key_token = new byte [8];
Array.Copy (hash, (hash.Length - 8), public_key_token, 0, 8);
Array.Reverse (public_key_token, 0, 8);
byte[] local_public_key_token = new byte [8];
Array.Copy (hash, (hash.Length - 8), local_public_key_token, 0, 8);
Array.Reverse (local_public_key_token, 0, 8);
public_key_token = local_public_key_token; // publish only once finished (required for thread-safety)
}
return public_key_token;
}

3
Mono.Cecil/Mono.Cecil/AssemblyReader.cs

@ -1558,10 +1558,11 @@ namespace Mono.Cecil { @@ -1558,10 +1558,11 @@ namespace Mono.Cecil {
var methods = type.Methods;
for (int i = 0; i < methods.Count; i++) {
var method = methods [i];
if (method.sem_attrs.HasValue)
if (method.sem_attrs_ready)
continue;
method.sem_attrs = ReadMethodSemantics (method);
method.sem_attrs_ready = true;
}
}

33
Mono.Cecil/Mono.Cecil/CustomAttribute.cs

@ -191,7 +191,7 @@ namespace Mono.Cecil { @@ -191,7 +191,7 @@ namespace Mono.Cecil {
if (!HasImage || signature == 0)
throw new NotSupportedException ();
return blob = Module.Read (this, (attribute, reader) => reader.ReadCustomAttributeBlob (attribute.signature));
return Module.Read (ref blob, this, (attribute, reader) => reader.ReadCustomAttributeBlob (attribute.signature));
}
void Resolve ()
@ -199,23 +199,22 @@ namespace Mono.Cecil { @@ -199,23 +199,22 @@ namespace Mono.Cecil {
if (resolved || !HasImage)
return;
try {
Module.Read (this, (attribute, reader) => {
Module.Read (this, (attribute, reader) => {
try {
reader.ReadCustomAttributeSignature (attribute);
return this;
});
resolved = true;
} catch (ResolutionException) {
if (arguments != null)
arguments.Clear ();
if (fields != null)
fields.Clear ();
if (properties != null)
properties.Clear ();
resolved = false;
}
resolved = true;
} catch (ResolutionException) {
if (arguments != null)
arguments.Clear ();
if (fields != null)
fields.Clear ();
if (properties != null)
properties.Clear ();
resolved = false;
}
return this;
});
}
}

20
Mono.Cecil/Mono.Cecil/EventDefinition.cs

@ -113,7 +113,7 @@ namespace Mono.Cecil { @@ -113,7 +113,7 @@ namespace Mono.Cecil {
}
public Collection<CustomAttribute> CustomAttributes {
get { return custom_attributes ?? (custom_attributes = this.GetCustomAttributes (Module)); }
get { return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, Module)); }
}
#region EventAttributes
@ -148,16 +148,18 @@ namespace Mono.Cecil { @@ -148,16 +148,18 @@ namespace Mono.Cecil {
void InitializeMethods ()
{
if (add_method != null
|| invoke_method != null
|| remove_method != null)
return;
var module = this.Module;
if (!module.HasImage ())
return;
lock (module.SyncRoot) {
if (add_method != null
|| invoke_method != null
|| remove_method != null)
return;
if (!module.HasImage ())
return;
module.Read (this, (@event, reader) => reader.ReadMethods (@event));
module.Read (this, (@event, reader) => reader.ReadMethods (@event));
}
}
public override EventDefinition Resolve ()

14
Mono.Cecil/Mono.Cecil/FieldDefinition.cs

@ -124,7 +124,7 @@ namespace Mono.Cecil { @@ -124,7 +124,7 @@ namespace Mono.Cecil {
public bool HasConstant {
get {
ResolveConstant ();
this.ResolveConstant (ref constant, Module);
return constant != Mixin.NoValue;
}
@ -136,14 +136,6 @@ namespace Mono.Cecil { @@ -136,14 +136,6 @@ namespace Mono.Cecil {
set { constant = value; }
}
void ResolveConstant ()
{
if (constant != Mixin.NotResolved)
return;
this.ResolveConstant (ref constant, Module);
}
public bool HasCustomAttributes {
get {
if (custom_attributes != null)
@ -154,7 +146,7 @@ namespace Mono.Cecil { @@ -154,7 +146,7 @@ namespace Mono.Cecil {
}
public Collection<CustomAttribute> CustomAttributes {
get { return custom_attributes ?? (custom_attributes = this.GetCustomAttributes (Module)); }
get { return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, Module)); }
}
public bool HasMarshalInfo {
@ -167,7 +159,7 @@ namespace Mono.Cecil { @@ -167,7 +159,7 @@ namespace Mono.Cecil {
}
public MarshalInfo MarshalInfo {
get { return marshal_info ?? (marshal_info = this.GetMarshalInfo (Module)); }
get { return marshal_info ?? (this.GetMarshalInfo (ref marshal_info, Module)); }
set { marshal_info = value; }
}

4
Mono.Cecil/Mono.Cecil/GenericParameter.cs

@ -78,7 +78,7 @@ namespace Mono.Cecil { @@ -78,7 +78,7 @@ namespace Mono.Cecil {
return constraints;
if (HasImage)
return constraints = Module.Read (this, (generic_parameter, reader) => reader.ReadGenericConstraints (generic_parameter));
return Module.Read (ref constraints, this, (generic_parameter, reader) => reader.ReadGenericConstraints (generic_parameter));
return constraints = new Collection<TypeReference> ();
}
@ -94,7 +94,7 @@ namespace Mono.Cecil { @@ -94,7 +94,7 @@ namespace Mono.Cecil {
}
public Collection<CustomAttribute> CustomAttributes {
get { return custom_attributes ?? (custom_attributes = this.GetCustomAttributes (Module)); }
get { return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, Module)); }
}
internal new bool HasImage {

11
Mono.Cecil/Mono.Cecil/IConstantProvider.cs

@ -44,9 +44,14 @@ namespace Mono.Cecil { @@ -44,9 +44,14 @@ namespace Mono.Cecil {
ref object constant,
ModuleDefinition module)
{
constant = module.HasImage ()
? module.Read (self, (provider, reader) => reader.ReadConstant (provider))
: Mixin.NoValue;
lock (module.SyncRoot) {
if (constant != Mixin.NotResolved)
return;
if (module.HasImage ())
constant = module.Read (self, (provider, reader) => reader.ReadConstant (provider));
else
constant = Mixin.NoValue;
}
}
}
}

6
Mono.Cecil/Mono.Cecil/ICustomAttributeProvider.cs

@ -27,7 +27,6 @@ @@ -27,7 +27,6 @@
//
using System;
using Mono.Collections.Generic;
namespace Mono.Cecil {
@ -52,11 +51,12 @@ namespace Mono.Cecil { @@ -52,11 +51,12 @@ namespace Mono.Cecil {
public static Collection<CustomAttribute> GetCustomAttributes (
this ICustomAttributeProvider self,
ref Collection<CustomAttribute> variable,
ModuleDefinition module)
{
return module.HasImage ()
? module.Read (self, (provider, reader) => reader.ReadCustomAttributes (provider))
: new Collection<CustomAttribute> ();
? module.Read (ref variable, self, (provider, reader) => reader.ReadCustomAttributes (provider))
: variable = new Collection<CustomAttribute>();
}
}
}

5
Mono.Cecil/Mono.Cecil/IGenericParameterProvider.cs

@ -65,11 +65,12 @@ namespace Mono.Cecil { @@ -65,11 +65,12 @@ namespace Mono.Cecil {
public static Collection<GenericParameter> GetGenericParameters (
this IGenericParameterProvider self,
ref Collection<GenericParameter> collection,
ModuleDefinition module)
{
return module.HasImage ()
? module.Read (self, (provider, reader) => reader.ReadGenericParameters (provider))
: new Collection<GenericParameter> ();
? module.Read (ref collection, self, (provider, reader) => reader.ReadGenericParameters (provider))
: collection = new Collection<GenericParameter> ();
}
}
}

3
Mono.Cecil/Mono.Cecil/IMarshalInfoProvider.cs

@ -47,10 +47,11 @@ namespace Mono.Cecil { @@ -47,10 +47,11 @@ namespace Mono.Cecil {
public static MarshalInfo GetMarshalInfo (
this IMarshalInfoProvider self,
ref MarshalInfo variable,
ModuleDefinition module)
{
return module.HasImage ()
? module.Read (self, (provider, reader) => reader.ReadMarshalInfo (provider))
? module.Read (ref variable, self, (provider, reader) => reader.ReadMarshalInfo (provider))
: null;
}
}

26
Mono.Cecil/Mono.Cecil/MethodDefinition.cs

@ -37,7 +37,8 @@ namespace Mono.Cecil { @@ -37,7 +37,8 @@ namespace Mono.Cecil {
ushort attributes;
ushort impl_attributes;
internal MethodSemanticsAttributes? sem_attrs;
internal volatile bool sem_attrs_ready;
internal MethodSemanticsAttributes sem_attrs;
Collection<CustomAttribute> custom_attributes;
Collection<SecurityDeclaration> security_declarations;
@ -59,23 +60,24 @@ namespace Mono.Cecil { @@ -59,23 +60,24 @@ namespace Mono.Cecil {
public MethodSemanticsAttributes SemanticsAttributes {
get {
if (sem_attrs.HasValue)
return sem_attrs.Value;
if (sem_attrs_ready)
return sem_attrs;
if (HasImage) {
ReadSemantics ();
return sem_attrs.Value;
return sem_attrs;
}
sem_attrs = MethodSemanticsAttributes.None;
return sem_attrs.Value;
sem_attrs_ready = true;
return sem_attrs;
}
set { sem_attrs = value; }
}
internal void ReadSemantics ()
{
if (sem_attrs.HasValue)
if (sem_attrs_ready)
return;
var module = this.Module;
@ -98,7 +100,7 @@ namespace Mono.Cecil { @@ -98,7 +100,7 @@ namespace Mono.Cecil {
}
public Collection<SecurityDeclaration> SecurityDeclarations {
get { return security_declarations ?? (security_declarations = this.GetSecurityDeclarations (Module)); }
get { return security_declarations ?? (this.GetSecurityDeclarations (ref security_declarations, Module)); }
}
public bool HasCustomAttributes {
@ -111,7 +113,7 @@ namespace Mono.Cecil { @@ -111,7 +113,7 @@ namespace Mono.Cecil {
}
public Collection<CustomAttribute> CustomAttributes {
get { return custom_attributes ?? (custom_attributes = this.GetCustomAttributes (Module)); }
get { return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, Module)); }
}
public int RVA {
@ -138,7 +140,7 @@ namespace Mono.Cecil { @@ -138,7 +140,7 @@ namespace Mono.Cecil {
return null;
if (HasImage && rva != 0)
return body = Module.Read (this, (method, reader) => reader.ReadMethodBody (method));
return Module.Read (ref body, this, (method, reader) => reader.ReadMethodBody (method));
return body = new MethodBody (this);
}
@ -160,7 +162,7 @@ namespace Mono.Cecil { @@ -160,7 +162,7 @@ namespace Mono.Cecil {
return pinvoke;
if (HasImage && IsPInvokeImpl)
return pinvoke = Module.Read (this, (method, reader) => reader.ReadPInvokeInfo (method));
return Module.Read (ref pinvoke, this, (method, reader) => reader.ReadPInvokeInfo (method));
return null;
}
@ -188,7 +190,7 @@ namespace Mono.Cecil { @@ -188,7 +190,7 @@ namespace Mono.Cecil {
return overrides;
if (HasImage)
return overrides = Module.Read (this, (method, reader) => reader.ReadOverrides (method));
return Module.Read (ref overrides, this, (method, reader) => reader.ReadOverrides (method));
return overrides = new Collection<MethodReference> ();
}
@ -204,7 +206,7 @@ namespace Mono.Cecil { @@ -204,7 +206,7 @@ namespace Mono.Cecil {
}
public override Collection<GenericParameter> GenericParameters {
get { return generic_parameters ?? (generic_parameters = this.GetGenericParameters (Module)); }
get { return generic_parameters ?? (this.GetGenericParameters (ref generic_parameters, Module)); }
}
#region MethodAttributes

50
Mono.Cecil/Mono.Cecil/ModuleDefinition.cs

@ -29,8 +29,8 @@ @@ -29,8 +29,8 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using SR = System.Reflection;
using Mono.Cecil.Cil;
using Mono.Cecil.Metadata;
using Mono.Cecil.PE;
@ -261,7 +261,11 @@ namespace Mono.Cecil { @@ -261,7 +261,11 @@ namespace Mono.Cecil {
#if !READ_ONLY
internal MetadataImporter MetadataImporter {
get { return importer ?? (importer = new MetadataImporter (this)); }
get {
if (importer == null)
Interlocked.CompareExchange(ref importer, new MetadataImporter(this), null);
return importer;
}
}
#endif
@ -270,7 +274,11 @@ namespace Mono.Cecil { @@ -270,7 +274,11 @@ namespace Mono.Cecil {
}
public TypeSystem TypeSystem {
get { return type_system ?? (type_system = TypeSystem.CreateTypeSystem (this)); }
get {
if (type_system == null)
Interlocked.CompareExchange(ref type_system, TypeSystem.CreateTypeSystem (this), null);
return type_system;
}
}
public bool HasAssemblyReferences {
@ -288,7 +296,7 @@ namespace Mono.Cecil { @@ -288,7 +296,7 @@ namespace Mono.Cecil {
return references;
if (HasImage)
return references = Read (this, (_, reader) => reader.ReadAssemblyReferences ());
return Read (ref references, this, (_, reader) => reader.ReadAssemblyReferences ());
return references = new Collection<AssemblyNameReference> ();
}
@ -309,7 +317,7 @@ namespace Mono.Cecil { @@ -309,7 +317,7 @@ namespace Mono.Cecil {
return modules;
if (HasImage)
return modules = Read (this, (_, reader) => reader.ReadModuleReferences ());
return Read (ref modules, this, (_, reader) => reader.ReadModuleReferences ());
return modules = new Collection<ModuleReference> ();
}
@ -333,7 +341,7 @@ namespace Mono.Cecil { @@ -333,7 +341,7 @@ namespace Mono.Cecil {
return resources;
if (HasImage)
return resources = Read (this, (_, reader) => reader.ReadResources ());
return Read (ref resources, this, (_, reader) => reader.ReadResources ());
return resources = new Collection<Resource> ();
}
@ -349,7 +357,7 @@ namespace Mono.Cecil { @@ -349,7 +357,7 @@ namespace Mono.Cecil {
}
public Collection<CustomAttribute> CustomAttributes {
get { return custom_attributes ?? (custom_attributes = this.GetCustomAttributes (this)); }
get { return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, this)); }
}
public bool HasTypes {
@ -367,7 +375,7 @@ namespace Mono.Cecil { @@ -367,7 +375,7 @@ namespace Mono.Cecil {
return types;
if (HasImage)
return types = Read (this, (_, reader) => reader.ReadTypes ());
return Read (ref types, this, (_, reader) => reader.ReadTypes ());
return types = new TypeDefinitionCollection (this);
}
@ -388,7 +396,7 @@ namespace Mono.Cecil { @@ -388,7 +396,7 @@ namespace Mono.Cecil {
return exported_types;
if (HasImage)
return exported_types = Read (this, (_, reader) => reader.ReadExportedTypes ());
return Read (ref exported_types, this, (_, reader) => reader.ReadExportedTypes ());
return exported_types = new Collection<ExportedType> ();
}
@ -400,7 +408,7 @@ namespace Mono.Cecil { @@ -400,7 +408,7 @@ namespace Mono.Cecil {
return entry_point;
if (HasImage)
return entry_point = Read (this, (_, reader) => reader.ReadEntryPoint ());
return Read (ref entry_point, this, (_, reader) => reader.ReadEntryPoint ());
return entry_point = null;
}
@ -760,6 +768,10 @@ namespace Mono.Cecil { @@ -760,6 +768,10 @@ namespace Mono.Cecil {
readonly object module_lock = new object();
internal object SyncRoot {
get { return module_lock; }
}
internal TRet Read<TItem, TRet> (TItem item, Func<TItem, MetadataReader, TRet> read)
{
lock (module_lock) {
@ -774,6 +786,24 @@ namespace Mono.Cecil { @@ -774,6 +786,24 @@ namespace Mono.Cecil {
return ret;
}
}
internal TRet Read<TItem, TRet> (ref TRet variable, TItem item, Func<TItem, MetadataReader, TRet> read) where TRet : class
{
lock (module_lock) {
if (variable != null)
return variable;
var position = reader.position;
var context = reader.context;
var ret = read (item, reader);
reader.position = position;
reader.context = context;
return variable = ret;
}
}
void ProcessDebugHeader ()
{

14
Mono.Cecil/Mono.Cecil/ParameterDefinition.cs

@ -51,7 +51,7 @@ namespace Mono.Cecil { @@ -51,7 +51,7 @@ namespace Mono.Cecil {
public bool HasConstant {
get {
ResolveConstant ();
this.ResolveConstant (ref constant, parameter_type.Module);
return constant != Mixin.NoValue;
}
@ -63,14 +63,6 @@ namespace Mono.Cecil { @@ -63,14 +63,6 @@ namespace Mono.Cecil {
set { constant = value; }
}
void ResolveConstant ()
{
if (constant != Mixin.NotResolved)
return;
this.ResolveConstant (ref constant, parameter_type.Module);
}
public bool HasCustomAttributes {
get {
if (custom_attributes != null)
@ -81,7 +73,7 @@ namespace Mono.Cecil { @@ -81,7 +73,7 @@ namespace Mono.Cecil {
}
public Collection<CustomAttribute> CustomAttributes {
get { return custom_attributes ?? (custom_attributes = this.GetCustomAttributes (parameter_type.Module)); }
get { return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, parameter_type.Module)); }
}
public bool HasMarshalInfo {
@ -94,7 +86,7 @@ namespace Mono.Cecil { @@ -94,7 +86,7 @@ namespace Mono.Cecil {
}
public MarshalInfo MarshalInfo {
get { return marshal_info ?? (marshal_info = this.GetMarshalInfo (parameter_type.Module)); }
get { return marshal_info ?? (this.GetMarshalInfo (ref marshal_info, parameter_type.Module)); }
set { marshal_info = value; }
}

26
Mono.Cecil/Mono.Cecil/PropertyDefinition.cs

@ -76,7 +76,7 @@ namespace Mono.Cecil { @@ -76,7 +76,7 @@ namespace Mono.Cecil {
}
public Collection<CustomAttribute> CustomAttributes {
get { return custom_attributes ?? (custom_attributes = this.GetCustomAttributes (Module)); }
get { return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, Module)); }
}
public MethodDefinition GetMethod {
@ -168,7 +168,7 @@ namespace Mono.Cecil { @@ -168,7 +168,7 @@ namespace Mono.Cecil {
public bool HasConstant {
get {
ResolveConstant ();
this.ResolveConstant (ref constant, Module);
return constant != Mixin.NoValue;
}
@ -180,14 +180,6 @@ namespace Mono.Cecil { @@ -180,14 +180,6 @@ namespace Mono.Cecil {
set { constant = value; }
}
void ResolveConstant ()
{
if (constant != Mixin.NotResolved)
return;
this.ResolveConstant (ref constant, Module);
}
#region PropertyAttributes
public bool IsSpecialName {
@ -245,14 +237,16 @@ namespace Mono.Cecil { @@ -245,14 +237,16 @@ namespace Mono.Cecil {
void InitializeMethods ()
{
if (get_method != null || set_method != null)
return;
var module = this.Module;
if (!module.HasImage ())
return;
lock (module.SyncRoot) {
if (get_method != null || set_method != null)
return;
if (!module.HasImage ())
return;
module.Read (this, (property, reader) => reader.ReadMethods (property));
module.Read (this, (property, reader) => reader.ReadMethods (property));
}
}
public override PropertyDefinition Resolve ()

7
Mono.Cecil/Mono.Cecil/SecurityDeclaration.cs

@ -27,7 +27,7 @@ @@ -27,7 +27,7 @@
//
using System;
using System.Threading;
using Mono.Collections.Generic;
namespace Mono.Cecil {
@ -172,11 +172,12 @@ namespace Mono.Cecil { @@ -172,11 +172,12 @@ namespace Mono.Cecil {
public static Collection<SecurityDeclaration> GetSecurityDeclarations (
this ISecurityDeclarationProvider self,
ref Collection<SecurityDeclaration> variable,
ModuleDefinition module)
{
return module.HasImage ()
? module.Read (self, (provider, reader) => reader.ReadSecurityDeclarations (provider))
: new Collection<SecurityDeclaration> ();
? module.Read (ref variable, self, (provider, reader) => reader.ReadSecurityDeclarations (provider))
: LazyInitializer.EnsureInitialized(ref variable);
}
}
}

18
Mono.Cecil/Mono.Cecil/TypeDefinition.cs

@ -131,7 +131,7 @@ namespace Mono.Cecil { @@ -131,7 +131,7 @@ namespace Mono.Cecil {
return interfaces;
if (HasImage)
return interfaces = Module.Read (this, (type, reader) => reader.ReadInterfaces (type));
return Module.Read (ref interfaces, this, (type, reader) => reader.ReadInterfaces (type));
return interfaces = new Collection<TypeReference> ();
}
@ -155,7 +155,7 @@ namespace Mono.Cecil { @@ -155,7 +155,7 @@ namespace Mono.Cecil {
return nested_types;
if (HasImage)
return nested_types = Module.Read (this, (type, reader) => reader.ReadNestedTypes (type));
return Module.Read (ref nested_types, this, (type, reader) => reader.ReadNestedTypes (type));
return nested_types = new MemberDefinitionCollection<TypeDefinition> (this);
}
@ -183,7 +183,7 @@ namespace Mono.Cecil { @@ -183,7 +183,7 @@ namespace Mono.Cecil {
return methods;
if (HasImage)
return methods = Module.Read (this, (type, reader) => reader.ReadMethods (type));
return Module.Read (ref methods, this, (type, reader) => reader.ReadMethods (type));
return methods = new MemberDefinitionCollection<MethodDefinition> (this);
}
@ -207,7 +207,7 @@ namespace Mono.Cecil { @@ -207,7 +207,7 @@ namespace Mono.Cecil {
return fields;
if (HasImage)
return fields = Module.Read (this, (type, reader) => reader.ReadFields (type));
return Module.Read (ref fields, this, (type, reader) => reader.ReadFields (type));
return fields = new MemberDefinitionCollection<FieldDefinition> (this);
}
@ -231,7 +231,7 @@ namespace Mono.Cecil { @@ -231,7 +231,7 @@ namespace Mono.Cecil {
return events;
if (HasImage)
return events = Module.Read (this, (type, reader) => reader.ReadEvents (type));
return Module.Read (ref events, this, (type, reader) => reader.ReadEvents (type));
return events = new MemberDefinitionCollection<EventDefinition> (this);
}
@ -255,7 +255,7 @@ namespace Mono.Cecil { @@ -255,7 +255,7 @@ namespace Mono.Cecil {
return properties;
if (HasImage)
return properties = Module.Read (this, (type, reader) => reader.ReadProperties (type));
return Module.Read (ref properties, this, (type, reader) => reader.ReadProperties (type));
return properties = new MemberDefinitionCollection<PropertyDefinition> (this);
}
@ -271,7 +271,7 @@ namespace Mono.Cecil { @@ -271,7 +271,7 @@ namespace Mono.Cecil {
}
public Collection<SecurityDeclaration> SecurityDeclarations {
get { return security_declarations ?? (security_declarations = this.GetSecurityDeclarations (Module)); }
get { return security_declarations ?? (this.GetSecurityDeclarations (ref security_declarations, Module)); }
}
public bool HasCustomAttributes {
@ -284,7 +284,7 @@ namespace Mono.Cecil { @@ -284,7 +284,7 @@ namespace Mono.Cecil {
}
public Collection<CustomAttribute> CustomAttributes {
get { return custom_attributes ?? (custom_attributes = this.GetCustomAttributes (Module)); }
get { return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, Module)); }
}
public override bool HasGenericParameters {
@ -297,7 +297,7 @@ namespace Mono.Cecil { @@ -297,7 +297,7 @@ namespace Mono.Cecil {
}
public override Collection<GenericParameter> GenericParameters {
get { return generic_parameters ?? (generic_parameters = this.GetGenericParameters (Module)); }
get { return generic_parameters ?? (this.GetGenericParameters (ref generic_parameters, Module)); }
}
#region TypeAttributes

61
Mono.Cecil/Mono.Cecil/TypeSystem.cs

@ -174,18 +174,27 @@ namespace Mono.Cecil { @@ -174,18 +174,27 @@ namespace Mono.Cecil {
internal abstract TypeReference LookupType (string @namespace, string name);
TypeReference LookupSystemType (string name, ElementType element_type)
TypeReference LookupSystemType (ref TypeReference typeRef, string name, ElementType element_type)
{
var type = LookupType ("System", name);
type.etype = element_type;
return type;
lock (module.SyncRoot) {
if (typeRef != null)
return typeRef;
var type = LookupType ("System", name);
type.etype = element_type;
return typeRef = type;
}
}
TypeReference LookupSystemValueType (string name, ElementType element_type)
TypeReference LookupSystemValueType (ref TypeReference typeRef, string name, ElementType element_type)
{
var type = LookupSystemType (name, element_type);
type.IsValueType = true;
return type;
lock (module.SyncRoot) {
if (typeRef != null)
return typeRef;
var type = LookupType ("System", name);
type.etype = element_type;
type.IsValueType = true;
return typeRef = type;
}
}
public IMetadataScope Corlib {
@ -199,75 +208,75 @@ namespace Mono.Cecil { @@ -199,75 +208,75 @@ namespace Mono.Cecil {
}
public TypeReference Object {
get { return type_object ?? (type_object = LookupSystemType ("Object", ElementType.Object)); }
get { return type_object ?? (LookupSystemType (ref type_object, "Object", ElementType.Object)); }
}
public TypeReference Void {
get { return type_void ?? (type_void = LookupSystemType ("Void", ElementType.Void)); }
get { return type_void ?? (LookupSystemType (ref type_void, "Void", ElementType.Void)); }
}
public TypeReference Boolean {
get { return type_bool ?? (type_bool = LookupSystemValueType ("Boolean", ElementType.Boolean)); }
get { return type_bool ?? (LookupSystemValueType (ref type_bool, "Boolean", ElementType.Boolean)); }
}
public TypeReference Char {
get { return type_char ?? (type_char = LookupSystemValueType ("Char", ElementType.Char)); }
get { return type_char ?? (LookupSystemValueType (ref type_char, "Char", ElementType.Char)); }
}
public TypeReference SByte {
get { return type_sbyte ?? (type_sbyte = LookupSystemValueType ("SByte", ElementType.I1)); }
get { return type_sbyte ?? (LookupSystemValueType (ref type_sbyte, "SByte", ElementType.I1)); }
}
public TypeReference Byte {
get { return type_byte ?? (type_byte = LookupSystemValueType ("Byte", ElementType.U1)); }
get { return type_byte ?? (LookupSystemValueType (ref type_byte, "Byte", ElementType.U1)); }
}
public TypeReference Int16 {
get { return type_int16 ?? (type_int16 = LookupSystemValueType ("Int16", ElementType.I2)); }
get { return type_int16 ?? (LookupSystemValueType (ref type_int16, "Int16", ElementType.I2)); }
}
public TypeReference UInt16 {
get { return type_uint16 ?? (type_uint16 = LookupSystemValueType ("UInt16", ElementType.U2)); }
get { return type_uint16 ?? (LookupSystemValueType (ref type_uint16, "UInt16", ElementType.U2)); }
}
public TypeReference Int32 {
get { return type_int32 ?? (type_int32 = LookupSystemValueType ("Int32", ElementType.I4)); }
get { return type_int32 ?? (LookupSystemValueType (ref type_int32, "Int32", ElementType.I4)); }
}
public TypeReference UInt32 {
get { return type_uint32 ?? (type_uint32 = LookupSystemValueType ("UInt32", ElementType.U4)); }
get { return type_uint32 ?? (LookupSystemValueType (ref type_uint32, "UInt32", ElementType.U4)); }
}
public TypeReference Int64 {
get { return type_int64 ?? (type_int64 = LookupSystemValueType ("Int64", ElementType.I8)); }
get { return type_int64 ?? (LookupSystemValueType (ref type_int64, "Int64", ElementType.I8)); }
}
public TypeReference UInt64 {
get { return type_uint64 ?? (type_uint64 = LookupSystemValueType ("UInt64", ElementType.U8)); }
get { return type_uint64 ?? (LookupSystemValueType (ref type_uint64, "UInt64", ElementType.U8)); }
}
public TypeReference Single {
get { return type_single ?? (type_single = LookupSystemValueType ("Single", ElementType.R4)); }
get { return type_single ?? (LookupSystemValueType (ref type_single, "Single", ElementType.R4)); }
}
public TypeReference Double {
get { return type_double ?? (type_double = LookupSystemValueType ("Double", ElementType.R8)); }
get { return type_double ?? (LookupSystemValueType (ref type_double, "Double", ElementType.R8)); }
}
public TypeReference IntPtr {
get { return type_intptr ?? (type_intptr = LookupSystemValueType ("IntPtr", ElementType.I)); }
get { return type_intptr ?? (LookupSystemValueType (ref type_intptr, "IntPtr", ElementType.I)); }
}
public TypeReference UIntPtr {
get { return type_uintptr ?? (type_uintptr = LookupSystemValueType ("UIntPtr", ElementType.U)); }
get { return type_uintptr ?? (LookupSystemValueType (ref type_uintptr, "UIntPtr", ElementType.U)); }
}
public TypeReference String {
get { return type_string ?? (type_string = LookupSystemType ("String", ElementType.String)); }
get { return type_string ?? (LookupSystemType (ref type_string, "String", ElementType.String)); }
}
public TypeReference TypedReference {
get { return type_typedref ?? (type_typedref = LookupSystemValueType ("TypedReference", ElementType.TypedByRef)); }
get { return type_typedref ?? (LookupSystemValueType (ref type_typedref, "TypedReference", ElementType.TypedByRef)); }
}
}
}

Loading…
Cancel
Save