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
+27 -5
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);
@@ -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"));
} }
} }