|
|
|
@ -307,34 +307,34 @@ namespace Decompiler
@@ -307,34 +307,34 @@ namespace Decompiler
|
|
|
|
|
Ast.Expression arg2 = args.Count >= 2 ? args[1] : null; |
|
|
|
|
Ast.Expression arg3 = args.Count >= 3 ? args[2] : null; |
|
|
|
|
|
|
|
|
|
switch((Code)opCode) { |
|
|
|
|
switch(opCode) { |
|
|
|
|
#region Arithmetic
|
|
|
|
|
case Code.Add: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Add, arg2); |
|
|
|
|
case Code.Add_Ovf: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Add, arg2); |
|
|
|
|
case Code.Add_Ovf_Un: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Add, arg2); |
|
|
|
|
case Code.Div: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Divide, arg2); |
|
|
|
|
case Code.Div_Un: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Divide, arg2); |
|
|
|
|
case Code.Mul: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Multiply, arg2); |
|
|
|
|
case Code.Mul_Ovf: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Multiply, arg2); |
|
|
|
|
case Code.Mul_Ovf_Un: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Multiply, arg2); |
|
|
|
|
case Code.Rem: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Modulus, arg2); |
|
|
|
|
case Code.Rem_Un: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Modulus, arg2); |
|
|
|
|
case Code.Sub: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Subtract, arg2); |
|
|
|
|
case Code.Sub_Ovf: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Subtract, arg2); |
|
|
|
|
case Code.Sub_Ovf_Un: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Subtract, arg2); |
|
|
|
|
case Code.And: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.BitwiseAnd, arg2); |
|
|
|
|
case Code.Or: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.BitwiseOr, arg2); |
|
|
|
|
case Code.Xor: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.ExclusiveOr, arg2); |
|
|
|
|
case Code.Shl: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.ShiftLeft, arg2); |
|
|
|
|
case Code.Shr: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.ShiftRight, arg2); |
|
|
|
|
case Code.Shr_Un: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.ShiftRight, 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_Un: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Add, 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.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_Un: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Multiply, 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.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_Un: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Subtract, 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.Xor: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.ExclusiveOr, 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_Un: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.ShiftRight, arg2); |
|
|
|
|
|
|
|
|
|
case Code.Neg: return new Ast.UnaryOperatorExpression(UnaryOperatorType.Minus, arg1); |
|
|
|
|
case Code.Not: return new Ast.UnaryOperatorExpression(UnaryOperatorType.BitNot, arg1); |
|
|
|
|
case ILCode.Neg: return new Ast.UnaryOperatorExpression(UnaryOperatorType.Minus, arg1); |
|
|
|
|
case ILCode.Not: return new Ast.UnaryOperatorExpression(UnaryOperatorType.BitNot, arg1); |
|
|
|
|
#endregion
|
|
|
|
|
#region Arrays
|
|
|
|
|
case Code.Newarr: |
|
|
|
|
case (Code)ILCode.InitArray: |
|
|
|
|
case ILCode.Newarr: |
|
|
|
|
case ILCode.InitArray: |
|
|
|
|
{ |
|
|
|
|
var ace = new Ast.ArrayCreateExpression(); |
|
|
|
|
ace.Type = operandAsTypeRef; |
|
|
|
@ -351,39 +351,41 @@ namespace Decompiler
@@ -351,39 +351,41 @@ namespace Decompiler
|
|
|
|
|
} |
|
|
|
|
return ace; |
|
|
|
|
} |
|
|
|
|
case Code.Ldlen: |
|
|
|
|
case ILCode.Ldlen: |
|
|
|
|
return arg1.Member("Length"); |
|
|
|
|
case Code.Ldelem_I: |
|
|
|
|
case Code.Ldelem_I1: |
|
|
|
|
case Code.Ldelem_I2: |
|
|
|
|
case Code.Ldelem_I4: |
|
|
|
|
case Code.Ldelem_I8: |
|
|
|
|
case Code.Ldelem_U1: |
|
|
|
|
case Code.Ldelem_U2: |
|
|
|
|
case Code.Ldelem_U4: |
|
|
|
|
case Code.Ldelem_R4: |
|
|
|
|
case Code.Ldelem_R8: |
|
|
|
|
case Code.Ldelem_Ref: |
|
|
|
|
case Code.Ldelem_Any: |
|
|
|
|
case ILCode.Ldelem_I: |
|
|
|
|
case ILCode.Ldelem_I1: |
|
|
|
|
case ILCode.Ldelem_I2: |
|
|
|
|
case ILCode.Ldelem_I4: |
|
|
|
|
case ILCode.Ldelem_I8: |
|
|
|
|
case ILCode.Ldelem_U1: |
|
|
|
|
case ILCode.Ldelem_U2: |
|
|
|
|
case ILCode.Ldelem_U4: |
|
|
|
|
case ILCode.Ldelem_R4: |
|
|
|
|
case ILCode.Ldelem_R8: |
|
|
|
|
case ILCode.Ldelem_Ref: |
|
|
|
|
case ILCode.Ldelem_Any: |
|
|
|
|
return arg1.Indexer(arg2); |
|
|
|
|
case Code.Ldelema: |
|
|
|
|
case ILCode.Ldelema: |
|
|
|
|
return MakeRef(arg1.Indexer(arg2)); |
|
|
|
|
|
|
|
|
|
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: |
|
|
|
|
return new Ast.AssignmentExpression(arg1.Indexer(arg2), arg3); |
|
|
|
|
#endregion
|
|
|
|
|
#region Comparison
|
|
|
|
|
case Code.Ceq: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Equality, arg2); |
|
|
|
|
case Code.Cgt: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.GreaterThan, arg2); |
|
|
|
|
case Code.Cgt_Un: |
|
|
|
|
case ILCode.Ceq: |
|
|
|
|
return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Equality, arg2); |
|
|
|
|
case ILCode.Cgt: |
|
|
|
|
return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.GreaterThan, arg2); |
|
|
|
|
case ILCode.Cgt_Un: |
|
|
|
|
// can also mean Inequality, when used with object references
|
|
|
|
|
{ |
|
|
|
|
TypeReference arg1Type = byteCode.Arguments[0].InferredType; |
|
|
|
@ -392,96 +394,98 @@ namespace Decompiler
@@ -392,96 +394,98 @@ namespace Decompiler
|
|
|
|
|
else |
|
|
|
|
return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.GreaterThan, arg2); |
|
|
|
|
} |
|
|
|
|
case Code.Clt: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.LessThan, arg2); |
|
|
|
|
case Code.Clt_Un: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.LessThan, arg2); |
|
|
|
|
case ILCode.Clt: |
|
|
|
|
return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.LessThan, arg2); |
|
|
|
|
case ILCode.Clt_Un: |
|
|
|
|
return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.LessThan, arg2); |
|
|
|
|
#endregion
|
|
|
|
|
#region Conversions
|
|
|
|
|
case Code.Conv_I1: |
|
|
|
|
case Code.Conv_I2: |
|
|
|
|
case Code.Conv_I4: |
|
|
|
|
case Code.Conv_I8: |
|
|
|
|
case Code.Conv_U1: |
|
|
|
|
case Code.Conv_U2: |
|
|
|
|
case Code.Conv_U4: |
|
|
|
|
case Code.Conv_U8: |
|
|
|
|
case ILCode.Conv_I1: |
|
|
|
|
case ILCode.Conv_I2: |
|
|
|
|
case ILCode.Conv_I4: |
|
|
|
|
case ILCode.Conv_I8: |
|
|
|
|
case ILCode.Conv_U1: |
|
|
|
|
case ILCode.Conv_U2: |
|
|
|
|
case ILCode.Conv_U4: |
|
|
|
|
case ILCode.Conv_U8: |
|
|
|
|
return arg1; // conversion is handled by Convert() function using the info from type analysis
|
|
|
|
|
case Code.Conv_I: return arg1.CastTo(typeof(IntPtr)); // TODO
|
|
|
|
|
case Code.Conv_U: return arg1.CastTo(typeof(UIntPtr)); // TODO
|
|
|
|
|
case Code.Conv_R4: return arg1.CastTo(typeof(float)); |
|
|
|
|
case Code.Conv_R8: return arg1.CastTo(typeof(double)); |
|
|
|
|
case Code.Conv_R_Un: return arg1.CastTo(typeof(double)); // TODO
|
|
|
|
|
case ILCode.Conv_I: return arg1.CastTo(typeof(IntPtr)); // TODO
|
|
|
|
|
case ILCode.Conv_U: return arg1.CastTo(typeof(UIntPtr)); // TODO
|
|
|
|
|
case ILCode.Conv_R4: return arg1.CastTo(typeof(float)); |
|
|
|
|
case ILCode.Conv_R8: return arg1.CastTo(typeof(double)); |
|
|
|
|
case ILCode.Conv_R_Un: return arg1.CastTo(typeof(double)); // TODO
|
|
|
|
|
|
|
|
|
|
case Code.Conv_Ovf_I1: |
|
|
|
|
case Code.Conv_Ovf_I2: |
|
|
|
|
case Code.Conv_Ovf_I4: |
|
|
|
|
case Code.Conv_Ovf_I8: |
|
|
|
|
case Code.Conv_Ovf_U1: |
|
|
|
|
case Code.Conv_Ovf_U2: |
|
|
|
|
case Code.Conv_Ovf_U4: |
|
|
|
|
case Code.Conv_Ovf_U8: |
|
|
|
|
case Code.Conv_Ovf_I1_Un: |
|
|
|
|
case Code.Conv_Ovf_I2_Un: |
|
|
|
|
case Code.Conv_Ovf_I4_Un: |
|
|
|
|
case Code.Conv_Ovf_I8_Un: |
|
|
|
|
case Code.Conv_Ovf_U1_Un: |
|
|
|
|
case Code.Conv_Ovf_U2_Un: |
|
|
|
|
case Code.Conv_Ovf_U4_Un: |
|
|
|
|
case Code.Conv_Ovf_U8_Un: |
|
|
|
|
case ILCode.Conv_Ovf_I1: |
|
|
|
|
case ILCode.Conv_Ovf_I2: |
|
|
|
|
case ILCode.Conv_Ovf_I4: |
|
|
|
|
case ILCode.Conv_Ovf_I8: |
|
|
|
|
case ILCode.Conv_Ovf_U1: |
|
|
|
|
case ILCode.Conv_Ovf_U2: |
|
|
|
|
case ILCode.Conv_Ovf_U4: |
|
|
|
|
case ILCode.Conv_Ovf_U8: |
|
|
|
|
case ILCode.Conv_Ovf_I1_Un: |
|
|
|
|
case ILCode.Conv_Ovf_I2_Un: |
|
|
|
|
case ILCode.Conv_Ovf_I4_Un: |
|
|
|
|
case ILCode.Conv_Ovf_I8_Un: |
|
|
|
|
case ILCode.Conv_Ovf_U1_Un: |
|
|
|
|
case ILCode.Conv_Ovf_U2_Un: |
|
|
|
|
case ILCode.Conv_Ovf_U4_Un: |
|
|
|
|
case ILCode.Conv_Ovf_U8_Un: |
|
|
|
|
return arg1; // conversion was handled by Convert() function using the info from type analysis
|
|
|
|
|
case Code.Conv_Ovf_I: return arg1.CastTo(typeof(IntPtr)); // TODO
|
|
|
|
|
case Code.Conv_Ovf_U: return arg1.CastTo(typeof(UIntPtr)); |
|
|
|
|
case Code.Conv_Ovf_I_Un: return arg1.CastTo(typeof(IntPtr)); |
|
|
|
|
case Code.Conv_Ovf_U_Un: return arg1.CastTo(typeof(UIntPtr)); |
|
|
|
|
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_I_Un: return arg1.CastTo(typeof(IntPtr)); |
|
|
|
|
case ILCode.Conv_Ovf_U_Un: return arg1.CastTo(typeof(UIntPtr)); |
|
|
|
|
|
|
|
|
|
case Code.Castclass: |
|
|
|
|
case Code.Unbox_Any: |
|
|
|
|
case ILCode.Castclass: |
|
|
|
|
case ILCode.Unbox_Any: |
|
|
|
|
return arg1.CastTo(operandAsTypeRef); |
|
|
|
|
case Code.Isinst: |
|
|
|
|
case ILCode.Isinst: |
|
|
|
|
return arg1.CastAs(operandAsTypeRef); |
|
|
|
|
case Code.Box: |
|
|
|
|
case ILCode.Box: |
|
|
|
|
return arg1; |
|
|
|
|
case Code.Unbox: |
|
|
|
|
case ILCode.Unbox: |
|
|
|
|
return InlineAssembly(byteCode, args); |
|
|
|
|
#endregion
|
|
|
|
|
#region Indirect
|
|
|
|
|
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 Code.Ldobj: |
|
|
|
|
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: |
|
|
|
|
case ILCode.Ldobj: |
|
|
|
|
if (args[0] is DirectionExpression) |
|
|
|
|
return ((DirectionExpression)args[0]).Expression.Detach(); |
|
|
|
|
else |
|
|
|
|
return InlineAssembly(byteCode, args); |
|
|
|
|
|
|
|
|
|
case Code.Stind_I: |
|
|
|
|
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_Ref: |
|
|
|
|
case Code.Stobj: |
|
|
|
|
case ILCode.Stind_I: |
|
|
|
|
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_Ref: |
|
|
|
|
case ILCode.Stobj: |
|
|
|
|
if (args[0] is DirectionExpression) |
|
|
|
|
return new AssignmentExpression(((DirectionExpression)args[0]).Expression.Detach(), args[1]); |
|
|
|
|
else |
|
|
|
|
return InlineAssembly(byteCode, args); |
|
|
|
|
#endregion
|
|
|
|
|
case Code.Arglist: return InlineAssembly(byteCode, args); |
|
|
|
|
case Code.Break: return InlineAssembly(byteCode, args); |
|
|
|
|
case Code.Call: |
|
|
|
|
case ILCode.Arglist: return InlineAssembly(byteCode, args); |
|
|
|
|
case ILCode.Break: return InlineAssembly(byteCode, args); |
|
|
|
|
case ILCode.Call: |
|
|
|
|
return TransformCall(false, operand, methodDef, args); |
|
|
|
|
case Code.Callvirt: |
|
|
|
|
case ILCode.Callvirt: |
|
|
|
|
return TransformCall(true, operand, methodDef, args); |
|
|
|
|
case Code.Ldftn: |
|
|
|
|
case ILCode.Ldftn: |
|
|
|
|
{ |
|
|
|
|
Cecil.MethodReference cecilMethod = ((MethodReference)operand); |
|
|
|
|
var expr = new Ast.IdentifierExpression(cecilMethod.Name); |
|
|
|
@ -490,7 +494,7 @@ namespace Decompiler
@@ -490,7 +494,7 @@ namespace Decompiler
|
|
|
|
|
return new IdentifierExpression("ldftn").Invoke(expr) |
|
|
|
|
.WithAnnotation(new Transforms.DelegateConstruction.Annotation(false)); |
|
|
|
|
} |
|
|
|
|
case Code.Ldvirtftn: |
|
|
|
|
case ILCode.Ldvirtftn: |
|
|
|
|
{ |
|
|
|
|
Cecil.MethodReference cecilMethod = ((MethodReference)operand); |
|
|
|
|
var expr = new Ast.IdentifierExpression(cecilMethod.Name); |
|
|
|
@ -500,22 +504,23 @@ namespace Decompiler
@@ -500,22 +504,23 @@ namespace Decompiler
|
|
|
|
|
.WithAnnotation(new Transforms.DelegateConstruction.Annotation(true)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
case Code.Calli: return InlineAssembly(byteCode, args); |
|
|
|
|
case Code.Ckfinite: return InlineAssembly(byteCode, args); |
|
|
|
|
case Code.Constrained: return InlineAssembly(byteCode, args); |
|
|
|
|
case Code.Cpblk: return InlineAssembly(byteCode, args); |
|
|
|
|
case Code.Cpobj: return InlineAssembly(byteCode, args); |
|
|
|
|
case Code.Dup: return arg1; |
|
|
|
|
case Code.Endfilter: return InlineAssembly(byteCode, args); |
|
|
|
|
case Code.Endfinally: return null; |
|
|
|
|
case Code.Initblk: return InlineAssembly(byteCode, args); |
|
|
|
|
case Code.Initobj: |
|
|
|
|
case ILCode.Calli: return InlineAssembly(byteCode, args); |
|
|
|
|
case ILCode.Ckfinite: return InlineAssembly(byteCode, args); |
|
|
|
|
case ILCode.Constrained: return InlineAssembly(byteCode, args); |
|
|
|
|
case ILCode.Cpblk: 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: |
|
|
|
|
if (args[0] is DirectionExpression) |
|
|
|
|
return new AssignmentExpression(((DirectionExpression)args[0]).Expression.Detach(), new DefaultValueExpression { Type = operandAsTypeRef }); |
|
|
|
|
else |
|
|
|
|
return InlineAssembly(byteCode, args); |
|
|
|
|
case Code.Jmp: return InlineAssembly(byteCode, args); |
|
|
|
|
case Code.Ldarg: |
|
|
|
|
case ILCode.Jmp: |
|
|
|
|
return InlineAssembly(byteCode, args); |
|
|
|
|
case ILCode.Ldarg: |
|
|
|
|
if (methodDef.HasThis && ((ParameterDefinition)operand).Index < 0) { |
|
|
|
|
if (context.CurrentMethod.DeclaringType.IsValueType) |
|
|
|
|
return MakeRef(new Ast.ThisReferenceExpression()); |
|
|
|
@ -528,59 +533,61 @@ namespace Decompiler
@@ -528,59 +533,61 @@ namespace Decompiler
|
|
|
|
|
else |
|
|
|
|
return expr; |
|
|
|
|
} |
|
|
|
|
case Code.Ldarga: |
|
|
|
|
case ILCode.Ldarga: |
|
|
|
|
if (methodDef.HasThis && ((ParameterDefinition)operand).Index < 0) { |
|
|
|
|
return MakeRef(new Ast.ThisReferenceExpression()); |
|
|
|
|
} else { |
|
|
|
|
return MakeRef(new Ast.IdentifierExpression(((ParameterDefinition)operand).Name).WithAnnotation(operand)); |
|
|
|
|
} |
|
|
|
|
case Code.Ldc_I4: |
|
|
|
|
case ILCode.Ldc_I4: |
|
|
|
|
return AstBuilder.MakePrimitive((int)operand, byteCode.InferredType); |
|
|
|
|
case Code.Ldc_I8: |
|
|
|
|
case Code.Ldc_R4: |
|
|
|
|
case Code.Ldc_R8: |
|
|
|
|
case ILCode.Ldc_I8: |
|
|
|
|
case ILCode.Ldc_R4: |
|
|
|
|
case ILCode.Ldc_R8: |
|
|
|
|
case ILCode.Ldc_Decimal: |
|
|
|
|
return new Ast.PrimitiveExpression(operand); |
|
|
|
|
case Code.Ldfld: |
|
|
|
|
case ILCode.Ldfld: |
|
|
|
|
if (arg1 is DirectionExpression) |
|
|
|
|
arg1 = ((DirectionExpression)arg1).Expression.Detach(); |
|
|
|
|
return arg1.Member(((FieldReference) operand).Name).WithAnnotation(operand); |
|
|
|
|
case Code.Ldsfld: |
|
|
|
|
case ILCode.Ldsfld: |
|
|
|
|
return AstBuilder.ConvertType(((FieldReference)operand).DeclaringType) |
|
|
|
|
.Member(((FieldReference)operand).Name).WithAnnotation(operand); |
|
|
|
|
case Code.Stfld: |
|
|
|
|
case ILCode.Stfld: |
|
|
|
|
if (arg1 is DirectionExpression) |
|
|
|
|
arg1 = ((DirectionExpression)arg1).Expression.Detach(); |
|
|
|
|
return new AssignmentExpression(arg1.Member(((FieldReference) operand).Name).WithAnnotation(operand), arg2); |
|
|
|
|
case Code.Stsfld: |
|
|
|
|
case ILCode.Stsfld: |
|
|
|
|
return new AssignmentExpression( |
|
|
|
|
AstBuilder.ConvertType(((FieldReference)operand).DeclaringType) |
|
|
|
|
.Member(((FieldReference)operand).Name).WithAnnotation(operand), |
|
|
|
|
arg1); |
|
|
|
|
case Code.Ldflda: |
|
|
|
|
case ILCode.Ldflda: |
|
|
|
|
return MakeRef(arg1.Member(((FieldReference) operand).Name).WithAnnotation(operand)); |
|
|
|
|
case Code.Ldsflda: |
|
|
|
|
case ILCode.Ldsflda: |
|
|
|
|
return MakeRef( |
|
|
|
|
AstBuilder.ConvertType(((FieldReference)operand).DeclaringType) |
|
|
|
|
.Member(((FieldReference)operand).Name).WithAnnotation(operand)); |
|
|
|
|
case Code.Ldloc: |
|
|
|
|
case ILCode.Ldloc: |
|
|
|
|
localVariablesToDefine.Add((ILVariable)operand); |
|
|
|
|
return new Ast.IdentifierExpression(((ILVariable)operand).Name).WithAnnotation(operand); |
|
|
|
|
case Code.Ldloca: |
|
|
|
|
case ILCode.Ldloca: |
|
|
|
|
localVariablesToDefine.Add((ILVariable)operand); |
|
|
|
|
return MakeRef(new Ast.IdentifierExpression(((ILVariable)operand).Name).WithAnnotation(operand)); |
|
|
|
|
case Code.Ldnull: |
|
|
|
|
case ILCode.Ldnull: |
|
|
|
|
return new Ast.NullReferenceExpression(); |
|
|
|
|
case Code.Ldstr: return new Ast.PrimitiveExpression(operand); |
|
|
|
|
case Code.Ldtoken: |
|
|
|
|
case ILCode.Ldstr: |
|
|
|
|
return new Ast.PrimitiveExpression(operand); |
|
|
|
|
case ILCode.Ldtoken: |
|
|
|
|
if (operand is Cecil.TypeReference) { |
|
|
|
|
return new Ast.TypeOfExpression { Type = operandAsTypeRef }.Member("TypeHandle"); |
|
|
|
|
} else { |
|
|
|
|
return InlineAssembly(byteCode, args); |
|
|
|
|
} |
|
|
|
|
case Code.Leave: return new GotoStatement() { Label = ((ILLabel)operand).Name }; |
|
|
|
|
case Code.Localloc: return InlineAssembly(byteCode, args); |
|
|
|
|
case Code.Mkrefany: return InlineAssembly(byteCode, args); |
|
|
|
|
case Code.Newobj: |
|
|
|
|
case ILCode.Leave: return new GotoStatement() { Label = ((ILLabel)operand).Name }; |
|
|
|
|
case ILCode.Localloc: return InlineAssembly(byteCode, args); |
|
|
|
|
case ILCode.Mkrefany: return InlineAssembly(byteCode, args); |
|
|
|
|
case ILCode.Newobj: |
|
|
|
|
{ |
|
|
|
|
Cecil.TypeReference declaringType = ((MethodReference)operand).DeclaringType; |
|
|
|
|
|
|
|
|
@ -600,34 +607,34 @@ namespace Decompiler
@@ -600,34 +607,34 @@ namespace Decompiler
|
|
|
|
|
oce.Arguments.AddRange(args); |
|
|
|
|
return oce.WithAnnotation(operand); |
|
|
|
|
} |
|
|
|
|
case Code.No: return InlineAssembly(byteCode, args); |
|
|
|
|
case Code.Nop: return null; |
|
|
|
|
case Code.Pop: return arg1; |
|
|
|
|
case Code.Readonly: return InlineAssembly(byteCode, args); |
|
|
|
|
case Code.Refanytype: return InlineAssembly(byteCode, args); |
|
|
|
|
case Code.Refanyval: return InlineAssembly(byteCode, args); |
|
|
|
|
case Code.Ret: { |
|
|
|
|
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 Code.Rethrow: return new Ast.ThrowStatement(); |
|
|
|
|
case Code.Sizeof: |
|
|
|
|
case ILCode.Rethrow: return new Ast.ThrowStatement(); |
|
|
|
|
case ILCode.Sizeof: |
|
|
|
|
return new Ast.SizeOfExpression { Type = operandAsTypeRef }; |
|
|
|
|
case Code.Starg: |
|
|
|
|
case ILCode.Starg: |
|
|
|
|
return new Ast.AssignmentExpression(new Ast.IdentifierExpression(((ParameterDefinition)operand).Name).WithAnnotation(operand), arg1); |
|
|
|
|
case Code.Stloc: { |
|
|
|
|
case ILCode.Stloc: { |
|
|
|
|
ILVariable locVar = (ILVariable)operand; |
|
|
|
|
localVariablesToDefine.Add(locVar); |
|
|
|
|
return new Ast.AssignmentExpression(new Ast.IdentifierExpression(locVar.Name).WithAnnotation(locVar), arg1); |
|
|
|
|
} |
|
|
|
|
case Code.Switch: return InlineAssembly(byteCode, args); |
|
|
|
|
case Code.Tail: return InlineAssembly(byteCode, args); |
|
|
|
|
case Code.Throw: return new Ast.ThrowStatement { Expression = arg1 }; |
|
|
|
|
case Code.Unaligned: return InlineAssembly(byteCode, args); |
|
|
|
|
case Code.Volatile: return InlineAssembly(byteCode, args); |
|
|
|
|
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: " + opCode); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -711,9 +718,20 @@ namespace Decompiler
@@ -711,9 +718,20 @@ namespace Decompiler
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
// Default invocation
|
|
|
|
|
AdjustArgumentsForMethodCall(cecilMethod, methodArgs); |
|
|
|
|
return target.Invoke(cecilMethod.Name, ConvertTypeArguments(cecilMethod), methodArgs).WithAnnotation(cecilMethod); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void AdjustArgumentsForMethodCall(MethodReference cecilMethod, List<Expression> methodArgs) |
|
|
|
|
{ |
|
|
|
|
// Convert 'ref' into 'out' where necessary
|
|
|
|
|
for (int i = 0; i < methodArgs.Count && i < cecilMethod.Parameters.Count; i++) { |
|
|
|
|
DirectionExpression dir = methodArgs[i] as DirectionExpression; |
|
|
|
|
if (dir != null && cecilMethod.Parameters[i].IsOut) |
|
|
|
|
dir.FieldDirection = FieldDirection.Out; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static PropertyDefinition GetIndexer(MethodDefinition cecilMethodDef) |
|
|
|
|
{ |
|
|
|
|
TypeDefinition typeDef = cecilMethodDef.DeclaringType; |
|
|
|
|