Browse Source

Fixed decompiling "new byte[length]" where length is a long.

pull/314/merge
Daniel Grunwald 14 years ago
parent
commit
0010be6add
  1. 11
      ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs
  2. 7
      ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs
  3. 66
      ICSharpCode.Decompiler/ILAst/PeepholeTransform.cs
  4. 15
      ICSharpCode.Decompiler/ILAst/TypeAnalysis.cs
  5. 10
      ICSharpCode.Decompiler/Tests/TypeAnalysisTests.cs

11
ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs

@ -525,6 +525,10 @@ namespace ICSharpCode.Decompiler.Ast @@ -525,6 +525,10 @@ namespace ICSharpCode.Decompiler.Ast
case ILCode.Conv_Ovf_U2_Un:
case ILCode.Conv_Ovf_U4_Un:
case ILCode.Conv_Ovf_U8_Un:
case ILCode.Conv_Ovf_I:
case ILCode.Conv_Ovf_U:
case ILCode.Conv_Ovf_I_Un:
case ILCode.Conv_Ovf_U_Un:
{
// conversion was handled by Convert() function using the info from type analysis
CastExpression cast = arg1 as CastExpression;
@ -533,11 +537,8 @@ namespace ICSharpCode.Decompiler.Ast @@ -533,11 +537,8 @@ namespace ICSharpCode.Decompiler.Ast
}
return arg1;
}
case ILCode.Conv_Ovf_I: return arg1.CastTo(new SimpleType("IntPtr")); // TODO
case ILCode.Conv_Ovf_U: return arg1.CastTo(new SimpleType("UIntPtr"));
case ILCode.Conv_Ovf_I_Un: return arg1.CastTo(new SimpleType("IntPtr"));
case ILCode.Conv_Ovf_U_Un: return arg1.CastTo(new SimpleType("UIntPtr"));
case ILCode.Castclass: return arg1.CastTo(operandAsTypeRef);
case ILCode.Castclass:
return arg1.CastTo(operandAsTypeRef);
case ILCode.Unbox_Any:
// unboxing does not require a cast if the argument was an isinst instruction
if (arg1 is AsExpression && byteCode.Arguments[0].Code == ILCode.Isinst && TypeAnalysis.IsSameType(operand as TypeReference, byteCode.Arguments[0].Operand as TypeReference))

7
ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs

@ -44,7 +44,7 @@ namespace ICSharpCode.Decompiler.ILAst @@ -44,7 +44,7 @@ namespace ICSharpCode.Decompiler.ILAst
JoinBasicBlocks,
SimplifyLogicNot,
SimplifyShiftOperators,
TransformDecimalCtorToConstant,
TypeConversionSimplifications,
SimplifyLdObjAndStObj,
SimplifyCustomShortCircuit,
SimplifyLiftedOperators,
@ -143,9 +143,8 @@ namespace ICSharpCode.Decompiler.ILAst @@ -143,9 +143,8 @@ namespace ICSharpCode.Decompiler.ILAst
if (abortBeforeStep == ILAstOptimizationStep.SimplifyShiftOperators) return;
modified |= block.RunOptimization(SimplifyShiftOperators);
if (abortBeforeStep == ILAstOptimizationStep.TransformDecimalCtorToConstant) return;
modified |= block.RunOptimization(TransformDecimalCtorToConstant);
modified |= block.RunOptimization(SimplifyLdcI4ConvI8);
if (abortBeforeStep == ILAstOptimizationStep.TypeConversionSimplifications) return;
modified |= block.RunOptimization(TypeConversionSimplifications);
if (abortBeforeStep == ILAstOptimizationStep.SimplifyLdObjAndStObj) return;
modified |= block.RunOptimization(SimplifyLdObjAndStObj);

66
ICSharpCode.Decompiler/ILAst/PeepholeTransform.cs

@ -28,8 +28,20 @@ namespace ICSharpCode.Decompiler.ILAst @@ -28,8 +28,20 @@ namespace ICSharpCode.Decompiler.ILAst
{
public partial class ILAstOptimizer
{
#region TransformDecimalCtorToConstant
static bool TransformDecimalCtorToConstant(List<ILNode> body, ILExpression expr, int pos)
#region TypeConversionSimplifications
static bool TypeConversionSimplifications(List<ILNode> body, ILExpression expr, int pos)
{
bool modified = false;
modified |= TransformDecimalCtorToConstant(expr);
modified |= SimplifyLdcI4ConvI8(expr);
modified |= RemoveConvIFromArrayCreation(expr);
foreach(ILExpression arg in expr.Arguments) {
modified |= TypeConversionSimplifications(null, arg, -1);
}
return modified;
}
static bool TransformDecimalCtorToConstant(ILExpression expr)
{
MethodReference r;
List<ILExpression> args;
@ -62,11 +74,34 @@ namespace ICSharpCode.Decompiler.ILAst @@ -62,11 +74,34 @@ namespace ICSharpCode.Decompiler.ILAst
}
}
}
bool modified = false;
foreach(ILExpression arg in expr.Arguments) {
modified |= TransformDecimalCtorToConstant(null, arg, -1);
return false;
}
static bool SimplifyLdcI4ConvI8(ILExpression expr)
{
ILExpression ldc;
int val;
if (expr.Match(ILCode.Conv_I8, out ldc) && ldc.Match(ILCode.Ldc_I4, out val)) {
expr.Code = ILCode.Ldc_I8;
expr.Operand = (long)val;
expr.Arguments.Clear();
return true;
}
return modified;
return false;
}
static bool RemoveConvIFromArrayCreation(ILExpression expr)
{
TypeReference typeRef;
ILExpression length;
ILExpression input;
if (expr.Match(ILCode.Newarr, out typeRef, out length)) {
if (length.Match(ILCode.Conv_Ovf_I, out input) || length.Match(ILCode.Conv_I, out input)) {
expr.Arguments[0] = input;
return true;
}
}
return false;
}
#endregion
@ -129,25 +164,6 @@ namespace ICSharpCode.Decompiler.ILAst @@ -129,25 +164,6 @@ namespace ICSharpCode.Decompiler.ILAst
}
#endregion
#region SimplifyLdcI4ConvI8
static bool SimplifyLdcI4ConvI8(List<ILNode> body, ILExpression expr, int pos)
{
ILExpression ldc;
int val;
if (expr.Match(ILCode.Conv_I8, out ldc) && ldc.Match(ILCode.Ldc_I4, out val)) {
expr.Code = ILCode.Ldc_I8;
expr.Operand = (long)val;
expr.Arguments.Clear();
return true;
}
bool modified = false;
foreach(ILExpression arg in expr.Arguments) {
modified |= SimplifyLdcI4ConvI8(null, arg, -1);
}
return modified;
}
#endregion
#region CachedDelegateInitialization
void CachedDelegateInitializationWithField(ILBlock block, ref int i)
{

15
ICSharpCode.Decompiler/ILAst/TypeAnalysis.cs

@ -606,8 +606,19 @@ namespace ICSharpCode.Decompiler.ILAst @@ -606,8 +606,19 @@ namespace ICSharpCode.Decompiler.ILAst
#endregion
#region Array instructions
case ILCode.Newarr:
if (forceInferChildren)
InferTypeForExpression(expr.Arguments.Single(), typeSystem.Int32);
if (forceInferChildren) {
var lengthType = InferTypeForExpression(expr.Arguments.Single(), null);
if (lengthType == typeSystem.IntPtr) {
lengthType = typeSystem.Int64;
} else if (lengthType == typeSystem.UIntPtr) {
lengthType = typeSystem.UInt64;
} else if (lengthType != typeSystem.UInt32 && lengthType != typeSystem.Int64 && lengthType != typeSystem.UInt64) {
lengthType = typeSystem.Int32;
}
if (forceInferChildren) {
InferTypeForExpression(expr.Arguments.Single(), lengthType);
}
}
return new ArrayType((TypeReference)expr.Operand);
case ILCode.InitArray:
var operandAsArrayType = (ArrayType)expr.Operand;

10
ICSharpCode.Decompiler/Tests/TypeAnalysisTests.cs

@ -120,4 +120,14 @@ public class TypeAnalysisTests @@ -120,4 +120,14 @@ public class TypeAnalysisTests
Console.WriteLine(o is Random);
Console.WriteLine(!(o is Random));
}
public byte[] CreateArrayWithInt(int length)
{
return new byte[length];
}
public byte[] CreateArrayWithLong(long length)
{
return new byte[length];
}
}

Loading…
Cancel
Save