AS3: post/pre increment/decrement decompilation, declaration of local registers

This commit is contained in:
Jindra Pet��k
2011-07-12 20:04:28 +02:00
parent 6106a6e6ca
commit dcfffa711d
11 changed files with 141 additions and 22 deletions
+105 -13
View File
@@ -650,6 +650,41 @@ public class AVM2Code {
private int toSourceCount = 0; private int toSourceCount = 0;
private int ipOfType(int from,boolean up,Class search,Class skipped,int start,int end)
{
if(up)
{
System.out.println("Searching up from "+from);
for(int i=from;i>=start;i--){
if(search.isInstance(code.get(i).definition)){
return i;
}else if((skipped!=null)&&skipped.isInstance(code.get(i).definition))
{
//skipped
}else{
return -1;
}
}
}else
{
System.out.println("Searching down from "+from);
for(int i=from;i<=end;i++){
if(search.isInstance(code.get(i).definition)){
return i;
}else if((skipped!=null)&&skipped.isInstance(code.get(i).definition))
{
//skipped
}else{
return -1;
}
}
}
System.out.println("NotfoundAtAll "+search);
return -1;
}
public HashMap<Integer,String> getLocalRegNamesFromDebug(ABC abc){ public HashMap<Integer,String> getLocalRegNamesFromDebug(ABC abc){
HashMap<Integer,String> localRegNames= new HashMap<Integer,String>(); HashMap<Integer,String> localRegNames= new HashMap<Integer,String>();
for(AVM2Instruction ins:code) for(AVM2Instruction ins:code)
@@ -663,6 +698,19 @@ public HashMap<Integer,String> getLocalRegNamesFromDebug(ABC abc){
return localRegNames; return localRegNames;
} }
private void clearKilledAssigments(List<TreeItem> output){
for(int i=0;i<output.size();i++){
if(output.get(i) instanceof SetLocalTreeItem)
{
if(isKilled(((SetLocalTreeItem)output.get(i)).regIndex, 0, code.size()-1))
{
output.remove(i);
i--;
}
}
}
}
private ConvertOutput toSource(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, Stack<TreeItem> scopeStack, ABC abc, ConstantPool constants, MethodInfo method_info[], MethodBody body, int start, int end) throws ConvertException { private ConvertOutput toSource(boolean isStatic, int classIndex, java.util.HashMap<Integer, TreeItem> localRegs, Stack<TreeItem> stack, Stack<TreeItem> scopeStack, ABC abc, ConstantPool constants, MethodInfo method_info[], MethodBody body, int start, int end) throws ConvertException {
boolean debugMode = false; boolean debugMode = false;
if (debugMode) if (debugMode)
@@ -1082,11 +1130,14 @@ public HashMap<Integer,String> getLocalRegNamesFromDebug(ABC abc){
//stack.add("(" + stack.pop() + ")||"); //stack.add("(" + stack.pop() + ")||");
isAnd = false; isAnd = false;
} else if ((insAfter.definition instanceof IncrementIIns) || ((insAfter.definition instanceof IncrementIns))) { } else if ((insAfter.definition instanceof IncrementIIns) || ((insAfter.definition instanceof IncrementIns))) {
if (((ip - 1 >= start) && (ip + 2 <= end)) && ((code.get(ip + 2).definition instanceof SetLocalTypeIns) && (code.get(ip - 1).definition instanceof GetLocalTypeIns))) { int np=-1;
stack.add(new PostIncrementTreeItem(insAfter, stack.pop())); if(((np=ipOfType(ip+2, false, SetLocalTypeIns.class, CoerceOrConvertTypeIns.class, start, end))>-1)
ip += 3; &&(ipOfType(ip-1, true, GetLocalTypeIns.class, CoerceOrConvertTypeIns.class, start, end)>-1))
addr = pos2adr(ip); {
break; stack.add(new PostIncrementTreeItem(insAfter, stack.pop()));
ip = np+1;
addr = pos2adr(ip);
break;
} }
if (((ip - 1 >= start) && (ip + 2 <= end)) if (((ip - 1 >= start) && (ip + 2 <= end))
&& (code.get(ip + 2).definition instanceof SetLocalTypeIns) && (code.get(ip + 2).definition instanceof SetLocalTypeIns)
@@ -1114,11 +1165,14 @@ public HashMap<Integer,String> getLocalRegNamesFromDebug(ABC abc){
addr = pos2adr(ip); addr = pos2adr(ip);
break; break;
} else if ((insAfter.definition instanceof DecrementIIns) || ((insAfter.definition instanceof DecrementIns))) { } else if ((insAfter.definition instanceof DecrementIIns) || ((insAfter.definition instanceof DecrementIns))) {
if (((ip - 1 >= start) && (ip + 2 <= end)) && ((code.get(ip + 2).definition instanceof SetLocalTypeIns) && (code.get(ip - 1).definition instanceof GetLocalTypeIns))) { int np=-1;
stack.add(new PostDecrementTreeItem(insAfter, stack.pop())); if(((np=ipOfType(ip+2, false, SetLocalTypeIns.class, CoerceOrConvertTypeIns.class, start, end))>-1)
ip += 3; &&(ipOfType(ip-1, true, GetLocalTypeIns.class, CoerceOrConvertTypeIns.class, start, end)>-1))
addr = pos2adr(ip); {
break; stack.add(new PostDecrementTreeItem(insAfter, stack.pop()));
ip = np+1;
addr = pos2adr(ip);
break;
} }
if (((ip - 1 >= start) && (ip + 2 <= end)) if (((ip - 1 >= start) && (ip + 2 <= end))
&& (code.get(ip + 2).definition instanceof SetLocalTypeIns) && (code.get(ip + 2).definition instanceof SetLocalTypeIns)
@@ -1146,7 +1200,7 @@ public HashMap<Integer,String> getLocalRegNamesFromDebug(ABC abc){
addr = pos2adr(ip); addr = pos2adr(ip);
break; break;
} else if ((insBefore.definition instanceof IncrementIIns) || ((insBefore.definition instanceof IncrementIns))) { } else if ((insBefore.definition instanceof IncrementIIns) || ((insBefore.definition instanceof IncrementIns))) {
if (((ip - 2 >= start) && (ip + 2 <= end)) && (code.get(ip + 1).definition instanceof ConvertIIns) && (code.get(ip + 2).definition instanceof SetLocalTypeIns) && (code.get(ip - 2).definition instanceof GetLocalTypeIns)) { if (((ip - 2 >= start) && (ip + 2 <= end)) && (code.get(ip + 1).definition instanceof CoerceOrConvertTypeIns) && (code.get(ip + 2).definition instanceof SetLocalTypeIns) && (code.get(ip - 2).definition instanceof GetLocalTypeIns)) {
stack.pop(); stack.pop();
int regId = ((SetLocalTypeIns) code.get(ip + 2).definition).getRegisterId(code.get(ip + 2)); int regId = ((SetLocalTypeIns) code.get(ip + 2).definition).getRegisterId(code.get(ip + 2));
stack.add(new PreIncrementTreeItem(insBefore, new LocalRegTreeItem(code.get(ip + 2), regId, localRegs.get(regId)))); stack.add(new PreIncrementTreeItem(insBefore, new LocalRegTreeItem(code.get(ip + 2), regId, localRegs.get(regId))));
@@ -1183,7 +1237,7 @@ public HashMap<Integer,String> getLocalRegNamesFromDebug(ABC abc){
addr = pos2adr(ip); addr = pos2adr(ip);
break; break;
} else if ((insBefore.definition instanceof DecrementIIns) || ((insBefore.definition instanceof DecrementIns))) { } else if ((insBefore.definition instanceof DecrementIIns) || ((insBefore.definition instanceof DecrementIns))) {
if (((ip - 2 >= start) && (ip + 2 <= end)) && (code.get(ip + 1).definition instanceof ConvertIIns) && (code.get(ip + 2).definition instanceof SetLocalTypeIns) && (code.get(ip - 2).definition instanceof GetLocalTypeIns)) { if (((ip - 2 >= start) && (ip + 2 <= end)) && (code.get(ip + 1).definition instanceof CoerceOrConvertTypeIns) && (code.get(ip + 2).definition instanceof SetLocalTypeIns) && (code.get(ip - 2).definition instanceof GetLocalTypeIns)) {
stack.pop(); stack.pop();
int regId = ((SetLocalTypeIns) code.get(ip + 2).definition).getRegisterId(code.get(ip + 2)); int regId = ((SetLocalTypeIns) code.get(ip + 2).definition).getRegisterId(code.get(ip + 2));
stack.add(new PreDecrementTreeItem(insBefore, new LocalRegTreeItem(code.get(ip + 2), regId, localRegs.get(regId)))); stack.add(new PreDecrementTreeItem(insBefore, new LocalRegTreeItem(code.get(ip + 2), regId, localRegs.get(regId))));
@@ -1322,7 +1376,7 @@ public HashMap<Integer,String> getLocalRegNamesFromDebug(ABC abc){
} }
if (debugMode) if (debugMode)
System.out.println("CLOSE SubSource:" + start + "-" + end + " " + code.get(start).toString() + " to " + code.get(end).toString()); System.out.println("CLOSE SubSource:" + start + "-" + end + " " + code.get(start).toString() + " to " + code.get(end).toString());
clearKilledAssigments(output);
return new ConvertOutput(stack, output); return new ConvertOutput(stack, output);
} catch (ConvertException cex) { } catch (ConvertException cex) {
throw cex; throw cex;
@@ -1360,6 +1414,27 @@ public HashMap<Integer,String> getLocalRegNamesFromDebug(ABC abc){
} }
} }
public int getRegisterCount(){
int maxRegister=-1;
for(AVM2Instruction ins:code)
{
int regId=-1;
if(ins.definition instanceof SetLocalTypeIns)
{
regId=((SetLocalTypeIns)ins.definition).getRegisterId(ins);
}
if(ins.definition instanceof GetLocalTypeIns)
{
regId=((GetLocalTypeIns)ins.definition).getRegisterId(ins);
}
if(regId>maxRegister)
{
maxRegister=regId;
}
}
return maxRegister+1;
}
public String toSource(boolean isStatic, int classIndex, ABC abc, ConstantPool constants, MethodInfo method_info[], MethodBody body, boolean hilighted) { public String toSource(boolean isStatic, int classIndex, ABC abc, ConstantPool constants, MethodInfo method_info[], MethodBody body, boolean hilighted) {
toSourceCount = 0; toSourceCount = 0;
loopList = new ArrayList<Loop>(); loopList = new ArrayList<Loop>();
@@ -1378,12 +1453,29 @@ public HashMap<Integer,String> getLocalRegNamesFromDebug(ABC abc){
return s; return s;
} }
String parts[] = s.split("\r\n"); String parts[] = s.split("\r\n");
String sub = ""; String sub = "";
int level = 0; int level = 0;
for (int t = 0; t < body.traits.traits.length; t++) { for (int t = 0; t < body.traits.traits.length; t++) {
sub += body.traits.traits[t].convert(constants, method_info,abc) + ";\r\n"; sub += body.traits.traits[t].convert(constants, method_info,abc) + ";\r\n";
} }
int regCount=getRegisterCount();
int paramCount=0;
if(body.method_info!=-1)
{
MethodInfo mi=method_info[body.method_info];
paramCount=mi.param_types.length;
if(mi.flagNeed_rest()){
paramCount++;
}
}
for(int i=paramCount+1;i<regCount;i++)
{
if(!isKilled(i, 0, code.size()-1)){
sub+="var "+InstructionDefinition.localRegName(i)+";\r\n";
}
}
try { try {
Stack<String> loopStack = new Stack<String>(); Stack<String> loopStack = new Stack<String>();
for (int p = 0; p < parts.length; p++) { for (int p = 0; p < parts.length; p++) {
@@ -30,7 +30,7 @@ import java.util.List;
import java.util.Stack; import java.util.Stack;
public class CoerceAIns extends InstructionDefinition { public class CoerceAIns extends InstructionDefinition implements CoerceOrConvertTypeIns{
public CoerceAIns() { public CoerceAIns() {
super(0x82, "coerce_a", new int[]{}); super(0x82, "coerce_a", new int[]{});
@@ -31,7 +31,7 @@ import java.util.List;
import java.util.Stack; import java.util.Stack;
public class CoerceIns extends InstructionDefinition { public class CoerceIns extends InstructionDefinition implements CoerceOrConvertTypeIns {
public CoerceIns() { public CoerceIns() {
super(0x80, "coerce", new int[]{AVM2Code.DAT_MULTINAME_INDEX}); super(0x80, "coerce", new int[]{AVM2Code.DAT_MULTINAME_INDEX});
@@ -0,0 +1,27 @@
/*
* Copyright (C) 2011 JPEXS
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package com.jpexs.asdec.abc.avm2.instructions.types;
/**
*
* @author JPEXS
*/
public interface CoerceOrConvertTypeIns {
}
@@ -30,7 +30,7 @@ import java.util.List;
import java.util.Stack; import java.util.Stack;
public class CoerceSIns extends InstructionDefinition { public class CoerceSIns extends InstructionDefinition implements CoerceOrConvertTypeIns {
public CoerceSIns() { public CoerceSIns() {
super(0x85, "coerce_s", new int[]{}); super(0x85, "coerce_s", new int[]{});
@@ -30,7 +30,7 @@ import java.util.List;
import java.util.Stack; import java.util.Stack;
public class ConvertBIns extends InstructionDefinition { public class ConvertBIns extends InstructionDefinition implements CoerceOrConvertTypeIns {
public ConvertBIns() { public ConvertBIns() {
super(0x76, "convert_b", new int[]{}); super(0x76, "convert_b", new int[]{});
@@ -30,7 +30,7 @@ import java.util.List;
import java.util.Stack; import java.util.Stack;
public class ConvertDIns extends InstructionDefinition { public class ConvertDIns extends InstructionDefinition implements CoerceOrConvertTypeIns {
public ConvertDIns() { public ConvertDIns() {
super(0x75, "convert_d", new int[]{}); super(0x75, "convert_d", new int[]{});
@@ -30,7 +30,7 @@ import java.util.List;
import java.util.Stack; import java.util.Stack;
public class ConvertIIns extends InstructionDefinition { public class ConvertIIns extends InstructionDefinition implements CoerceOrConvertTypeIns {
public ConvertIIns() { public ConvertIIns() {
super(0x73, "convert_i", new int[]{}); super(0x73, "convert_i", new int[]{});
@@ -30,7 +30,7 @@ import java.util.List;
import java.util.Stack; import java.util.Stack;
public class ConvertOIns extends InstructionDefinition { public class ConvertOIns extends InstructionDefinition implements CoerceOrConvertTypeIns {
public ConvertOIns() { public ConvertOIns() {
super(0x77, "convert_o", new int[]{}); super(0x77, "convert_o", new int[]{});
@@ -30,7 +30,7 @@ import java.util.List;
import java.util.Stack; import java.util.Stack;
public class ConvertSIns extends InstructionDefinition { public class ConvertSIns extends InstructionDefinition implements CoerceOrConvertTypeIns {
public ConvertSIns() { public ConvertSIns() {
super(0x70, "convert_s", new int[]{}); super(0x70, "convert_s", new int[]{});
@@ -30,7 +30,7 @@ import java.util.List;
import java.util.Stack; import java.util.Stack;
public class ConvertUIns extends InstructionDefinition { public class ConvertUIns extends InstructionDefinition implements CoerceOrConvertTypeIns {
public ConvertUIns() { public ConvertUIns() {
super(0x74, "convert_u", new int[]{}); super(0x74, "convert_u", new int[]{});