@ -180,13 +180,9 @@ namespace Decompiler
@@ -180,13 +180,9 @@ namespace Decompiler
List < Ast . Expression > TransformExpressionArguments ( ByteCodeExpression expr )
{
List < Ast . Expression > args = new List < Ast . Expression > ( ) ;
foreach ( CilStackSlot stackSlot in expr . StackBefore . PeekCount ( expr . PopCount ) ) {
string name = string . Format ( "expr{0:X2}" , stackSlot . AllocadedBy . Offset ) ;
args . Add ( new Ast . IdentifierExpression ( name ) ) ;
}
// Args generated by nested expressions (which must be closed)
foreach ( ByteCodeExpression nestedExpr in expr . Last Arguments) {
args . Add ( ( Ast . Expression ) TransformExpression ( nestedExpr ) ) ;
foreach ( ByteCodeExpression arg in expr . Arguments ) {
args . Add ( ( Ast . Expression ) TransformExpression ( arg ) ) ;
}
return args ;
}
@ -194,22 +190,14 @@ namespace Decompiler
@@ -194,22 +190,14 @@ namespace Decompiler
object TransformExpression ( ByteCodeExpression expr )
{
List < Ast . Expression > args = TransformExpressionArguments ( expr ) ;
return TransformByteCode ( methodDef , expr . LastByteCode , args ) ;
return TransformByteCode ( methodDef , expr , args ) ;
}
Ast . Statement TransformExpressionToStatement ( ByteCodeExpression expr )
{
object codeExpr = TransformExpression ( expr ) ;
if ( codeExpr is Ast . Expression ) {
if ( expr . PushCount > = 1 ) {
string type = expr . LastByteCode . Type . FullName ;
string name = string . Format ( "expr{0:X2}" , expr . LastByteCode . Offset ) ;
Ast . LocalVariableDeclaration astLocal = new Ast . LocalVariableDeclaration ( new Ast . TypeReference ( type . ToString ( ) ) ) ;
astLocal . Variables . Add ( new Ast . VariableDeclaration ( name , ( Ast . Expression ) codeExpr ) ) ;
return astLocal ;
} else {
return new Ast . ExpressionStatement ( ( Ast . Expression ) codeExpr ) ;
}
return new Ast . ExpressionStatement ( ( Ast . Expression ) codeExpr ) ;
} else if ( codeExpr is Ast . Statement ) {
return ( Ast . Statement ) codeExpr ;
} else {
@ -234,7 +222,7 @@ namespace Decompiler
@@ -234,7 +222,7 @@ namespace Decompiler
List < Ast . Expression > args = TransformExpressionArguments ( ( ( SimpleBranch ) branch ) . BasicBlock . Body [ 0 ] ) ;
Ast . Expression arg1 = args . Count > = 1 ? args [ 0 ] : null ;
Ast . Expression arg2 = args . Count > = 2 ? args [ 1 ] : null ;
switch ( ( ( SimpleBranch ) branch ) . BasicBlock . Body [ 0 ] . LastByteCode . OpCode . Code ) {
switch ( ( ( SimpleBranch ) branch ) . BasicBlock . Body [ 0 ] . OpCode . Code ) {
case Code . Brfalse : return new Ast . UnaryOperatorExpression ( arg1 , UnaryOperatorType . Not ) ;
case Code . Brtrue : return arg1 ;
case Code . Beq : return new Ast . BinaryOperatorExpression ( arg1 , BinaryOperatorType . Equality , arg2 ) ;
@ -284,7 +272,7 @@ namespace Decompiler
@@ -284,7 +272,7 @@ namespace Decompiler
}
}
static object TransformByteCode ( MethodDefinition methodDef , ByteCode byteCode , List < Ast . Expression > args )
static object TransformByteCode ( MethodDefinition methodDef , ByteCodeExpression byteCode , List < Ast . Expression > args )
{
try {
Ast . INode ret = TransformByteCode_Internal ( methodDef , byteCode , args ) ;
@ -296,14 +284,16 @@ namespace Decompiler
@@ -296,14 +284,16 @@ namespace Decompiler
} catch ( NotImplementedException ) {
// Output the operand of the unknown IL code as well
if ( byteCode . Operand ! = null ) {
args . Insert ( 0 , new IdentifierExpression ( b yteCode. FormatedOperand ) ) ;
args . Insert ( 0 , new IdentifierExpression ( B yteCode. FormatByt eCo de Operand ( byteCode . Operand ) ) ) ;
}
return new Ast . InvocationExpression ( new IdentifierExpression ( "IL__" + byteCode . OpCode . Name ) , args ) ;
}
}
static Ast . INode TransformByteCode_Internal ( MethodDefinition methodDef , ByteCode byteCode , List < Ast . Expression > args )
static Ast . INode TransformByteCode_Internal ( MethodDefinition methodDef , ByteCodeExpression byteCode , List < Ast . Expression > args )
{
// throw new NotImplementedException();
OpCode opCode = byteCode . OpCode ;
object operand = byteCode . Operand ;
Ast . TypeReference operandAsTypeRef = operand is Cecil . TypeReference ? new Ast . TypeReference ( ( ( Cecil . TypeReference ) operand ) . FullName ) : null ;
@ -313,8 +303,8 @@ namespace Decompiler
@@ -313,8 +303,8 @@ namespace Decompiler
Ast . Expression arg3 = args . Count > = 3 ? args [ 2 ] : null ;
Ast . Statement branchCommand = null ;
if ( operand is ByteCode ) {
branchCommand = new Ast . GotoStatement ( ( ( ByteCode ) operand ) . Expression . BasicBlock . Label ) ;
if ( byteCode . BranchTarget ! = null ) {
branchCommand = new Ast . GotoStatement ( byteCode . BranchTarget . BasicBlock . Label ) ;
}
switch ( opCode . Code ) {
@ -603,13 +593,17 @@ namespace Decompiler
@@ -603,13 +593,17 @@ namespace Decompiler
VariableDefinition locVar = ( VariableDefinition ) operand ;
string name = locVar . Name ;
arg1 = Convert ( arg1 , locVar . VariableType ) ;
if ( localVarDefined [ name ] ) {
return new Ast . AssignmentExpression ( new Ast . IdentifierExpression ( name ) , AssignmentOperatorType . Assign , arg1 ) ;
if ( localVarDefined . ContainsKey ( name ) ) {
if ( localVarDefined [ name ] ) {
return new Ast . AssignmentExpression ( new Ast . IdentifierExpression ( name ) , AssignmentOperatorType . Assign , arg1 ) ;
} else {
Ast . LocalVariableDeclaration astLocalVar = new Ast . LocalVariableDeclaration ( new Ast . VariableDeclaration ( name , arg1 ) ) ;
astLocalVar . TypeReference = new Ast . TypeReference ( localVarTypes [ name ] . FullName ) ;
localVarDefined [ name ] = true ;
return astLocalVar ;
}
} else {
Ast . LocalVariableDeclaration astLocalVar = new Ast . LocalVariableDeclaration ( new Ast . VariableDeclaration ( name , arg1 ) ) ;
astLocalVar . TypeReference = new Ast . TypeReference ( localVarTypes [ name ] . FullName ) ;
localVarDefined [ name ] = true ;
return astLocalVar ;
return new Ast . AssignmentExpression ( new Ast . IdentifierExpression ( name ) , AssignmentOperatorType . Assign , arg1 ) ;
}
}
case Code . Stobj : throw new NotImplementedException ( ) ;