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
case ILCode.Conv_Ovf_U2_Un: case ILCode.Conv_Ovf_U2_Un:
case ILCode.Conv_Ovf_U4_Un: case ILCode.Conv_Ovf_U4_Un:
case ILCode.Conv_Ovf_U8_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 // conversion was handled by Convert() function using the info from type analysis
CastExpression cast = arg1 as CastExpression; CastExpression cast = arg1 as CastExpression;
@ -533,11 +537,8 @@ namespace ICSharpCode.Decompiler.Ast
} }
return arg1; return arg1;
} }
case ILCode.Conv_Ovf_I: return arg1.CastTo(new SimpleType("IntPtr")); // TODO case ILCode.Castclass:
case ILCode.Conv_Ovf_U: return arg1.CastTo(new SimpleType("UIntPtr")); return arg1.CastTo(operandAsTypeRef);
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.Unbox_Any: case ILCode.Unbox_Any:
// unboxing does not require a cast if the argument was an isinst instruction // 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)) 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
JoinBasicBlocks, JoinBasicBlocks,
SimplifyLogicNot, SimplifyLogicNot,
SimplifyShiftOperators, SimplifyShiftOperators,
TransformDecimalCtorToConstant, TypeConversionSimplifications,
SimplifyLdObjAndStObj, SimplifyLdObjAndStObj,
SimplifyCustomShortCircuit, SimplifyCustomShortCircuit,
SimplifyLiftedOperators, SimplifyLiftedOperators,
@ -143,9 +143,8 @@ namespace ICSharpCode.Decompiler.ILAst
if (abortBeforeStep == ILAstOptimizationStep.SimplifyShiftOperators) return; if (abortBeforeStep == ILAstOptimizationStep.SimplifyShiftOperators) return;
modified |= block.RunOptimization(SimplifyShiftOperators); modified |= block.RunOptimization(SimplifyShiftOperators);
if (abortBeforeStep == ILAstOptimizationStep.TransformDecimalCtorToConstant) return; if (abortBeforeStep == ILAstOptimizationStep.TypeConversionSimplifications) return;
modified |= block.RunOptimization(TransformDecimalCtorToConstant); modified |= block.RunOptimization(TypeConversionSimplifications);
modified |= block.RunOptimization(SimplifyLdcI4ConvI8);
if (abortBeforeStep == ILAstOptimizationStep.SimplifyLdObjAndStObj) return; if (abortBeforeStep == ILAstOptimizationStep.SimplifyLdObjAndStObj) return;
modified |= block.RunOptimization(SimplifyLdObjAndStObj); modified |= block.RunOptimization(SimplifyLdObjAndStObj);

66
ICSharpCode.Decompiler/ILAst/PeepholeTransform.cs

@ -28,8 +28,20 @@ namespace ICSharpCode.Decompiler.ILAst
{ {
public partial class ILAstOptimizer public partial class ILAstOptimizer
{ {
#region TransformDecimalCtorToConstant #region TypeConversionSimplifications
static bool TransformDecimalCtorToConstant(List<ILNode> body, ILExpression expr, int pos) 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; MethodReference r;
List<ILExpression> args; List<ILExpression> args;
@ -62,11 +74,34 @@ namespace ICSharpCode.Decompiler.ILAst
} }
} }
} }
bool modified = false; return false;
foreach(ILExpression arg in expr.Arguments) {
modified |= TransformDecimalCtorToConstant(null, arg, -1);
} }
return modified;
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 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 #endregion
@ -129,25 +164,6 @@ namespace ICSharpCode.Decompiler.ILAst
} }
#endregion #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 #region CachedDelegateInitialization
void CachedDelegateInitializationWithField(ILBlock block, ref int i) void CachedDelegateInitializationWithField(ILBlock block, ref int i)
{ {

15
ICSharpCode.Decompiler/ILAst/TypeAnalysis.cs

@ -606,8 +606,19 @@ namespace ICSharpCode.Decompiler.ILAst
#endregion #endregion
#region Array instructions #region Array instructions
case ILCode.Newarr: case ILCode.Newarr:
if (forceInferChildren) if (forceInferChildren) {
InferTypeForExpression(expr.Arguments.Single(), typeSystem.Int32); 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); return new ArrayType((TypeReference)expr.Operand);
case ILCode.InitArray: case ILCode.InitArray:
var operandAsArrayType = (ArrayType)expr.Operand; var operandAsArrayType = (ArrayType)expr.Operand;

10
ICSharpCode.Decompiler/Tests/TypeAnalysisTests.cs

@ -120,4 +120,14 @@ public class TypeAnalysisTests
Console.WriteLine(o is Random); Console.WriteLine(o is Random);
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