Browse Source

Whitespace reformatting of TransformByteCode

pull/70/head
David Srbecký 15 years ago
parent
commit
fe0b0130e4
  1. 418
      ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs

418
ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs

@ -79,9 +79,7 @@ namespace ICSharpCode.Decompiler.Ast
{ {
Ast.BlockStatement astBlock = new BlockStatement(); Ast.BlockStatement astBlock = new BlockStatement();
if (block != null) { if (block != null) {
if (block.EntryGoto != null) foreach(ILNode node in block.GetChildren()) {
astBlock.Add((Statement)TransformExpression(block.EntryGoto));
foreach(ILNode node in block.Body) {
astBlock.AddRange(TransformNode(node)); astBlock.AddRange(TransformNode(node));
} }
} }
@ -154,41 +152,6 @@ namespace ICSharpCode.Decompiler.Ast
} }
} }
List<Ast.Expression> TransformExpressionArguments(ILExpression expr)
{
List<Ast.Expression> args = new List<Ast.Expression>();
// Args generated by nested expressions (which must be closed)
foreach(ILExpression arg in expr.Arguments) {
args.Add((Ast.Expression)TransformExpression(arg));
}
return args;
}
static string FormatByteCodeOperand(object operand)
{
if (operand == null) {
return string.Empty;
//} else if (operand is ILExpression) {
// return string.Format("IL_{0:X2}", ((ILExpression)operand).Offset);
} else if (operand is MethodReference) {
return ((MethodReference)operand).Name + "()";
} else if (operand is Cecil.TypeReference) {
return ((Cecil.TypeReference)operand).FullName;
} else if (operand is VariableDefinition) {
return ((VariableDefinition)operand).Name;
} else if (operand is ParameterDefinition) {
return ((ParameterDefinition)operand).Name;
} else if (operand is FieldReference) {
return ((FieldReference)operand).Name;
} else if (operand is string) {
return "\"" + operand + "\"";
} else if (operand is int) {
return operand.ToString();
} else {
return operand.ToString();
}
}
AstNode TransformExpression(ILExpression expr) AstNode TransformExpression(ILExpression expr)
{ {
AstNode node = TransformByteCode(expr); AstNode node = TransformByteCode(expr);
@ -204,57 +167,57 @@ namespace ICSharpCode.Decompiler.Ast
object operand = byteCode.Operand; object operand = byteCode.Operand;
AstType operandAsTypeRef = AstBuilder.ConvertType(operand as Cecil.TypeReference); AstType operandAsTypeRef = AstBuilder.ConvertType(operand as Cecil.TypeReference);
List<Ast.Expression> args = TransformExpressionArguments(byteCode); List<Ast.Expression> args = new List<Expression>();
foreach(ILExpression arg in byteCode.Arguments) {
args.Add((Ast.Expression)TransformExpression(arg));
}
Ast.Expression arg1 = args.Count >= 1 ? args[0] : null; Ast.Expression arg1 = args.Count >= 1 ? args[0] : null;
Ast.Expression arg2 = args.Count >= 2 ? args[1] : null; Ast.Expression arg2 = args.Count >= 2 ? args[1] : null;
Ast.Expression arg3 = args.Count >= 3 ? args[2] : null; Ast.Expression arg3 = args.Count >= 3 ? args[2] : null;
switch(byteCode.Code) { switch(byteCode.Code) {
#region Arithmetic #region Arithmetic
case ILCode.Add: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Add, arg2); case ILCode.Add: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Add, arg2);
case ILCode.Add_Ovf: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Add, arg2); case ILCode.Add_Ovf: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Add, arg2);
case ILCode.Add_Ovf_Un: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Add, arg2); case ILCode.Add_Ovf_Un: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Add, arg2);
case ILCode.Div: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Divide, arg2); case ILCode.Div: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Divide, arg2);
case ILCode.Div_Un: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Divide, arg2); case ILCode.Div_Un: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Divide, arg2);
case ILCode.Mul: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Multiply, arg2); case ILCode.Mul: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Multiply, arg2);
case ILCode.Mul_Ovf: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Multiply, arg2); case ILCode.Mul_Ovf: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Multiply, arg2);
case ILCode.Mul_Ovf_Un: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Multiply, arg2); case ILCode.Mul_Ovf_Un: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Multiply, arg2);
case ILCode.Rem: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Modulus, arg2); case ILCode.Rem: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Modulus, arg2);
case ILCode.Rem_Un: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Modulus, arg2); case ILCode.Rem_Un: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Modulus, arg2);
case ILCode.Sub: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Subtract, arg2); case ILCode.Sub: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Subtract, arg2);
case ILCode.Sub_Ovf: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Subtract, arg2); case ILCode.Sub_Ovf: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Subtract, arg2);
case ILCode.Sub_Ovf_Un: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Subtract, arg2); case ILCode.Sub_Ovf_Un: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Subtract, arg2);
case ILCode.And: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.BitwiseAnd, arg2); case ILCode.And: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.BitwiseAnd, arg2);
case ILCode.Or: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.BitwiseOr, arg2); case ILCode.Or: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.BitwiseOr, arg2);
case ILCode.Xor: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.ExclusiveOr, arg2); case ILCode.Xor: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.ExclusiveOr, arg2);
case ILCode.Shl: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.ShiftLeft, arg2); case ILCode.Shl: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.ShiftLeft, arg2);
case ILCode.Shr: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.ShiftRight, arg2); case ILCode.Shr: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.ShiftRight, arg2);
case ILCode.Shr_Un: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.ShiftRight, arg2); case ILCode.Shr_Un: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.ShiftRight, arg2);
case ILCode.Neg: return new Ast.UnaryOperatorExpression(UnaryOperatorType.Minus, arg1);
case ILCode.Neg: return new Ast.UnaryOperatorExpression(UnaryOperatorType.Minus, arg1); case ILCode.Not: return new Ast.UnaryOperatorExpression(UnaryOperatorType.BitNot, arg1);
case ILCode.Not: return new Ast.UnaryOperatorExpression(UnaryOperatorType.BitNot, arg1); #endregion
#endregion #region Arrays
#region Arrays
case ILCode.Newarr: case ILCode.Newarr:
case ILCode.InitArray: case ILCode.InitArray: {
{ var ace = new Ast.ArrayCreateExpression();
var ace = new Ast.ArrayCreateExpression(); ace.Type = operandAsTypeRef;
ace.Type = operandAsTypeRef; ComposedType ct = operandAsTypeRef as ComposedType;
ComposedType ct = operandAsTypeRef as ComposedType; if (ct != null) {
if (ct != null) { // change "new (int[,])[10] to new int[10][,]"
// change "new (int[,])[10] to new int[10][,]" ct.ArraySpecifiers.MoveTo(ace.AdditionalArraySpecifiers);
ct.ArraySpecifiers.MoveTo(ace.AdditionalArraySpecifiers); }
} if (byteCode.Code == ILCode.InitArray) {
if (byteCode.Code == ILCode.InitArray) { ace.Initializer = new ArrayInitializerExpression();
ace.Initializer = new ArrayInitializerExpression(); ace.Initializer.Elements.AddRange(args);
ace.Initializer.Elements.AddRange(args); } else {
} else { ace.Arguments.Add(arg1);
ace.Arguments.Add(arg1);
}
return ace;
} }
case ILCode.Ldlen: return ace;
return arg1.Member("Length"); }
case ILCode.Ldlen: return arg1.Member("Length");
case ILCode.Ldelem_I: case ILCode.Ldelem_I:
case ILCode.Ldelem_I1: case ILCode.Ldelem_I1:
case ILCode.Ldelem_I2: case ILCode.Ldelem_I2:
@ -268,9 +231,7 @@ namespace ICSharpCode.Decompiler.Ast
case ILCode.Ldelem_Ref: case ILCode.Ldelem_Ref:
case ILCode.Ldelem_Any: case ILCode.Ldelem_Any:
return arg1.Indexer(arg2); return arg1.Indexer(arg2);
case ILCode.Ldelema: case ILCode.Ldelema: return MakeRef(arg1.Indexer(arg2));
return MakeRef(arg1.Indexer(arg2));
case ILCode.Stelem_I: case ILCode.Stelem_I:
case ILCode.Stelem_I1: case ILCode.Stelem_I1:
case ILCode.Stelem_I2: case ILCode.Stelem_I2:
@ -281,33 +242,28 @@ namespace ICSharpCode.Decompiler.Ast
case ILCode.Stelem_Ref: case ILCode.Stelem_Ref:
case ILCode.Stelem_Any: case ILCode.Stelem_Any:
return new Ast.AssignmentExpression(arg1.Indexer(arg2), arg3); return new Ast.AssignmentExpression(arg1.Indexer(arg2), arg3);
#endregion #endregion
#region Comparison #region Comparison
case ILCode.Ceq: case ILCode.Ceq: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Equality, arg2);
return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Equality, arg2); case ILCode.Cgt: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.GreaterThan, arg2);
case ILCode.Cgt: case ILCode.Cgt_Un: {
return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.GreaterThan, arg2);
case ILCode.Cgt_Un:
// can also mean Inequality, when used with object references // can also mean Inequality, when used with object references
{ TypeReference arg1Type = byteCode.Arguments[0].InferredType;
TypeReference arg1Type = byteCode.Arguments[0].InferredType; if (arg1Type != null && !arg1Type.IsValueType)
if (arg1Type != null && !arg1Type.IsValueType) return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.InEquality, arg2);
return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.InEquality, arg2); else
else return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.GreaterThan, arg2);
return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.GreaterThan, arg2); }
} case ILCode.Clt: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.LessThan, arg2);
case ILCode.Clt: case ILCode.Clt_Un: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.LessThan, arg2);
return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.LessThan, arg2); #endregion
case ILCode.Clt_Un: #region Logical
return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.LessThan, arg2);
#endregion
#region Logical
case ILCode.LogicNot: return new Ast.UnaryOperatorExpression(UnaryOperatorType.Not, arg1); case ILCode.LogicNot: return new Ast.UnaryOperatorExpression(UnaryOperatorType.Not, arg1);
case ILCode.LogicAnd: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.ConditionalAnd, arg2); case ILCode.LogicAnd: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.ConditionalAnd, arg2);
case ILCode.LogicOr: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.ConditionalOr, arg2); case ILCode.LogicOr: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.ConditionalOr, arg2);
case ILCode.TernaryOp: return new Ast.ConditionalExpression() { Condition = arg1, TrueExpression = arg2, FalseExpression = arg3 }; case ILCode.TernaryOp: return new Ast.ConditionalExpression() { Condition = arg1, TrueExpression = arg2, FalseExpression = arg3 };
#endregion #endregion
#region Branch #region Branch
case ILCode.Br: return new Ast.GotoStatement(((ILLabel)byteCode.Operand).Name); case ILCode.Br: return new Ast.GotoStatement(((ILLabel)byteCode.Operand).Name);
case ILCode.Brtrue: case ILCode.Brtrue:
return new Ast.IfElseStatement() { return new Ast.IfElseStatement() {
@ -316,10 +272,10 @@ namespace ICSharpCode.Decompiler.Ast
new Ast.GotoStatement(((ILLabel)byteCode.Operand).Name) new Ast.GotoStatement(((ILLabel)byteCode.Operand).Name)
} }
}; };
case ILCode.LoopOrSwitchBreak: return new Ast.BreakStatement(); case ILCode.LoopOrSwitchBreak: return new Ast.BreakStatement();
case ILCode.LoopContinue: return new Ast.ContinueStatement(); case ILCode.LoopContinue: return new Ast.ContinueStatement();
#endregion #endregion
#region Conversions #region Conversions
case ILCode.Conv_I1: case ILCode.Conv_I1:
case ILCode.Conv_I2: case ILCode.Conv_I2:
case ILCode.Conv_I4: case ILCode.Conv_I4:
@ -329,12 +285,11 @@ namespace ICSharpCode.Decompiler.Ast
case ILCode.Conv_U4: case ILCode.Conv_U4:
case ILCode.Conv_U8: case ILCode.Conv_U8:
return arg1; // conversion is handled by Convert() function using the info from type analysis return arg1; // conversion is handled by Convert() function using the info from type analysis
case ILCode.Conv_I: return arg1.CastTo(typeof(IntPtr)); // TODO case ILCode.Conv_I: return arg1.CastTo(typeof(IntPtr)); // TODO
case ILCode.Conv_U: return arg1.CastTo(typeof(UIntPtr)); // TODO case ILCode.Conv_U: return arg1.CastTo(typeof(UIntPtr)); // TODO
case ILCode.Conv_R4: return arg1.CastTo(typeof(float)); case ILCode.Conv_R4: return arg1.CastTo(typeof(float));
case ILCode.Conv_R8: return arg1.CastTo(typeof(double)); case ILCode.Conv_R8: return arg1.CastTo(typeof(double));
case ILCode.Conv_R_Un: return arg1.CastTo(typeof(double)); // TODO case ILCode.Conv_R_Un: return arg1.CastTo(typeof(double)); // TODO
case ILCode.Conv_Ovf_I1: case ILCode.Conv_Ovf_I1:
case ILCode.Conv_Ovf_I2: case ILCode.Conv_Ovf_I2:
case ILCode.Conv_Ovf_I4: case ILCode.Conv_Ovf_I4:
@ -352,22 +307,17 @@ namespace ICSharpCode.Decompiler.Ast
case ILCode.Conv_Ovf_U4_Un: case ILCode.Conv_Ovf_U4_Un:
case ILCode.Conv_Ovf_U8_Un: case ILCode.Conv_Ovf_U8_Un:
return arg1; // conversion was handled by Convert() function using the info from type analysis return arg1; // conversion was handled by Convert() function using the info from type analysis
case ILCode.Conv_Ovf_I: return arg1.CastTo(typeof(IntPtr)); // TODO case ILCode.Conv_Ovf_I: return arg1.CastTo(typeof(IntPtr)); // TODO
case ILCode.Conv_Ovf_U: return arg1.CastTo(typeof(UIntPtr)); case ILCode.Conv_Ovf_U: return arg1.CastTo(typeof(UIntPtr));
case ILCode.Conv_Ovf_I_Un: return arg1.CastTo(typeof(IntPtr)); case ILCode.Conv_Ovf_I_Un: return arg1.CastTo(typeof(IntPtr));
case ILCode.Conv_Ovf_U_Un: return arg1.CastTo(typeof(UIntPtr)); case ILCode.Conv_Ovf_U_Un: return arg1.CastTo(typeof(UIntPtr));
case ILCode.Castclass: return arg1.CastTo(operandAsTypeRef);
case ILCode.Castclass: case ILCode.Unbox_Any: return arg1.CastTo(operandAsTypeRef);
case ILCode.Unbox_Any: case ILCode.Isinst: return arg1.CastAs(operandAsTypeRef);
return arg1.CastTo(operandAsTypeRef); case ILCode.Box: return arg1;
case ILCode.Isinst: case ILCode.Unbox: return InlineAssembly(byteCode, args);
return arg1.CastAs(operandAsTypeRef); #endregion
case ILCode.Box: #region Indirect
return arg1;
case ILCode.Unbox:
return InlineAssembly(byteCode, args);
#endregion
#region Indirect
case ILCode.Ldind_I: case ILCode.Ldind_I:
case ILCode.Ldind_I1: case ILCode.Ldind_I1:
case ILCode.Ldind_I2: case ILCode.Ldind_I2:
@ -384,7 +334,6 @@ namespace ICSharpCode.Decompiler.Ast
return ((DirectionExpression)args[0]).Expression.Detach(); return ((DirectionExpression)args[0]).Expression.Detach();
else else
return InlineAssembly(byteCode, args); return InlineAssembly(byteCode, args);
case ILCode.Stind_I: case ILCode.Stind_I:
case ILCode.Stind_I1: case ILCode.Stind_I1:
case ILCode.Stind_I2: case ILCode.Stind_I2:
@ -398,49 +347,43 @@ namespace ICSharpCode.Decompiler.Ast
return new AssignmentExpression(((DirectionExpression)args[0]).Expression.Detach(), args[1]); return new AssignmentExpression(((DirectionExpression)args[0]).Expression.Detach(), args[1]);
else else
return InlineAssembly(byteCode, args); return InlineAssembly(byteCode, args);
#endregion #endregion
case ILCode.Arglist: return InlineAssembly(byteCode, args); case ILCode.Arglist: return InlineAssembly(byteCode, args);
case ILCode.Break: return InlineAssembly(byteCode, args); case ILCode.Break: return InlineAssembly(byteCode, args);
case ILCode.Call: case ILCode.Call: return TransformCall(false, operand, methodDef, args);
return TransformCall(false, operand, methodDef, args); case ILCode.Callvirt: return TransformCall(true, operand, methodDef, args);
case ILCode.Callvirt: case ILCode.Ldftn: {
return TransformCall(true, operand, methodDef, args); Cecil.MethodReference cecilMethod = ((MethodReference)operand);
case ILCode.Ldftn: var expr = new Ast.IdentifierExpression(cecilMethod.Name);
{ expr.TypeArguments.AddRange(ConvertTypeArguments(cecilMethod));
Cecil.MethodReference cecilMethod = ((MethodReference)operand); expr.AddAnnotation(cecilMethod);
var expr = new Ast.IdentifierExpression(cecilMethod.Name); return new IdentifierExpression("ldftn").Invoke(expr)
expr.TypeArguments.AddRange(ConvertTypeArguments(cecilMethod)); .WithAnnotation(new Transforms.DelegateConstruction.Annotation(false));
expr.AddAnnotation(cecilMethod); }
return new IdentifierExpression("ldftn").Invoke(expr) case ILCode.Ldvirtftn: {
.WithAnnotation(new Transforms.DelegateConstruction.Annotation(false)); Cecil.MethodReference cecilMethod = ((MethodReference)operand);
} var expr = new Ast.IdentifierExpression(cecilMethod.Name);
case ILCode.Ldvirtftn: expr.TypeArguments.AddRange(ConvertTypeArguments(cecilMethod));
{ expr.AddAnnotation(cecilMethod);
Cecil.MethodReference cecilMethod = ((MethodReference)operand); return new IdentifierExpression("ldvirtftn").Invoke(expr)
var expr = new Ast.IdentifierExpression(cecilMethod.Name); .WithAnnotation(new Transforms.DelegateConstruction.Annotation(true));
expr.TypeArguments.AddRange(ConvertTypeArguments(cecilMethod)); }
expr.AddAnnotation(cecilMethod); case ILCode.Calli: return InlineAssembly(byteCode, args);
return new IdentifierExpression("ldvirtftn").Invoke(expr) case ILCode.Ckfinite: return InlineAssembly(byteCode, args);
.WithAnnotation(new Transforms.DelegateConstruction.Annotation(true)); case ILCode.Constrained: return InlineAssembly(byteCode, args);
} case ILCode.Cpblk: return InlineAssembly(byteCode, args);
case ILCode.Cpobj: return InlineAssembly(byteCode, args);
case ILCode.Calli: return InlineAssembly(byteCode, args); case ILCode.Dup: return arg1;
case ILCode.Ckfinite: return InlineAssembly(byteCode, args); case ILCode.Endfilter: return InlineAssembly(byteCode, args);
case ILCode.Constrained: return InlineAssembly(byteCode, args); case ILCode.Endfinally: return null;
case ILCode.Cpblk: return InlineAssembly(byteCode, args); case ILCode.Initblk: return InlineAssembly(byteCode, args);
case ILCode.Cpobj: return InlineAssembly(byteCode, args);
case ILCode.Dup: return arg1;
case ILCode.Endfilter: return InlineAssembly(byteCode, args);
case ILCode.Endfinally: return null;
case ILCode.Initblk: return InlineAssembly(byteCode, args);
case ILCode.Initobj: case ILCode.Initobj:
if (args[0] is DirectionExpression) if (args[0] is DirectionExpression)
return new AssignmentExpression(((DirectionExpression)args[0]).Expression.Detach(), new DefaultValueExpression { Type = operandAsTypeRef }); return new AssignmentExpression(((DirectionExpression)args[0]).Expression.Detach(), new DefaultValueExpression { Type = operandAsTypeRef });
else else
return InlineAssembly(byteCode, args); return InlineAssembly(byteCode, args);
case ILCode.Jmp: case ILCode.Jmp: return InlineAssembly(byteCode, args);
return InlineAssembly(byteCode, args); case ILCode.Ldarg: {
case ILCode.Ldarg:
if (methodDef.HasThis && ((ParameterDefinition)operand).Index < 0) { if (methodDef.HasThis && ((ParameterDefinition)operand).Index < 0) {
if (context.CurrentMethod.DeclaringType.IsValueType) if (context.CurrentMethod.DeclaringType.IsValueType)
return MakeRef(new Ast.ThisReferenceExpression()); return MakeRef(new Ast.ThisReferenceExpression());
@ -453,14 +396,14 @@ namespace ICSharpCode.Decompiler.Ast
else else
return expr; return expr;
} }
}
case ILCode.Ldarga: case ILCode.Ldarga:
if (methodDef.HasThis && ((ParameterDefinition)operand).Index < 0) { if (methodDef.HasThis && ((ParameterDefinition)operand).Index < 0) {
return MakeRef(new Ast.ThisReferenceExpression()); return MakeRef(new Ast.ThisReferenceExpression());
} else { } else {
return MakeRef(new Ast.IdentifierExpression(((ParameterDefinition)operand).Name).WithAnnotation(operand)); return MakeRef(new Ast.IdentifierExpression(((ParameterDefinition)operand).Name).WithAnnotation(operand));
} }
case ILCode.Ldc_I4: case ILCode.Ldc_I4: return AstBuilder.MakePrimitive((int)operand, byteCode.InferredType);
return AstBuilder.MakePrimitive((int)operand, byteCode.InferredType);
case ILCode.Ldc_I8: case ILCode.Ldc_I8:
case ILCode.Ldc_R4: case ILCode.Ldc_R4:
case ILCode.Ldc_R8: case ILCode.Ldc_R8:
@ -482,8 +425,7 @@ namespace ICSharpCode.Decompiler.Ast
AstBuilder.ConvertType(((FieldReference)operand).DeclaringType) AstBuilder.ConvertType(((FieldReference)operand).DeclaringType)
.Member(((FieldReference)operand).Name).WithAnnotation(operand), .Member(((FieldReference)operand).Name).WithAnnotation(operand),
arg1); arg1);
case ILCode.Ldflda: case ILCode.Ldflda: return MakeRef(arg1.Member(((FieldReference) operand).Name).WithAnnotation(operand));
return MakeRef(arg1.Member(((FieldReference) operand).Name).WithAnnotation(operand));
case ILCode.Ldsflda: case ILCode.Ldsflda:
return MakeRef( return MakeRef(
AstBuilder.ConvertType(((FieldReference)operand).DeclaringType) AstBuilder.ConvertType(((FieldReference)operand).DeclaringType)
@ -494,68 +436,61 @@ namespace ICSharpCode.Decompiler.Ast
case ILCode.Ldloca: case ILCode.Ldloca:
localVariablesToDefine.Add((ILVariable)operand); localVariablesToDefine.Add((ILVariable)operand);
return MakeRef(new Ast.IdentifierExpression(((ILVariable)operand).Name).WithAnnotation(operand)); return MakeRef(new Ast.IdentifierExpression(((ILVariable)operand).Name).WithAnnotation(operand));
case ILCode.Ldnull: case ILCode.Ldnull: return new Ast.NullReferenceExpression();
return new Ast.NullReferenceExpression(); case ILCode.Ldstr: return new Ast.PrimitiveExpression(operand);
case ILCode.Ldstr:
return new Ast.PrimitiveExpression(operand);
case ILCode.Ldtoken: case ILCode.Ldtoken:
if (operand is Cecil.TypeReference) { if (operand is Cecil.TypeReference) {
return new Ast.TypeOfExpression { Type = operandAsTypeRef }.Member("TypeHandle"); return new Ast.TypeOfExpression { Type = operandAsTypeRef }.Member("TypeHandle");
} else { } else {
return InlineAssembly(byteCode, args); return InlineAssembly(byteCode, args);
} }
case ILCode.Leave: return new GotoStatement() { Label = ((ILLabel)operand).Name }; case ILCode.Leave: return new GotoStatement() { Label = ((ILLabel)operand).Name };
case ILCode.Localloc: return InlineAssembly(byteCode, args); case ILCode.Localloc: return InlineAssembly(byteCode, args);
case ILCode.Mkrefany: return InlineAssembly(byteCode, args); case ILCode.Mkrefany: return InlineAssembly(byteCode, args);
case ILCode.Newobj: case ILCode.Newobj: {
{ Cecil.TypeReference declaringType = ((MethodReference)operand).DeclaringType;
Cecil.TypeReference declaringType = ((MethodReference)operand).DeclaringType; if (declaringType is ArrayType) {
ComposedType ct = AstBuilder.ConvertType((ArrayType)declaringType) as ComposedType;
if (declaringType is ArrayType) { if (ct != null && ct.ArraySpecifiers.Count >= 1) {
ComposedType ct = AstBuilder.ConvertType((ArrayType)declaringType) as ComposedType; var ace = new Ast.ArrayCreateExpression();
if (ct != null && ct.ArraySpecifiers.Count >= 1) { ct.ArraySpecifiers.First().Remove();
var ace = new Ast.ArrayCreateExpression(); ct.ArraySpecifiers.MoveTo(ace.AdditionalArraySpecifiers);
ct.ArraySpecifiers.First().Remove(); ace.Type = ct;
ct.ArraySpecifiers.MoveTo(ace.AdditionalArraySpecifiers); ace.Arguments.AddRange(args);
ace.Type = ct; return ace;
ace.Arguments.AddRange(args);
return ace;
}
}
var oce = new Ast.ObjectCreateExpression();
oce.Type = AstBuilder.ConvertType(declaringType);
oce.Arguments.AddRange(args);
return oce.WithAnnotation(operand);
}
case ILCode.No: return InlineAssembly(byteCode, args);
case ILCode.Nop: return null;
case ILCode.Pop: return arg1;
case ILCode.Readonly: return InlineAssembly(byteCode, args);
case ILCode.Refanytype: return InlineAssembly(byteCode, args);
case ILCode.Refanyval: return InlineAssembly(byteCode, args);
case ILCode.Ret: {
if (methodDef.ReturnType.FullName != "System.Void") {
return new Ast.ReturnStatement { Expression = arg1 };
} else {
return new Ast.ReturnStatement();
} }
} }
case ILCode.Rethrow: return new Ast.ThrowStatement(); var oce = new Ast.ObjectCreateExpression();
case ILCode.Sizeof: oce.Type = AstBuilder.ConvertType(declaringType);
return new Ast.SizeOfExpression { Type = operandAsTypeRef }; oce.Arguments.AddRange(args);
case ILCode.Starg: return oce.WithAnnotation(operand);
return new Ast.AssignmentExpression(new Ast.IdentifierExpression(((ParameterDefinition)operand).Name).WithAnnotation(operand), arg1); }
case ILCode.Stloc: { case ILCode.No: return InlineAssembly(byteCode, args);
ILVariable locVar = (ILVariable)operand; case ILCode.Nop: return null;
localVariablesToDefine.Add(locVar); case ILCode.Pop: return arg1;
return new Ast.AssignmentExpression(new Ast.IdentifierExpression(locVar.Name).WithAnnotation(locVar), arg1); case ILCode.Readonly: return InlineAssembly(byteCode, args);
case ILCode.Refanytype: return InlineAssembly(byteCode, args);
case ILCode.Refanyval: return InlineAssembly(byteCode, args);
case ILCode.Ret:
if (methodDef.ReturnType.FullName != "System.Void") {
return new Ast.ReturnStatement { Expression = arg1 };
} else {
return new Ast.ReturnStatement();
} }
case ILCode.Switch: return InlineAssembly(byteCode, args); case ILCode.Rethrow: return new Ast.ThrowStatement();
case ILCode.Tail: return InlineAssembly(byteCode, args); case ILCode.Sizeof: return new Ast.SizeOfExpression { Type = operandAsTypeRef };
case ILCode.Throw: return new Ast.ThrowStatement { Expression = arg1 }; case ILCode.Starg: return new Ast.AssignmentExpression(new Ast.IdentifierExpression(((ParameterDefinition)operand).Name).WithAnnotation(operand), arg1);
case ILCode.Unaligned: return InlineAssembly(byteCode, args); case ILCode.Stloc: {
case ILCode.Volatile: return InlineAssembly(byteCode, args); ILVariable locVar = (ILVariable)operand;
default: throw new Exception("Unknown OpCode: " + byteCode.Code); localVariablesToDefine.Add(locVar);
return new Ast.AssignmentExpression(new Ast.IdentifierExpression(locVar.Name).WithAnnotation(locVar), arg1);
}
case ILCode.Switch: return InlineAssembly(byteCode, args);
case ILCode.Tail: return InlineAssembly(byteCode, args);
case ILCode.Throw: return new Ast.ThrowStatement { Expression = arg1 };
case ILCode.Unaligned: return InlineAssembly(byteCode, args);
case ILCode.Volatile: return InlineAssembly(byteCode, args);
default: throw new Exception("Unknown OpCode: " + byteCode.Code);
} }
} }
@ -707,6 +642,31 @@ namespace ICSharpCode.Decompiler.Ast
return new IdentifierExpression(byteCode.Code.GetName()).Invoke(args); return new IdentifierExpression(byteCode.Code.GetName()).Invoke(args);
} }
static string FormatByteCodeOperand(object operand)
{
if (operand == null) {
return string.Empty;
//} else if (operand is ILExpression) {
// return string.Format("IL_{0:X2}", ((ILExpression)operand).Offset);
} else if (operand is MethodReference) {
return ((MethodReference)operand).Name + "()";
} else if (operand is Cecil.TypeReference) {
return ((Cecil.TypeReference)operand).FullName;
} else if (operand is VariableDefinition) {
return ((VariableDefinition)operand).Name;
} else if (operand is ParameterDefinition) {
return ((ParameterDefinition)operand).Name;
} else if (operand is FieldReference) {
return ((FieldReference)operand).Name;
} else if (operand is string) {
return "\"" + operand + "\"";
} else if (operand is int) {
return operand.ToString();
} else {
return operand.ToString();
}
}
static IEnumerable<AstType> ConvertTypeArguments(MethodReference cecilMethod) static IEnumerable<AstType> ConvertTypeArguments(MethodReference cecilMethod)
{ {
GenericInstanceMethod g = cecilMethod as GenericInstanceMethod; GenericInstanceMethod g = cecilMethod as GenericInstanceMethod;

Loading…
Cancel
Save