AS2: Better decompiling for..in, emptying stack before return

This commit is contained in:
Jindra Pet��k
2013-01-21 20:45:08 +01:00
parent 1fd0a15143
commit b1e1747b84
+34 -12
View File
@@ -30,6 +30,7 @@ import com.jpexs.asdec.action.swf7.ActionTry;
import com.jpexs.asdec.action.treemodel.*; import com.jpexs.asdec.action.treemodel.*;
import com.jpexs.asdec.action.treemodel.clauses.*; import com.jpexs.asdec.action.treemodel.clauses.*;
import com.jpexs.asdec.action.treemodel.operations.AndTreeItem; import com.jpexs.asdec.action.treemodel.operations.AndTreeItem;
import com.jpexs.asdec.action.treemodel.operations.EqTreeItem;
import com.jpexs.asdec.action.treemodel.operations.NotTreeItem; import com.jpexs.asdec.action.treemodel.operations.NotTreeItem;
import com.jpexs.asdec.action.treemodel.operations.OrTreeItem; import com.jpexs.asdec.action.treemodel.operations.OrTreeItem;
import com.jpexs.asdec.helpers.Helper; import com.jpexs.asdec.helpers.Helper;
@@ -683,7 +684,24 @@ public class Action {
List<TreeItem> doBody = actionsToTree(registerNames, unknownJumps, loopList, jumpsOrIfs, stack, constants, actions, ip, adr2ip(actions, jif.getAddress(), version) - 1, version); List<TreeItem> doBody = actionsToTree(registerNames, unknownJumps, loopList, jumpsOrIfs, stack, constants, actions, ip, adr2ip(actions, jif.getAddress(), version) - 1, version);
Loop currentLoop = new Loop(ip, adr2ip(actions, jif.getAddress(), version) + 1); Loop currentLoop = new Loop(ip, adr2ip(actions, jif.getAddress(), version) + 1);
loopList.add(currentLoop); loopList.add(currentLoop);
output.add(new DoWhileTreeItem(action, adr2ip(actions, jif.getAddress(), version) + 1, ip, doBody, stack.isEmpty() ? new DirectValueTreeItem(null, new Boolean(true), constants) : stack.pop())); TreeItem expression = stack.pop();
boolean isForInReturn = false;
//Before return in for..in clause, stack must be emptied
if (doBody.isEmpty()) {
TreeItem e = expression;
if (e instanceof NotTreeItem) {
e = ((NotTreeItem) e).value;
if (e instanceof EqTreeItem) {
e = ((EqTreeItem) e).leftSide;
if (e instanceof EnumerateTreeItem) {
isForInReturn = true;
}
}
}
}
if (!isForInReturn) {
output.add(new DoWhileTreeItem(action, adr2ip(actions, jif.getAddress(), version) + 1, ip, doBody, expression));
}
ip = adr2ip(actions, jif.getAddress(), version) + 1; ip = adr2ip(actions, jif.getAddress(), version) + 1;
continue loopip; continue loopip;
} }
@@ -746,8 +764,8 @@ public class Action {
List<TreeItem> onFalse = new ArrayList<TreeItem>(); List<TreeItem> onFalse = new ArrayList<TreeItem>();
boolean hasElse = false; boolean hasElse = false;
int jumpElseIp = 0; int jumpElseIp = 0;
Stack<TreeItem> falseStack = new Stack<TreeItem>(); Stack<TreeItem> falseStack = (Stack<TreeItem>) stack.clone();
Stack<TreeItem> trueStack = new Stack<TreeItem>(); Stack<TreeItem> trueStack = (Stack<TreeItem>) stack.clone();// new Stack<TreeItem>();
//if (!isWhile) { //if (!isWhile) {
if (actions.get(jumpIp - 1) instanceof ActionJump) { if (actions.get(jumpIp - 1) instanceof ActionJump) {
long ref = ((ActionJump) actions.get(jumpIp - 1)).getRef(version); long ref = ((ActionJump) actions.get(jumpIp - 1)).getRef(version);
@@ -784,8 +802,9 @@ public class Action {
try { try {
int trueStackSizeBefore = trueStack.size();
onTrue = actionsToTree(registerNames, unknownJumps, loopList, jumpsOrIfs, trueStack, constants, actions, ip + 1, jumpIp - 1 - (hasElse || isWhile || isForIn ? 1 : 0), version); onTrue = actionsToTree(registerNames, unknownJumps, loopList, jumpsOrIfs, trueStack, constants, actions, ip + 1, jumpIp - 1 - (hasElse || isWhile || isForIn ? 1 : 0), version);
if (onTrue.isEmpty() && trueStack.size() > 0) { if (onTrue.isEmpty() && trueStack.size() > trueStackSizeBefore) {
isTernar = true; isTernar = true;
} }
int next = (hasElse ? jumpElseIp : jumpIp); int next = (hasElse ? jumpElseIp : jumpIp);
@@ -834,9 +853,9 @@ public class Action {
} }
} }
if (isForIn) { if (isForIn) {
variableName=onTrue.remove(0); variableName = onTrue.remove(0);
if(variableName instanceof SetTypeTreeItem){ if (variableName instanceof SetTypeTreeItem) {
variableName=((SetTypeTreeItem)variableName).getObject(); variableName = ((SetTypeTreeItem) variableName).getObject();
} }
output.add(new ForInTreeItem(action, jumpIp, loopStart, variableName, inItem, onTrue)); output.add(new ForInTreeItem(action, jumpIp, loopStart, variableName, inItem, onTrue));
} else if (isFor) { } else if (isFor) {
@@ -856,8 +875,10 @@ public class Action {
} else if ((action instanceof ActionEnumerate2) || (action instanceof ActionEnumerate)) { } else if ((action instanceof ActionEnumerate2) || (action instanceof ActionEnumerate)) {
loopStart = ip + 1; loopStart = ip + 1;
isForIn = true; isForIn = true;
inItem = stack.pop();
ip += 4; ip += 4;
action.translate(stack, constants, output, registerNames);
EnumerateTreeItem en = (EnumerateTreeItem) stack.peek();
inItem = en.object;
continue; continue;
} else if (action instanceof ActionTry) { } else if (action instanceof ActionTry) {
ActionTry atry = (ActionTry) action; ActionTry atry = (ActionTry) action;
@@ -993,6 +1014,7 @@ public class Action {
try { try {
action.translate(stack, constants, output, registerNames); action.translate(stack, constants, output, registerNames);
} catch (EmptyStackException ese) { } catch (EmptyStackException ese) {
Logger.getLogger(Action.class.getName()).log(Level.SEVERE, null, ese);
output.add(new UnsupportedTreeItem(action, "Empty stack")); output.add(new UnsupportedTreeItem(action, "Empty stack"));
} }
} }
@@ -1098,10 +1120,10 @@ public class Action {
if (parts.get(pos + 1) instanceof SetMemberTreeItem) { if (parts.get(pos + 1) instanceof SetMemberTreeItem) {
if (((SetMemberTreeItem) parts.get(pos + 1)).value == ((StoreRegisterTreeItem) parts.get(pos)).value) { if (((SetMemberTreeItem) parts.get(pos + 1)).value == ((StoreRegisterTreeItem) parts.get(pos)).value) {
instanceReg=((StoreRegisterTreeItem) parts.get(pos)).register.number; instanceReg = ((StoreRegisterTreeItem) parts.get(pos)).register.number;
NewMethodTreeItem nm=(NewMethodTreeItem)((StoreRegisterTreeItem) parts.get(pos)).value; NewMethodTreeItem nm = (NewMethodTreeItem) ((StoreRegisterTreeItem) parts.get(pos)).value;
GetMemberTreeItem gm=new GetMemberTreeItem(null,nm.scriptObject,nm.methodName); GetMemberTreeItem gm = new GetMemberTreeItem(null, nm.scriptObject, nm.methodName);
extendsOp=gm; extendsOp = gm;
} else { } else {
ok = false; ok = false;
break; break;