mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-09-25 08:41:17 +00:00
AS2:Fixed Ifs, Added For..in, better Functions
This commit is contained in:
@@ -6,6 +6,7 @@ import com.jpexs.asdec.action.parser.ParseException;
|
||||
import com.jpexs.asdec.action.parser.ParsedSymbol;
|
||||
import com.jpexs.asdec.action.swf4.*;
|
||||
import com.jpexs.asdec.action.swf5.*;
|
||||
import com.jpexs.asdec.action.swf6.ActionEnumerate2;
|
||||
import com.jpexs.asdec.action.swf6.ActionStrictEquals;
|
||||
import com.jpexs.asdec.action.swf7.ActionDefineFunction2;
|
||||
import com.jpexs.asdec.action.swf7.ActionTry;
|
||||
@@ -21,6 +22,7 @@ import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EmptyStackException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
@@ -379,8 +381,9 @@ public class Action {
|
||||
* @param stack Stack
|
||||
* @param constants Constant pool
|
||||
* @param output Output
|
||||
* @param regNames Register names
|
||||
*/
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output) {
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer,String> regNames) {
|
||||
|
||||
}
|
||||
|
||||
@@ -541,24 +544,25 @@ public class Action {
|
||||
* @return String with Source code
|
||||
*/
|
||||
public static String actionsToSource(List<Action> actions, int version) {
|
||||
List<TreeItem> tree = actionsToTree(actions, version);
|
||||
List<TreeItem> tree = actionsToTree(new HashMap<Integer,String>(),actions, version);
|
||||
return treeToString(tree);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts list of actions to List of treeItems
|
||||
*
|
||||
* @param regNames Register names
|
||||
* @param actions List of actions
|
||||
* @param version SWF version
|
||||
* @return List of treeItems
|
||||
*/
|
||||
public static List<TreeItem> actionsToTree(List<Action> actions, int version) {
|
||||
return actionsToTree(new ArrayList<Long>(), new ArrayList<Loop>(), getActionsAllIfsOrJumps(actions), new Stack<TreeItem>(), new ConstantPool(), actions, 0, actions.size() - 1, version);
|
||||
public static List<TreeItem> actionsToTree(HashMap<Integer,String> regNames,List<Action> actions, int version) {
|
||||
return actionsToTree(regNames,new ArrayList<Long>(), new ArrayList<Loop>(), getActionsAllIfsOrJumps(actions), new Stack<TreeItem>(), new ConstantPool(), actions, 0, actions.size() - 1, version);
|
||||
}
|
||||
|
||||
private static Stack<TreeItem> actionsToStackTree(List<Action> jumpsOrIfs, List<Action> actions, ConstantPool constants, int start, int end, int version) {
|
||||
private static Stack<TreeItem> actionsToStackTree(HashMap<Integer,String> regNames,List<Action> jumpsOrIfs, List<Action> actions, ConstantPool constants, int start, int end, int version) {
|
||||
Stack<TreeItem> ret = new Stack<TreeItem>();
|
||||
actionsToTree(new ArrayList<Long>(), new ArrayList<Loop>(), jumpsOrIfs, ret, constants, actions, start, end, version);
|
||||
actionsToTree(regNames,new ArrayList<Long>(), new ArrayList<Loop>(), jumpsOrIfs, ret, constants, actions, start, end, version);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -576,10 +580,12 @@ public class Action {
|
||||
}
|
||||
}
|
||||
|
||||
private static List<TreeItem> actionsToTree(List<Long> unknownJumps, List<Loop> loopList, List<Action> jumpsOrIfs, Stack<TreeItem> stack, ConstantPool constants, List<Action> actions, int start, int end, int version) {
|
||||
private static List<TreeItem> actionsToTree(HashMap<Integer,String> registerNames,List<Long> unknownJumps, List<Loop> loopList, List<Action> jumpsOrIfs, Stack<TreeItem> stack, ConstantPool constants, List<Action> actions, int start, int end, int version) {
|
||||
List<TreeItem> output = new ArrayList<TreeItem>();
|
||||
int ip = start;
|
||||
boolean isWhile = false;
|
||||
boolean isForIn = false;
|
||||
TreeItem inItem=null;
|
||||
int loopStart = 0;
|
||||
loopip:
|
||||
while (ip <= end + 1) {
|
||||
@@ -624,7 +630,7 @@ public class Action {
|
||||
if (((ActionIf) jif).getRef(version) == addr) {
|
||||
if (jif.getAddress() > addr) {
|
||||
jumpsOrIfs.remove(j);
|
||||
List<TreeItem> doBody = actionsToTree(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);
|
||||
loopList.add(currentLoop);
|
||||
output.add(new DoWhileTreeItem(action, adr2ip(actions, jif.getAddress(), version) + 1, ip, doBody, stack.pop()));
|
||||
@@ -678,11 +684,14 @@ public class Action {
|
||||
output.add(new UnsupportedTreeItem(action, "ActionIf to jump back"));
|
||||
break;
|
||||
}
|
||||
TreeItem expression = stack.pop();
|
||||
if (expression instanceof NotTreeItem) {
|
||||
expression = ((NotTreeItem) expression).value;
|
||||
} else {
|
||||
expression = new NotTreeItem(action, expression);
|
||||
TreeItem expression = null;
|
||||
if(!isForIn){
|
||||
expression=stack.pop();
|
||||
if (expression instanceof NotTreeItem) {
|
||||
expression = ((NotTreeItem) expression).value;
|
||||
} else {
|
||||
expression = new NotTreeItem(action, expression);
|
||||
}
|
||||
}
|
||||
List<TreeItem> onTrue = new ArrayList<TreeItem>();
|
||||
List<TreeItem> onFalse = new ArrayList<TreeItem>();
|
||||
@@ -697,21 +706,36 @@ public class Action {
|
||||
if ((refIp > jumpIp) && (refIp <= end + 1)) {
|
||||
hasElse = true;
|
||||
jumpElseIp = adr2ip(actions, ((ActionJump) actions.get(jumpIp - 1)).getRef(version), version);
|
||||
onFalse = actionsToTree(unknownJumps, loopList, jumpsOrIfs, falseStack, constants, actions, jumpIp, jumpElseIp - 1, version);
|
||||
onFalse = actionsToTree(registerNames,unknownJumps, loopList, jumpsOrIfs, falseStack, constants, actions, jumpIp, jumpElseIp - 1, version);
|
||||
}
|
||||
}
|
||||
//}
|
||||
Loop currentLoop = null;
|
||||
if (isWhile) {
|
||||
if (isWhile||isForIn) {
|
||||
currentLoop = new Loop(loopStart, jumpIp);
|
||||
loopList.add(currentLoop);
|
||||
}
|
||||
boolean isFor = false;
|
||||
boolean isTernar = false;
|
||||
List<TreeItem> finalExpression = null;
|
||||
|
||||
TreeItem variableName=null;
|
||||
if(isForIn){
|
||||
for(int t=ip+1;t<=end;t++){
|
||||
Action actionSV=actions.get(t);
|
||||
actionSV.translate(stack, constants, output, registerNames);
|
||||
if(actionSV instanceof ActionSetVariable){
|
||||
SetVariableTreeItem svt=(SetVariableTreeItem)output.remove(output.size()-1);
|
||||
variableName=svt.name;
|
||||
ip=t;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
onTrue = actionsToTree(unknownJumps, loopList, jumpsOrIfs, trueStack, constants, actions, ip + 1, jumpIp - 1 - (hasElse || isWhile ? 1 : 0), version);
|
||||
onTrue = actionsToTree(registerNames,unknownJumps, loopList, jumpsOrIfs, trueStack, constants, actions, ip + 1, jumpIp - 1 - (hasElse || isWhile || isForIn ? 1 : 0), version);
|
||||
if (onTrue.size() == 0 && trueStack.size() > 0) {
|
||||
isTernar = true;
|
||||
}
|
||||
@@ -740,13 +764,15 @@ public class Action {
|
||||
}
|
||||
}
|
||||
}
|
||||
finalExpression = actionsToTree(unknownJumps, loopList, jumpsOrIfs, stack, constants, actions, adr2ip(actions, uje.addr, version), jumpIp - 2, version);
|
||||
finalExpression = actionsToTree(registerNames,unknownJumps, loopList, jumpsOrIfs, stack, constants, actions, adr2ip(actions, uje.addr, version), jumpIp - 2, version);
|
||||
isFor = true;
|
||||
} else {
|
||||
//throw new ConvertException("Unknown pattern: jump to nowhere", ip);
|
||||
}
|
||||
}
|
||||
if (isFor) {
|
||||
if(isForIn){
|
||||
output.add(new ForInTreeItem(action,jumpIp, loopStart,variableName,inItem,onTrue));
|
||||
}else if (isFor) {
|
||||
output.add(new ForTreeItem(action, currentLoop.loopBreak, currentLoop.loopContinue, new ArrayList<TreeItem>(), expression, finalExpression, onTrue));
|
||||
} else if (isTernar) {
|
||||
stack.push(new TernarOpTreeItem(action, expression, trueStack.pop(), falseStack.pop()));
|
||||
@@ -758,10 +784,17 @@ public class Action {
|
||||
ip = (hasElse ? jumpElseIp : jumpIp);
|
||||
isWhile = false;
|
||||
isFor = false;
|
||||
isForIn = false;
|
||||
continue;
|
||||
} else if (action instanceof ActionTry) {
|
||||
} else if(action instanceof ActionEnumerate2){
|
||||
loopStart=ip+1;
|
||||
isForIn=true;
|
||||
inItem=stack.pop();
|
||||
ip+=4;
|
||||
continue;
|
||||
}else if (action instanceof ActionTry) {
|
||||
ActionTry atry = (ActionTry) action;
|
||||
List<TreeItem> tryCommands = actionsToTree(unknownJumps, loopList, jumpsOrIfs, new Stack<TreeItem>(), constants, atry.tryBody, 0, atry.tryBody.size() - 1, version);
|
||||
List<TreeItem> tryCommands = actionsToTree(registerNames,unknownJumps, loopList, jumpsOrIfs, new Stack<TreeItem>(), constants, atry.tryBody, 0, atry.tryBody.size() - 1, version);
|
||||
TreeItem catchName;
|
||||
if (atry.catchInRegisterFlag) {
|
||||
catchName = new DirectValueTreeItem(atry, new RegisterNumber(atry.catchRegister), constants);
|
||||
@@ -771,25 +804,39 @@ public class Action {
|
||||
List<TreeItem> catchExceptions = new ArrayList<TreeItem>();
|
||||
catchExceptions.add(catchName);
|
||||
List<List<TreeItem>> catchCommands = new ArrayList<List<TreeItem>>();
|
||||
catchCommands.add(actionsToTree(unknownJumps, loopList, jumpsOrIfs, new Stack<TreeItem>(), constants, atry.catchBody, 0, atry.catchBody.size() - 1, version));
|
||||
List<TreeItem> finallyCommands = actionsToTree(unknownJumps, loopList, jumpsOrIfs, new Stack<TreeItem>(), constants, atry.finallyBody, 0, atry.finallyBody.size() - 1, version);
|
||||
catchCommands.add(actionsToTree(registerNames,unknownJumps, loopList, jumpsOrIfs, new Stack<TreeItem>(), constants, atry.catchBody, 0, atry.catchBody.size() - 1, version));
|
||||
List<TreeItem> finallyCommands = actionsToTree(registerNames,unknownJumps, loopList, jumpsOrIfs, new Stack<TreeItem>(), constants, atry.finallyBody, 0, atry.finallyBody.size() - 1, version);
|
||||
output.add(new TryTreeItem(tryCommands, catchExceptions, catchCommands, finallyCommands));
|
||||
} else if (action instanceof ActionWith) {
|
||||
ActionWith awith = (ActionWith) action;
|
||||
List<TreeItem> withCommands = actionsToTree(unknownJumps, loopList, jumpsOrIfs, new Stack<TreeItem>(), constants, awith.actions, 0, awith.actions.size() - 1, version);
|
||||
List<TreeItem> withCommands = actionsToTree(registerNames,unknownJumps, loopList, jumpsOrIfs, new Stack<TreeItem>(), constants, awith.actions, 0, awith.actions.size() - 1, version);
|
||||
output.add(new WithTreeItem(action, stack.pop(), withCommands));
|
||||
} else if (action instanceof ActionDefineFunction) {
|
||||
FunctionTreeItem fti = new FunctionTreeItem(action, actionsToTree(unknownJumps, loopList, jumpsOrIfs, new Stack<TreeItem>(), constants, ((ActionDefineFunction) action).code, 0, ((ActionDefineFunction) action).code.size() - 1, version), constants);
|
||||
FunctionTreeItem fti = new FunctionTreeItem(action,((ActionDefineFunction)action).functionName,((ActionDefineFunction)action).paramNames, actionsToTree(registerNames,unknownJumps, loopList, jumpsOrIfs, new Stack<TreeItem>(), constants, ((ActionDefineFunction) action).code, 0, ((ActionDefineFunction) action).code.size() - 1, version), constants);
|
||||
stack.push(fti);
|
||||
} else if (action instanceof ActionDefineFunction2) {
|
||||
FunctionTreeItem fti = new FunctionTreeItem(action, actionsToTree(unknownJumps, loopList, jumpsOrIfs, new Stack<TreeItem>(), constants, ((ActionDefineFunction2) action).code, 0, ((ActionDefineFunction2) action).code.size() - 1, version), constants);
|
||||
HashMap<Integer,String> funcRegNames=(HashMap<Integer,String>)registerNames.clone();
|
||||
for(int f=0;f<((ActionDefineFunction2)action).paramNames.size();f++){
|
||||
int reg=((ActionDefineFunction2)action).paramRegisters.get(f);
|
||||
if(reg!=0)
|
||||
funcRegNames.put(reg, ((ActionDefineFunction2)action).paramNames.get(f));
|
||||
}
|
||||
int pos=1;
|
||||
if(((ActionDefineFunction2)action).preloadThisFlag) {funcRegNames.put(pos, "this");pos++;}
|
||||
if(((ActionDefineFunction2)action).preloadArgumentsFlag) {funcRegNames.put(pos, "arguments");pos++;}
|
||||
if(((ActionDefineFunction2)action).preloadSuperFlag) {funcRegNames.put(pos, "super");pos++;}
|
||||
if(((ActionDefineFunction2)action).preloadRootFlag) {funcRegNames.put(pos, "_root");pos++;}
|
||||
if(((ActionDefineFunction2)action).preloadParentFlag) {funcRegNames.put(pos, "_parent");pos++;}
|
||||
if(((ActionDefineFunction2)action).preloadGlobalFlag) {funcRegNames.put(pos, "_global");pos++;}
|
||||
|
||||
FunctionTreeItem fti = new FunctionTreeItem(action,((ActionDefineFunction2)action).functionName,((ActionDefineFunction2)action).paramNames, actionsToTree(funcRegNames,unknownJumps, loopList, jumpsOrIfs, new Stack<TreeItem>(), constants, ((ActionDefineFunction2) action).code, 0, ((ActionDefineFunction2) action).code.size() - 1, version), constants);
|
||||
stack.push(fti);
|
||||
} else if (action instanceof ActionPushDuplicate) {
|
||||
do {
|
||||
if (actions.get(ip + 1) instanceof ActionNot) {
|
||||
if (actions.get(ip + 2) instanceof ActionIf) {
|
||||
int nextPos = adr2ip(actions, ((ActionIf) actions.get(ip + 2)).getRef(version), version);
|
||||
stack.push(new AndTreeItem(action, stack.pop(), actionsToStackTree(jumpsOrIfs, actions, constants, ip + 4 /*je tam pop*/, nextPos - 1, version).pop()));
|
||||
stack.push(new AndTreeItem(action, stack.pop(), actionsToStackTree(registerNames,jumpsOrIfs, actions, constants, ip + 4 /*je tam pop*/, nextPos - 1, version).pop()));
|
||||
ip = nextPos;
|
||||
} else {
|
||||
output.add(new UnsupportedTreeItem(action, "ActionPushDuplicate with Not"));
|
||||
@@ -797,7 +844,7 @@ public class Action {
|
||||
}
|
||||
} else if (actions.get(ip + 1) instanceof ActionIf) {
|
||||
int nextPos = adr2ip(actions, ((ActionIf) actions.get(ip + 1)).getRef(version), version);
|
||||
stack.push(new OrTreeItem(action, stack.pop(), actionsToStackTree(jumpsOrIfs, actions, constants, ip + 3, nextPos - 1, version).pop()));
|
||||
stack.push(new OrTreeItem(action, stack.pop(), actionsToStackTree(registerNames,jumpsOrIfs, actions, constants, ip + 3, nextPos - 1, version).pop()));
|
||||
ip = nextPos;
|
||||
} else {
|
||||
output.add(new UnsupportedTreeItem(action, "ActionPushDuplicate with no If"));
|
||||
@@ -806,13 +853,14 @@ public class Action {
|
||||
action = actions.get(ip);
|
||||
}
|
||||
while (action instanceof ActionPushDuplicate);
|
||||
continue;
|
||||
} else if (action instanceof ActionStoreRegister) {
|
||||
if ((ip + 1 <= end) && (actions.get(ip + 1) instanceof ActionPop)) {
|
||||
action.translate(stack, constants, output);
|
||||
action.translate(stack, constants, output, registerNames);
|
||||
stack.pop();
|
||||
ip++;
|
||||
} else {
|
||||
action.translate(stack, constants, output);
|
||||
action.translate(stack, constants, output, registerNames);
|
||||
}
|
||||
} else if (action instanceof ActionStrictEquals) {
|
||||
if ((ip + 1 < actions.size()) && (actions.get(ip + 1) instanceof ActionIf)) {
|
||||
@@ -833,7 +881,7 @@ public class Action {
|
||||
do {
|
||||
ip++;
|
||||
if ((actions.get(ip - 1) instanceof ActionStrictEquals) && (actions.get(ip) instanceof ActionIf)) {
|
||||
caseValues.add(actionsToStackTree(jumpsOrIfs, actions, constants, caseStart, ip - 2, version).pop());
|
||||
caseValues.add(actionsToStackTree(registerNames,jumpsOrIfs, actions, constants, caseStart, ip - 2, version).pop());
|
||||
caseStart = ip + 1;
|
||||
caseBodyIps.add(adr2ip(actions, ((ActionIf) actions.get(ip)).getRef(version), version));
|
||||
if (actions.get(ip + 1) instanceof ActionJump) {
|
||||
@@ -848,16 +896,16 @@ public class Action {
|
||||
if (i < caseBodyIps.size() - 1) {
|
||||
caseEnd = caseBodyIps.get(i + 1) - 1;
|
||||
}
|
||||
caseCommands.add(actionsToTree(unknownJumps, loopList, jumpsOrIfs, stack, constants, actions, caseBodyIps.get(i), caseEnd, version));
|
||||
caseCommands.add(actionsToTree(registerNames,unknownJumps, loopList, jumpsOrIfs, stack, constants, actions, caseBodyIps.get(i), caseEnd, version));
|
||||
}
|
||||
output.add(new SwitchTreeItem(action, defaultAddr, switchedObject, caseValues, caseCommands, null));
|
||||
continue;
|
||||
} else {
|
||||
action.translate(stack, constants, output);
|
||||
action.translate(stack, constants, output, registerNames);
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
action.translate(stack, constants, output);
|
||||
action.translate(stack, constants, output, registerNames);
|
||||
} catch (EmptyStackException ese) {
|
||||
output.add(new UnsupportedTreeItem(action, "Empty stack"));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user