|
|
@ -305,8 +305,6 @@ namespace Decompiler |
|
|
|
|
|
|
|
|
|
|
|
AstNode TransformByteCode_Internal(ILExpression byteCode, List<Ast.Expression> args) |
|
|
|
AstNode TransformByteCode_Internal(ILExpression byteCode, List<Ast.Expression> args) |
|
|
|
{ |
|
|
|
{ |
|
|
|
// throw new NotImplementedException();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ILCode opCode = byteCode.Code; |
|
|
|
ILCode opCode = byteCode.Code; |
|
|
|
object operand = byteCode.Operand; |
|
|
|
object operand = byteCode.Operand; |
|
|
|
AstType operandAsTypeRef = AstBuilder.ConvertType(operand as Cecil.TypeReference); |
|
|
|
AstType operandAsTypeRef = AstBuilder.ConvertType(operand as Cecil.TypeReference); |
|
|
@ -369,7 +367,7 @@ namespace Decompiler |
|
|
|
case Code.Ldelem_Ref: |
|
|
|
case Code.Ldelem_Ref: |
|
|
|
return arg1.Indexer(arg2); |
|
|
|
return arg1.Indexer(arg2); |
|
|
|
case Code.Ldelem_Any: |
|
|
|
case Code.Ldelem_Any: |
|
|
|
throw new NotImplementedException(); |
|
|
|
return InlineAssembly(byteCode, args); |
|
|
|
case Code.Ldelema: |
|
|
|
case Code.Ldelema: |
|
|
|
return MakeRef(arg1.Indexer(arg2)); |
|
|
|
return MakeRef(arg1.Indexer(arg2)); |
|
|
|
|
|
|
|
|
|
|
@ -383,7 +381,7 @@ namespace Decompiler |
|
|
|
case Code.Stelem_Ref: |
|
|
|
case Code.Stelem_Ref: |
|
|
|
return new Ast.AssignmentExpression(arg1.Indexer(arg2), arg3); |
|
|
|
return new Ast.AssignmentExpression(arg1.Indexer(arg2), arg3); |
|
|
|
case Code.Stelem_Any: |
|
|
|
case Code.Stelem_Any: |
|
|
|
throw new NotImplementedException(); |
|
|
|
return InlineAssembly(byteCode, args); |
|
|
|
#endregion
|
|
|
|
#endregion
|
|
|
|
#region Branching
|
|
|
|
#region Branching
|
|
|
|
case Code.Br: return new Ast.GotoStatement(((ILLabel)byteCode.Operand).Name); |
|
|
|
case Code.Br: return new Ast.GotoStatement(((ILLabel)byteCode.Operand).Name); |
|
|
@ -445,30 +443,30 @@ namespace Decompiler |
|
|
|
case Code.Conv_Ovf_U8_Un: return arg1.CastTo(typeof(UInt64)); |
|
|
|
case Code.Conv_Ovf_U8_Un: return arg1.CastTo(typeof(UInt64)); |
|
|
|
#endregion
|
|
|
|
#endregion
|
|
|
|
#region Indirect
|
|
|
|
#region Indirect
|
|
|
|
case Code.Ldind_I: throw new NotImplementedException(); |
|
|
|
case Code.Ldind_I: return InlineAssembly(byteCode, args); |
|
|
|
case Code.Ldind_I1: throw new NotImplementedException(); |
|
|
|
case Code.Ldind_I1: return InlineAssembly(byteCode, args); |
|
|
|
case Code.Ldind_I2: throw new NotImplementedException(); |
|
|
|
case Code.Ldind_I2: return InlineAssembly(byteCode, args); |
|
|
|
case Code.Ldind_I4: throw new NotImplementedException(); |
|
|
|
case Code.Ldind_I4: return InlineAssembly(byteCode, args); |
|
|
|
case Code.Ldind_I8: throw new NotImplementedException(); |
|
|
|
case Code.Ldind_I8: return InlineAssembly(byteCode, args); |
|
|
|
case Code.Ldind_U1: throw new NotImplementedException(); |
|
|
|
case Code.Ldind_U1: return InlineAssembly(byteCode, args); |
|
|
|
case Code.Ldind_U2: throw new NotImplementedException(); |
|
|
|
case Code.Ldind_U2: return InlineAssembly(byteCode, args); |
|
|
|
case Code.Ldind_U4: throw new NotImplementedException(); |
|
|
|
case Code.Ldind_U4: return InlineAssembly(byteCode, args); |
|
|
|
case Code.Ldind_R4: throw new NotImplementedException(); |
|
|
|
case Code.Ldind_R4: return InlineAssembly(byteCode, args); |
|
|
|
case Code.Ldind_R8: throw new NotImplementedException(); |
|
|
|
case Code.Ldind_R8: return InlineAssembly(byteCode, args); |
|
|
|
case Code.Ldind_Ref: throw new NotImplementedException(); |
|
|
|
case Code.Ldind_Ref: return InlineAssembly(byteCode, args); |
|
|
|
|
|
|
|
|
|
|
|
case Code.Stind_I: throw new NotImplementedException(); |
|
|
|
case Code.Stind_I: return InlineAssembly(byteCode, args); |
|
|
|
case Code.Stind_I1: throw new NotImplementedException(); |
|
|
|
case Code.Stind_I1: return InlineAssembly(byteCode, args); |
|
|
|
case Code.Stind_I2: throw new NotImplementedException(); |
|
|
|
case Code.Stind_I2: return InlineAssembly(byteCode, args); |
|
|
|
case Code.Stind_I4: throw new NotImplementedException(); |
|
|
|
case Code.Stind_I4: return InlineAssembly(byteCode, args); |
|
|
|
case Code.Stind_I8: throw new NotImplementedException(); |
|
|
|
case Code.Stind_I8: return InlineAssembly(byteCode, args); |
|
|
|
case Code.Stind_R4: throw new NotImplementedException(); |
|
|
|
case Code.Stind_R4: return InlineAssembly(byteCode, args); |
|
|
|
case Code.Stind_R8: throw new NotImplementedException(); |
|
|
|
case Code.Stind_R8: return InlineAssembly(byteCode, args); |
|
|
|
case Code.Stind_Ref: throw new NotImplementedException(); |
|
|
|
case Code.Stind_Ref: return InlineAssembly(byteCode, args); |
|
|
|
#endregion
|
|
|
|
#endregion
|
|
|
|
case Code.Arglist: throw new NotImplementedException(); |
|
|
|
case Code.Arglist: return InlineAssembly(byteCode, args); |
|
|
|
case Code.Box: throw new NotImplementedException(); |
|
|
|
case Code.Box: return InlineAssembly(byteCode, args); |
|
|
|
case Code.Break: throw new NotImplementedException(); |
|
|
|
case Code.Break: return InlineAssembly(byteCode, args); |
|
|
|
case Code.Call: |
|
|
|
case Code.Call: |
|
|
|
return TransformCall(false, operand, methodDef, args); |
|
|
|
return TransformCall(false, operand, methodDef, args); |
|
|
|
case Code.Callvirt: |
|
|
|
case Code.Callvirt: |
|
|
@ -492,19 +490,19 @@ namespace Decompiler |
|
|
|
.WithAnnotation(new Transforms.DelegateConstruction.Annotation(true)); |
|
|
|
.WithAnnotation(new Transforms.DelegateConstruction.Annotation(true)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
case Code.Calli: throw new NotImplementedException(); |
|
|
|
case Code.Calli: return InlineAssembly(byteCode, args); |
|
|
|
case Code.Castclass: return arg1.CastTo(operandAsTypeRef); |
|
|
|
case Code.Castclass: return arg1.CastTo(operandAsTypeRef); |
|
|
|
case Code.Ckfinite: throw new NotImplementedException(); |
|
|
|
case Code.Ckfinite: return InlineAssembly(byteCode, args); |
|
|
|
case Code.Constrained: throw new NotImplementedException(); |
|
|
|
case Code.Constrained: return InlineAssembly(byteCode, args); |
|
|
|
case Code.Cpblk: throw new NotImplementedException(); |
|
|
|
case Code.Cpblk: return InlineAssembly(byteCode, args); |
|
|
|
case Code.Cpobj: throw new NotImplementedException(); |
|
|
|
case Code.Cpobj: return InlineAssembly(byteCode, args); |
|
|
|
case Code.Dup: return arg1; |
|
|
|
case Code.Dup: return arg1; |
|
|
|
case Code.Endfilter: throw new NotImplementedException(); |
|
|
|
case Code.Endfilter: return InlineAssembly(byteCode, args); |
|
|
|
case Code.Endfinally: return null; |
|
|
|
case Code.Endfinally: return null; |
|
|
|
case Code.Initblk: throw new NotImplementedException(); |
|
|
|
case Code.Initblk: return InlineAssembly(byteCode, args); |
|
|
|
case Code.Initobj: throw new NotImplementedException(); |
|
|
|
case Code.Initobj: return InlineAssembly(byteCode, args); |
|
|
|
case Code.Isinst: return arg1.CastAs(AstBuilder.ConvertType((Cecil.TypeReference)operand)); |
|
|
|
case Code.Isinst: return arg1.CastAs(AstBuilder.ConvertType((Cecil.TypeReference)operand)); |
|
|
|
case Code.Jmp: throw new NotImplementedException(); |
|
|
|
case Code.Jmp: return InlineAssembly(byteCode, args); |
|
|
|
case Code.Ldarg: |
|
|
|
case Code.Ldarg: |
|
|
|
if (methodDef.HasThis && ((ParameterDefinition)operand).Index < 0) { |
|
|
|
if (methodDef.HasThis && ((ParameterDefinition)operand).Index < 0) { |
|
|
|
return new Ast.ThisReferenceExpression(); |
|
|
|
return new Ast.ThisReferenceExpression(); |
|
|
@ -559,17 +557,17 @@ namespace Decompiler |
|
|
|
case Code.Ldloca: |
|
|
|
case Code.Ldloca: |
|
|
|
return MakeRef(new Ast.IdentifierExpression(((ILVariable)operand).Name)); |
|
|
|
return MakeRef(new Ast.IdentifierExpression(((ILVariable)operand).Name)); |
|
|
|
case Code.Ldnull: return new Ast.NullReferenceExpression(); |
|
|
|
case Code.Ldnull: return new Ast.NullReferenceExpression(); |
|
|
|
case Code.Ldobj: throw new NotImplementedException(); |
|
|
|
case Code.Ldobj: return InlineAssembly(byteCode, args); |
|
|
|
case Code.Ldstr: return new Ast.PrimitiveExpression(operand); |
|
|
|
case Code.Ldstr: return new Ast.PrimitiveExpression(operand); |
|
|
|
case Code.Ldtoken: |
|
|
|
case Code.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 { |
|
|
|
throw new NotImplementedException(); |
|
|
|
return InlineAssembly(byteCode, args); |
|
|
|
} |
|
|
|
} |
|
|
|
case Code.Leave: return null; |
|
|
|
case Code.Leave: return null; |
|
|
|
case Code.Localloc: throw new NotImplementedException(); |
|
|
|
case Code.Localloc: return InlineAssembly(byteCode, args); |
|
|
|
case Code.Mkrefany: throw new NotImplementedException(); |
|
|
|
case Code.Mkrefany: return InlineAssembly(byteCode, args); |
|
|
|
case Code.Newobj: |
|
|
|
case Code.Newobj: |
|
|
|
{ |
|
|
|
{ |
|
|
|
Cecil.TypeReference declaringType = ((MethodReference)operand).DeclaringType; |
|
|
|
Cecil.TypeReference declaringType = ((MethodReference)operand).DeclaringType; |
|
|
@ -586,12 +584,12 @@ namespace Decompiler |
|
|
|
oce.Arguments.AddRange(args); |
|
|
|
oce.Arguments.AddRange(args); |
|
|
|
return oce.WithAnnotation(operand); |
|
|
|
return oce.WithAnnotation(operand); |
|
|
|
} |
|
|
|
} |
|
|
|
case Code.No: throw new NotImplementedException(); |
|
|
|
case Code.No: return InlineAssembly(byteCode, args); |
|
|
|
case Code.Nop: return null; |
|
|
|
case Code.Nop: return null; |
|
|
|
case Code.Pop: return arg1; |
|
|
|
case Code.Pop: return arg1; |
|
|
|
case Code.Readonly: throw new NotImplementedException(); |
|
|
|
case Code.Readonly: return InlineAssembly(byteCode, args); |
|
|
|
case Code.Refanytype: throw new NotImplementedException(); |
|
|
|
case Code.Refanytype: return InlineAssembly(byteCode, args); |
|
|
|
case Code.Refanyval: throw new NotImplementedException(); |
|
|
|
case Code.Refanyval: return InlineAssembly(byteCode, args); |
|
|
|
case Code.Ret: { |
|
|
|
case Code.Ret: { |
|
|
|
if (methodDef.ReturnType.FullName != "System.Void") { |
|
|
|
if (methodDef.ReturnType.FullName != "System.Void") { |
|
|
|
arg1 = Convert(arg1, methodDef.ReturnType); |
|
|
|
arg1 = Convert(arg1, methodDef.ReturnType); |
|
|
@ -602,7 +600,7 @@ namespace Decompiler |
|
|
|
} |
|
|
|
} |
|
|
|
case Code.Rethrow: return new Ast.ThrowStatement(); |
|
|
|
case Code.Rethrow: return new Ast.ThrowStatement(); |
|
|
|
case Code.Sizeof: return new Ast.SizeOfExpression { Type = AstBuilder.ConvertType(operand as TypeReference) }; |
|
|
|
case Code.Sizeof: return new Ast.SizeOfExpression { Type = AstBuilder.ConvertType(operand as TypeReference) }; |
|
|
|
case Code.Starg: throw new NotImplementedException(); |
|
|
|
case Code.Starg: return InlineAssembly(byteCode, args); |
|
|
|
case Code.Stloc: { |
|
|
|
case Code.Stloc: { |
|
|
|
ILVariable locVar = (ILVariable)operand; |
|
|
|
ILVariable locVar = (ILVariable)operand; |
|
|
|
if (!definedLocalVars.Contains(locVar)) { |
|
|
|
if (!definedLocalVars.Contains(locVar)) { |
|
|
@ -615,14 +613,14 @@ namespace Decompiler |
|
|
|
return new Ast.AssignmentExpression(new Ast.IdentifierExpression(locVar.Name), arg1); |
|
|
|
return new Ast.AssignmentExpression(new Ast.IdentifierExpression(locVar.Name), arg1); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
case Code.Stobj: throw new NotImplementedException(); |
|
|
|
case Code.Stobj: return InlineAssembly(byteCode, args); |
|
|
|
case Code.Switch: throw new NotImplementedException(); |
|
|
|
case Code.Switch: return InlineAssembly(byteCode, args); |
|
|
|
case Code.Tail: throw new NotImplementedException(); |
|
|
|
case Code.Tail: return InlineAssembly(byteCode, args); |
|
|
|
case Code.Throw: return new Ast.ThrowStatement { Expression = arg1 }; |
|
|
|
case Code.Throw: return new Ast.ThrowStatement { Expression = arg1 }; |
|
|
|
case Code.Unaligned: throw new NotImplementedException(); |
|
|
|
case Code.Unaligned: return InlineAssembly(byteCode, args); |
|
|
|
case Code.Unbox: throw new NotImplementedException(); |
|
|
|
case Code.Unbox: return InlineAssembly(byteCode, args); |
|
|
|
case Code.Unbox_Any: throw new NotImplementedException(); |
|
|
|
case Code.Unbox_Any: return InlineAssembly(byteCode, args); |
|
|
|
case Code.Volatile: throw new NotImplementedException(); |
|
|
|
case Code.Volatile: return InlineAssembly(byteCode, args); |
|
|
|
default: throw new Exception("Unknown OpCode: " + opCode); |
|
|
|
default: throw new Exception("Unknown OpCode: " + opCode); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -692,6 +690,15 @@ namespace Decompiler |
|
|
|
return target.Invoke(cecilMethod.Name, ConvertTypeArguments(cecilMethod), methodArgs).WithAnnotation(cecilMethod); |
|
|
|
return target.Invoke(cecilMethod.Name, ConvertTypeArguments(cecilMethod), methodArgs).WithAnnotation(cecilMethod); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static Expression InlineAssembly(ILExpression byteCode, List<Ast.Expression> args) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// Output the operand of the unknown IL code as well
|
|
|
|
|
|
|
|
if (byteCode.Operand != null) { |
|
|
|
|
|
|
|
args.Insert(0, new IdentifierExpression(FormatByteCodeOperand(byteCode.Operand))); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return new IdentifierExpression(byteCode.Code.GetName()).Invoke(args); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static IEnumerable<AstType> ConvertTypeArguments(MethodReference cecilMethod) |
|
|
|
static IEnumerable<AstType> ConvertTypeArguments(MethodReference cecilMethod) |
|
|
|
{ |
|
|
|
{ |
|
|
|
GenericInstanceMethod g = cecilMethod as GenericInstanceMethod; |
|
|
|
GenericInstanceMethod g = cecilMethod as GenericInstanceMethod; |
|
|
|