mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-09-25 05:30:45 +00:00
AS2: Decompiling via graph - good against obfuscators
This commit is contained in:
@@ -18,6 +18,9 @@ package com.jpexs.asdec;
|
||||
|
||||
import com.jpexs.asdec.abc.avm2.instructions.other.NopIns;
|
||||
import com.jpexs.asdec.action.Action;
|
||||
import com.jpexs.asdec.action.IgnoredPair;
|
||||
import com.jpexs.asdec.action.parser.ASMParser;
|
||||
import com.jpexs.asdec.action.parser.ParseException;
|
||||
import com.jpexs.asdec.action.special.ActionNop;
|
||||
import com.jpexs.asdec.action.swf3.*;
|
||||
import com.jpexs.asdec.action.swf4.*;
|
||||
@@ -37,6 +40,7 @@ import com.jpexs.asdec.types.shaperecords.SHAPERECORD;
|
||||
import com.jpexs.asdec.types.shaperecords.StraightEdgeRecord;
|
||||
import com.jpexs.asdec.types.shaperecords.StyleChangeRecord;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@@ -45,6 +49,7 @@ import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
@@ -496,15 +501,27 @@ public class SWFInputStream extends InputStream {
|
||||
}
|
||||
last = a;
|
||||
}
|
||||
try {
|
||||
String s = Highlighting.stripHilights(Action.actionsToString(ret, null, version));
|
||||
ret = ASMParser.parse(new ByteArrayInputStream(s.getBytes()), SWF.DEFAULT_VERSION);
|
||||
} catch (ParseException ex) {
|
||||
Logger.getLogger(SWFInputStream.class.getName()).log(Level.SEVERE, "parsing error", ex);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private void readActionListAtPos(Stack<TreeItem> stack, ConstantPool cpool, SWFInputStream sis, ReReadableInputStream rri, int ip, List<Action> ret) throws IOException {
|
||||
boolean debugMode = false;
|
||||
boolean displayCompiletime=false;
|
||||
rri.setPos(ip);
|
||||
Action a;
|
||||
List<TreeItem> output = new ArrayList<TreeItem>();
|
||||
long filePos = rri.getPos();
|
||||
while ((a = sis.readAction()) != null) {
|
||||
if (debugMode) {
|
||||
System.out.println("ip: " + ip + " action: " + a + " stack:" + Highlighting.stripHilights(stack.toString()));
|
||||
}
|
||||
|
||||
if (a instanceof ActionPush) {
|
||||
if (cpool != null) {
|
||||
((ActionPush) a).constantPool = cpool.constants;
|
||||
@@ -542,14 +559,43 @@ public class SWFInputStream extends InputStream {
|
||||
aif = (ActionIf) a;
|
||||
TreeItem top = stack.pop();
|
||||
if (top.isCompileTime()) {
|
||||
if (debugMode) {
|
||||
System.out.print("is compiletime -> ");
|
||||
}
|
||||
if (top.toBoolean()) {
|
||||
newip = rri.getPos() + aif.offset;
|
||||
rri.setPos(newip);
|
||||
a = new ActionJump(aif.offset);
|
||||
if (debugMode) {
|
||||
System.out.println("jump");
|
||||
}
|
||||
} else {
|
||||
if (debugMode) {
|
||||
System.out.println("ignore");
|
||||
}
|
||||
a = new ActionNop();
|
||||
}
|
||||
beforeInsert = new ActionPop();
|
||||
if(displayCompiletime){
|
||||
beforeInsert = new ActionPop();
|
||||
}
|
||||
else{
|
||||
List<IgnoredPair> needed=top.getNeededActions();
|
||||
for(IgnoredPair ig:needed){
|
||||
if(ig.action instanceof ActionPush){
|
||||
if(!((ActionPush)ig.action).ignoredParts.contains(ig.pos)){
|
||||
((ActionPush)ig.action).ignoredParts.add(ig.pos);
|
||||
|
||||
if(((ActionPush)ig.action).ignoredParts.size()==((ActionPush)ig.action).values.size())
|
||||
{
|
||||
ig.action.ignored=true;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
ig.action.ignored=true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
goaif = true;
|
||||
}
|
||||
@@ -557,7 +603,7 @@ public class SWFInputStream extends InputStream {
|
||||
newip = rri.getPos() + ((ActionJump) a).offset;
|
||||
rri.setPos(newip);
|
||||
} else {
|
||||
a.translate(stack, cpool, output, new HashMap<Integer, String>());
|
||||
a.translate(stack, output, new HashMap<Integer, String>());
|
||||
}
|
||||
for (int i = 0; i < actionLen; i++) {
|
||||
ensureCapacity(ret, ip + i);
|
||||
|
||||
@@ -486,8 +486,12 @@ public class AVM2Graph extends Graph{
|
||||
}
|
||||
}
|
||||
boolean loop = false;
|
||||
boolean reversed=false;
|
||||
if ((!part.nextParts.isEmpty()) && part.nextParts.get(0).leadsTo(part, loopContinues)) {
|
||||
loop = true;
|
||||
}else if ((part.nextParts.size()>1) && part.nextParts.get(1).leadsTo(part, loopContinues)) {
|
||||
loop = true;
|
||||
reversed=true;
|
||||
}
|
||||
if (((part.nextParts.size() == 2) || ((part.nextParts.size() == 1) && loop)) && (!isSwitch)) {
|
||||
|
||||
@@ -508,7 +512,7 @@ public class AVM2Graph extends Graph{
|
||||
}
|
||||
|
||||
if (part.nextParts.size() > 1) {
|
||||
currentLoop.loopBreak = part.nextParts.get(1);
|
||||
currentLoop.loopBreak = part.nextParts.get(reversed?0:1);
|
||||
}
|
||||
|
||||
int breakIp = -1;
|
||||
@@ -537,7 +541,7 @@ public class AVM2Graph extends Graph{
|
||||
GraphPart finalPart = null;
|
||||
boolean isFor = false;
|
||||
try {
|
||||
loopBody = printGraph(methodPath, stack, scopeStack, allParts, parsedExceptions, finallyJumps, level + 1, part, part.nextParts.get(0), stopPart, loops, localRegs, body, ignoredSwitches);
|
||||
loopBody = printGraph(methodPath, stack, scopeStack, allParts, parsedExceptions, finallyJumps, level + 1, part, part.nextParts.get(reversed?1:0), stopPart, loops, localRegs, body, ignoredSwitches);
|
||||
} catch (ForException fex) {
|
||||
loopBody = fex.output;
|
||||
finalCommands = fex.finalOutput;
|
||||
@@ -646,7 +650,7 @@ public class AVM2Graph extends Graph{
|
||||
}
|
||||
if (loop && (part.nextParts.size() > 1)) {
|
||||
loops.remove(currentLoop); //remove loop so no break shows up
|
||||
ret.addAll(printGraph(methodPath, stack, scopeStack, allParts, parsedExceptions, finallyJumps, level, part, part.nextParts.get(1), stopPart, loops, localRegs, body, ignoredSwitches));
|
||||
ret.addAll(printGraph(methodPath, stack, scopeStack, allParts, parsedExceptions, finallyJumps, level, part, part.nextParts.get(reversed?0:1), stopPart, loops, localRegs, body, ignoredSwitches));
|
||||
}
|
||||
|
||||
if (next != null) {
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.jpexs.asdec.abc.gui;
|
||||
|
||||
import com.jpexs.asdec.abc.avm2.graph.AVM2Graph;
|
||||
import com.jpexs.asdec.graph.Graph;
|
||||
import com.jpexs.asdec.graph.GraphPart;
|
||||
import com.jpexs.asdec.gui.View;
|
||||
import java.awt.*;
|
||||
@@ -41,9 +42,9 @@ public class GraphFrame extends JFrame {
|
||||
private static final int SPACE_HORIZONTAL = 10;
|
||||
private static final int BLOCK_WIDTH = 200;
|
||||
private static final int BLOCK_HEIGHT = 20;
|
||||
private AVM2Graph graph;
|
||||
private Graph graph;
|
||||
|
||||
public GraphPanel(AVM2Graph graph) {
|
||||
public GraphPanel(Graph graph) {
|
||||
this.graph = graph;
|
||||
setPreferredSize(new Dimension((BLOCK_WIDTH + SPACE_HORIZONTAL) * getPartWidth(graph.heads.get(0), new HashSet<GraphPart>()), (BLOCK_HEIGHT + SPACE_VERTICAL) * getPartHeight(graph.heads.get(0), new ArrayList<GraphPart>())));
|
||||
}
|
||||
@@ -121,7 +122,7 @@ public class GraphFrame extends JFrame {
|
||||
}
|
||||
}
|
||||
|
||||
public GraphFrame(AVM2Graph graph, String name) {
|
||||
public GraphFrame(Graph graph, String name) {
|
||||
setSize(500, 500);
|
||||
Container cnt = getContentPane();
|
||||
cnt.setLayout(new BorderLayout());
|
||||
|
||||
@@ -48,6 +48,7 @@ import java.util.logging.Logger;
|
||||
public class Action {
|
||||
|
||||
public Action beforeInsert;
|
||||
public boolean ignored=false;
|
||||
/**
|
||||
* Action type identifier
|
||||
*/
|
||||
@@ -124,7 +125,7 @@ public class Action {
|
||||
List<Long> ret = new ArrayList<Long>();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets all ActionIf or ActionJump actions from subactions
|
||||
*
|
||||
@@ -363,17 +364,25 @@ public class Action {
|
||||
}
|
||||
|
||||
offset = 0;
|
||||
for (Action a : list) {
|
||||
for (Action a : list) {
|
||||
offset = a.getAddress();
|
||||
if (importantOffsets.contains(offset)) {
|
||||
ret += "loc" + Helper.formatAddress(offset) + ":";
|
||||
}
|
||||
if(a.beforeInsert!=null){
|
||||
ret+=a.beforeInsert.getASMSource(importantOffsets, constantPool, version) + "\r\n";
|
||||
}
|
||||
if(!(a instanceof ActionNop)){
|
||||
ret += Highlighting.hilighOffset("", offset) + a.getASMSource(importantOffsets, constantPool, version) + "\r\n";
|
||||
}
|
||||
|
||||
if(a.ignored){
|
||||
int len=a.getBytes(version).length;
|
||||
for(int i=0;i<len;i++){
|
||||
ret+="Nop\r\n";
|
||||
}
|
||||
}else{
|
||||
if (a.beforeInsert != null) {
|
||||
ret += a.beforeInsert.getASMSource(importantOffsets, constantPool, version) + "\r\n";
|
||||
}
|
||||
if (!(a instanceof ActionNop)) {
|
||||
ret += Highlighting.hilighOffset("", offset) + a.getASMSource(importantOffsets, constantPool, version) + "\r\n";
|
||||
}
|
||||
}
|
||||
offset += a.getBytes(version).length;
|
||||
}
|
||||
if (importantOffsets.contains(offset)) {
|
||||
@@ -402,7 +411,7 @@ public class Action {
|
||||
* @param output Output
|
||||
* @param regNames Register names
|
||||
*/
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -579,8 +588,10 @@ public class Action {
|
||||
*/
|
||||
public static String actionsToSource(List<Action> actions, int version) {
|
||||
try {
|
||||
//List<TreeItem> tree = actionsToTree(new HashMap<Integer, String>(), actions, version);
|
||||
List<TreeItem> tree = actionsToTree(new HashMap<Integer, String>(), actions, version);
|
||||
|
||||
|
||||
return treeToString(tree);
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(Action.class.getName()).log(Level.SEVERE, null, ex);
|
||||
@@ -597,14 +608,9 @@ public class Action {
|
||||
* @return List of treeItems
|
||||
*/
|
||||
public static List<TreeItem> actionsToTree(HashMap<Integer, String> regNames, List<Action> actions, int version) {
|
||||
Stack<TreeItem> stack = new Stack<TreeItem>();
|
||||
return actionsToTree(regNames, new ArrayList<Long>(), new ArrayList<Loop>(), getActionsAllIfsOrJumps(actions), stack, new ConstantPool(), actions, 0, actions.size() - 1, 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(regNames, new ArrayList<Long>(), new ArrayList<Loop>(), jumpsOrIfs, ret, constants, actions, start, end, version);
|
||||
return ret;
|
||||
//Stack<TreeItem> stack = new Stack<TreeItem>();
|
||||
return ActionGraph.translateViaGraph(regNames, actions, version);
|
||||
//return actionsToTree(regNames, stack, actions, 0, actions.size() - 1, version);
|
||||
}
|
||||
|
||||
private static class Loop {
|
||||
@@ -629,8 +635,10 @@ public class Action {
|
||||
logger.fine(s);
|
||||
}
|
||||
|
||||
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) {
|
||||
log("Entering " + start + "-" + end + (actions.size() > 0 ? (" (" + actions.get(start).toString() + " - " + actions.get(end == actions.size() ? end - 1 : end) + ")") : ""));
|
||||
public static List<TreeItem> actionsPartToTree(HashMap<Integer, String> registerNames, Stack<TreeItem> stack, List<Action> actions, int start, int end, int version) {
|
||||
if (start < actions.size() && (end > 0) && (start > 0)) {
|
||||
log("Entering " + start + "-" + end + (actions.size() > 0 ? (" (" + actions.get(start).toString() + " - " + actions.get(end == actions.size() ? end - 1 : end) + ")") : ""));
|
||||
}
|
||||
List<TreeItem> output = new ArrayList<TreeItem>();
|
||||
int ip = start;
|
||||
boolean isWhile = false;
|
||||
@@ -641,259 +649,71 @@ public class Action {
|
||||
while (ip <= end + 1) {
|
||||
|
||||
long addr = ip2adr(actions, ip, version);
|
||||
if (unknownJumps.contains(addr)) {
|
||||
unknownJumps.remove(new Long(addr));
|
||||
boolean switchFound = false;
|
||||
for (int i = output.size() - 1; i >= 0; i--) {
|
||||
if (output.get(i) instanceof SwitchTreeItem) {
|
||||
if (((SwitchTreeItem) output.get(i)).defaultCommands == null) {
|
||||
List<ContinueTreeItem> continues = ((SwitchTreeItem) output.get(i)).getContinues();
|
||||
boolean breakFound = false;
|
||||
for (ContinueTreeItem cti : continues) {
|
||||
if (cti.loopPos == addr) {
|
||||
cti.isKnown = true;
|
||||
cti.isBreak = true;
|
||||
((SwitchTreeItem) output.get(i)).loopBreak = addr;
|
||||
breakFound = true;
|
||||
}
|
||||
}
|
||||
if (breakFound) {
|
||||
switchFound = true;
|
||||
((SwitchTreeItem) output.get(i)).defaultCommands = new ArrayList<TreeItem>();
|
||||
for (int k = i + 1; k < output.size(); k++) {
|
||||
((SwitchTreeItem) output.get(i)).defaultCommands.add(output.remove(i + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!switchFound) {
|
||||
throw new UnknownJumpException(stack, addr, output);
|
||||
}
|
||||
}
|
||||
/*if (unknownJumps.contains(addr)) {
|
||||
unknownJumps.remove(new Long(addr));
|
||||
boolean switchFound = false;
|
||||
for (int i = output.size() - 1; i >= 0; i--) {
|
||||
if (output.get(i) instanceof SwitchTreeItem) {
|
||||
if (((SwitchTreeItem) output.get(i)).defaultCommands == null) {
|
||||
List<ContinueTreeItem> continues = ((SwitchTreeItem) output.get(i)).getContinues();
|
||||
boolean breakFound = false;
|
||||
for (ContinueTreeItem cti : continues) {
|
||||
if (cti.loopPos == addr) {
|
||||
cti.isKnown = true;
|
||||
cti.isBreak = true;
|
||||
((SwitchTreeItem) output.get(i)).loopBreak = addr;
|
||||
breakFound = true;
|
||||
}
|
||||
}
|
||||
if (breakFound) {
|
||||
switchFound = true;
|
||||
((SwitchTreeItem) output.get(i)).defaultCommands = new ArrayList<TreeItem>();
|
||||
for (int k = i + 1; k < output.size(); k++) {
|
||||
((SwitchTreeItem) output.get(i)).defaultCommands.add(output.remove(i + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!switchFound) {
|
||||
throw new UnknownJumpException(stack, addr, output);
|
||||
}
|
||||
}*/
|
||||
if (ip > end) {
|
||||
break;
|
||||
}
|
||||
Action action = actions.get(ip);
|
||||
log("" + Helper.formatAddress(addr) + " ip:" + ip + " action:" + action);
|
||||
for (int j = 0; j < jumpsOrIfs.size(); j++) {
|
||||
Action jif = jumpsOrIfs.get(j);
|
||||
if (jif instanceof ActionIf) {
|
||||
if (((ActionIf) jif).getRef(version) == addr) {
|
||||
if (jif.getAddress() > addr) {
|
||||
jumpsOrIfs.remove(j);
|
||||
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);
|
||||
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;
|
||||
continue loopip;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
for (int j = 0; j < jumpsOrIfs.size(); j++) {
|
||||
Action jif = jumpsOrIfs.get(j);
|
||||
if (jif instanceof ActionJump) {
|
||||
if (((ActionJump) jif).getRef(version) == addr) {
|
||||
if (jif.getAddress() > addr) {
|
||||
isWhile = true;
|
||||
loopStart = ip;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (action instanceof ActionJump) {
|
||||
int jumpIp = adr2ip(actions, ((ActionJump) action).getRef(version), version);
|
||||
for (Loop l : loopList) {
|
||||
if (l.loopBreak == ((ActionJump) action).getRef(version)) {
|
||||
output.add(new BreakTreeItem(action, l.loopBreak));
|
||||
ip = ip + 1;
|
||||
continue loopip;
|
||||
}
|
||||
if (l.loopContinue == ((ActionJump) action).getRef(version)) {
|
||||
l.continueCount++;
|
||||
output.add(new ContinueTreeItem(action, l.loopBreak));
|
||||
ip = ip + 1;
|
||||
continue loopip;
|
||||
}
|
||||
}
|
||||
output.add(new ContinueTreeItem(action, ((ActionJump) action).getRef(version), false));
|
||||
|
||||
if (!unknownJumps.contains(((ActionJump) action).getRef(version))) {
|
||||
unknownJumps.add(((ActionJump) action).getRef(version));
|
||||
}
|
||||
break;
|
||||
|
||||
} else if (action instanceof ActionIf) {
|
||||
int jumpIp = adr2ip(actions, ((ActionIf) action).getRef(version), version);
|
||||
if (jumpIp < ip) {
|
||||
output.add(new UnsupportedTreeItem(action, "ActionIf to jump back"));
|
||||
break;
|
||||
}
|
||||
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>();
|
||||
boolean hasElse = false;
|
||||
int jumpElseIp = 0;
|
||||
Stack<TreeItem> falseStack = (Stack<TreeItem>) stack.clone();
|
||||
Stack<TreeItem> trueStack = (Stack<TreeItem>) stack.clone();// new Stack<TreeItem>();
|
||||
//if (!isWhile) {
|
||||
if (actions.get(jumpIp - 1) instanceof ActionJump) {
|
||||
long ref = ((ActionJump) actions.get(jumpIp - 1)).getRef(version);
|
||||
int refIp = adr2ip(actions, ref, version);
|
||||
if ((refIp > jumpIp) && (refIp <= end + 1)) {
|
||||
hasElse = true;
|
||||
jumpElseIp = adr2ip(actions, ((ActionJump) actions.get(jumpIp - 1)).getRef(version), version);
|
||||
}
|
||||
}
|
||||
//}
|
||||
Loop currentLoop = null;
|
||||
if (isWhile || isForIn) {
|
||||
currentLoop = new Loop(ip2adr(actions, loopStart, version), ip2adr(actions, jumpIp, version));
|
||||
loopList.add(currentLoop);
|
||||
}
|
||||
boolean isFor = false;
|
||||
boolean isTernar = false;
|
||||
List<TreeItem> finalExpression = null;
|
||||
|
||||
TreeItem variableName = null;
|
||||
try {
|
||||
int falseStackSizeBefore = falseStack.size();
|
||||
if (hasElse) {
|
||||
log("Going to onfalse");
|
||||
onFalse = actionsToTree(registerNames, unknownJumps, loopList, jumpsOrIfs, falseStack, constants, actions, jumpIp, jumpElseIp - 1, version);
|
||||
}
|
||||
int trueStackSizeBefore = trueStack.size();
|
||||
log("Going to ontrue");
|
||||
onTrue = actionsToTree(registerNames, unknownJumps, loopList, jumpsOrIfs, trueStack, constants, actions, ip + 1, jumpIp - 1 - (hasElse || isWhile || isForIn ? 1 : 0), version);
|
||||
if (onTrue.isEmpty() && trueStack.size() > trueStackSizeBefore && onFalse.isEmpty() && falseStack.size() > falseStackSizeBefore) {
|
||||
isTernar = true;
|
||||
}
|
||||
int next = (hasElse ? jumpElseIp : jumpIp);
|
||||
if (actions.size() > next) {
|
||||
if (!isTernar) {
|
||||
Action nea = actions.get(next);
|
||||
if (nea instanceof ActionPop) {
|
||||
if (trueStack.size() > 0) {
|
||||
nea.translate(trueStack, constants, onTrue, registerNames);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (UnknownJumpException uje) {
|
||||
if ((adr2ip(actions, uje.addr, version) >= start) && (adr2ip(actions, uje.addr, version) <= end)) {
|
||||
if (currentLoop == null) {
|
||||
output.add(new UnsupportedTreeItem(action, "UnknownJump"));
|
||||
} else {
|
||||
currentLoop.loopContinue = uje.addr;
|
||||
onTrue = uje.output;
|
||||
List<ContinueTreeItem> contList = new ArrayList<ContinueTreeItem>();
|
||||
for (TreeItem ti : onTrue) {
|
||||
if (ti instanceof ContinueTreeItem) {
|
||||
contList.add((ContinueTreeItem) ti);
|
||||
}
|
||||
if (ti instanceof Block) {
|
||||
List<ContinueTreeItem> subcont = ((Block) ti).getContinues();
|
||||
for (int k = 0; k < subcont.size(); k++) {
|
||||
contList.add(subcont.get(k));
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int u = 0; u < contList.size(); u++) {
|
||||
if (contList.get(u) instanceof ContinueTreeItem) {
|
||||
if (((ContinueTreeItem) contList.get(u)).loopPos == uje.addr) {
|
||||
if (!((ContinueTreeItem) contList.get(u)).isKnown) {
|
||||
((ContinueTreeItem) contList.get(u)).isKnown = true;
|
||||
((ContinueTreeItem) contList.get(u)).loopPos = currentLoop.loopBreak;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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 (isForIn) {
|
||||
variableName = onTrue.remove(0);
|
||||
if (variableName instanceof SetTypeTreeItem) {
|
||||
variableName = ((SetTypeTreeItem) variableName).getObject();
|
||||
}
|
||||
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()));
|
||||
} else if (isWhile) {
|
||||
output.add(new WhileTreeItem(action, jumpIp, loopStart, expression, onTrue));
|
||||
} else {
|
||||
output.add(new IfTreeItem(action, expression, onTrue, onFalse));
|
||||
}
|
||||
ip = (hasElse ? jumpElseIp : jumpIp);
|
||||
isWhile = false;
|
||||
isFor = false;
|
||||
isForIn = false;
|
||||
continue;
|
||||
} else if ((action instanceof ActionEnumerate2) || (action instanceof ActionEnumerate)) {
|
||||
/*ActionJump && ActionIf removed*/
|
||||
if ((action instanceof ActionEnumerate2) || (action instanceof ActionEnumerate)) {
|
||||
loopStart = ip + 1;
|
||||
isForIn = true;
|
||||
ip += 4;
|
||||
action.translate(stack, constants, output, registerNames);
|
||||
action.translate(stack, output, registerNames);
|
||||
EnumerateTreeItem en = (EnumerateTreeItem) stack.peek();
|
||||
inItem = en.object;
|
||||
continue;
|
||||
} else if (action instanceof ActionTry) {
|
||||
ActionTry atry = (ActionTry) action;
|
||||
List<TreeItem> tryCommands = actionsToTree(registerNames, unknownJumps, loopList, jumpsOrIfs, new Stack<TreeItem>(), constants, atry.tryBody, 0, atry.tryBody.size() - 1, version);
|
||||
List<TreeItem> tryCommands = ActionGraph.translateViaGraph(registerNames, atry.tryBody, version);
|
||||
TreeItem catchName;
|
||||
if (atry.catchInRegisterFlag) {
|
||||
catchName = new DirectValueTreeItem(atry, new RegisterNumber(atry.catchRegister), constants);
|
||||
catchName = new DirectValueTreeItem(atry,-1, new RegisterNumber(atry.catchRegister), new ArrayList<String>());
|
||||
} else {
|
||||
catchName = new DirectValueTreeItem(atry, atry.catchName, constants);
|
||||
catchName = new DirectValueTreeItem(atry,-1, atry.catchName, new ArrayList<String>());
|
||||
}
|
||||
List<TreeItem> catchExceptions = new ArrayList<TreeItem>();
|
||||
catchExceptions.add(catchName);
|
||||
List<List<TreeItem>> catchCommands = new ArrayList<List<TreeItem>>();
|
||||
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);
|
||||
catchCommands.add(ActionGraph.translateViaGraph(registerNames, atry.catchBody, version));
|
||||
List<TreeItem> finallyCommands = ActionGraph.translateViaGraph(registerNames, atry.finallyBody, version);
|
||||
output.add(new TryTreeItem(tryCommands, catchExceptions, catchCommands, finallyCommands));
|
||||
} else if (action instanceof ActionWith) {
|
||||
ActionWith awith = (ActionWith) action;
|
||||
List<TreeItem> withCommands = actionsToTree(registerNames, unknownJumps, loopList, jumpsOrIfs, new Stack<TreeItem>(), constants, awith.actions, 0, awith.actions.size() - 1, version);
|
||||
List<TreeItem> withCommands = ActionGraph.translateViaGraph(registerNames, awith.actions, version);
|
||||
output.add(new WithTreeItem(action, stack.pop(), withCommands));
|
||||
} else if (action instanceof ActionDefineFunction) {
|
||||
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);
|
||||
FunctionTreeItem fti = new FunctionTreeItem(action, ((ActionDefineFunction) action).functionName, ((ActionDefineFunction) action).paramNames, ActionGraph.translateViaGraph(registerNames, ((ActionDefineFunction) action).code, version), ((ActionDefineFunction) action).constantPool, 1);
|
||||
stack.push(fti);
|
||||
} else if (action instanceof ActionDefineFunction2) {
|
||||
HashMap<Integer, String> funcRegNames = (HashMap<Integer, String>) registerNames.clone();
|
||||
@@ -929,87 +749,89 @@ public class Action {
|
||||
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);
|
||||
FunctionTreeItem fti = new FunctionTreeItem(action, ((ActionDefineFunction2) action).functionName, ((ActionDefineFunction2) action).paramNames, ActionGraph.translateViaGraph(funcRegNames, ((ActionDefineFunction2) action).code, version), ((ActionDefineFunction2) action).constantPool, ((ActionDefineFunction2) action).getFirstRegister());
|
||||
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(registerNames, jumpsOrIfs, actions, constants, ip + 4 /*je tam pop*/, nextPos - 1, version).pop()));
|
||||
ip = nextPos;
|
||||
} else {
|
||||
output.add(new UnsupportedTreeItem(action, "ActionPushDuplicate with Not"));
|
||||
break;
|
||||
}
|
||||
} 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(registerNames, jumpsOrIfs, actions, constants, ip + 3, nextPos - 1, version).pop()));
|
||||
ip = nextPos;
|
||||
} else {
|
||||
output.add(new UnsupportedTreeItem(action, "ActionPushDuplicate with no If"));
|
||||
break loopip;
|
||||
}
|
||||
action = actions.get(ip);
|
||||
} while (action instanceof ActionPushDuplicate);
|
||||
continue;
|
||||
} else if (action instanceof ActionStoreRegister) {
|
||||
} /*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(registerNames, actions, constants, ip + 4, nextPos - 1, version).pop()));
|
||||
ip = nextPos;
|
||||
} else {
|
||||
output.add(new UnsupportedTreeItem(action, "ActionPushDuplicate with Not"));
|
||||
break;
|
||||
}
|
||||
} 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(registerNames, actions, constants, ip + 3, nextPos - 1, version).pop()));
|
||||
ip = nextPos;
|
||||
} else {
|
||||
output.add(new UnsupportedTreeItem(action, "ActionPushDuplicate with no If"));
|
||||
break loopip;
|
||||
}
|
||||
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, registerNames);
|
||||
action.translate(stack, output, registerNames);
|
||||
stack.pop();
|
||||
ip++;
|
||||
} else {
|
||||
action.translate(stack, constants, output, registerNames);
|
||||
action.translate(stack, output, registerNames);
|
||||
}
|
||||
} else if (action instanceof ActionStrictEquals) {
|
||||
if ((ip + 1 < actions.size()) && (actions.get(ip + 1) instanceof ActionIf)) {
|
||||
List<TreeItem> caseValues = new ArrayList<TreeItem>();
|
||||
List<List<TreeItem>> caseCommands = new ArrayList<List<TreeItem>>();
|
||||
caseValues.add(stack.pop());
|
||||
TreeItem switchedObject = stack.pop();
|
||||
if (output.size() > 0) {
|
||||
if (output.get(output.size() - 1) instanceof StoreRegisterTreeItem) {
|
||||
output.remove(output.size() - 1);
|
||||
}
|
||||
}
|
||||
int caseStart = ip + 2;
|
||||
List<Integer> caseBodyIps = new ArrayList<Integer>();
|
||||
long defaultAddr = 0;
|
||||
caseBodyIps.add(adr2ip(actions, ((ActionIf) actions.get(ip + 1)).getRef(version), version));
|
||||
ip++;
|
||||
do {
|
||||
ip++;
|
||||
if ((actions.get(ip - 1) instanceof ActionStrictEquals) && (actions.get(ip) instanceof ActionIf)) {
|
||||
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) {
|
||||
defaultAddr = ((ActionJump) actions.get(ip + 1)).getRef(version);
|
||||
ip = adr2ip(actions, defaultAddr, version);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (ip < end);
|
||||
loopList.add(new Loop(-1, ip2adr(actions, ip, version)));
|
||||
for (int i = 0; i < caseBodyIps.size(); i++) {
|
||||
int caseEnd = ip - 1;
|
||||
if (i < caseBodyIps.size() - 1) {
|
||||
caseEnd = caseBodyIps.get(i + 1) - 1;
|
||||
}
|
||||
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, registerNames);
|
||||
}
|
||||
} else {
|
||||
} /*else if (action instanceof ActionStrictEquals) {
|
||||
if ((ip + 1 < actions.size()) && (actions.get(ip + 1) instanceof ActionIf)) {
|
||||
List<TreeItem> caseValues = new ArrayList<TreeItem>();
|
||||
List<List<TreeItem>> caseCommands = new ArrayList<List<TreeItem>>();
|
||||
caseValues.add(stack.pop());
|
||||
TreeItem switchedObject = stack.pop();
|
||||
if (output.size() > 0) {
|
||||
if (output.get(output.size() - 1) instanceof StoreRegisterTreeItem) {
|
||||
output.remove(output.size() - 1);
|
||||
}
|
||||
}
|
||||
int caseStart = ip + 2;
|
||||
List<Integer> caseBodyIps = new ArrayList<Integer>();
|
||||
long defaultAddr = 0;
|
||||
caseBodyIps.add(adr2ip(actions, ((ActionIf) actions.get(ip + 1)).getRef(version), version));
|
||||
ip++;
|
||||
do {
|
||||
ip++;
|
||||
if ((actions.get(ip - 1) instanceof ActionStrictEquals) && (actions.get(ip) instanceof ActionIf)) {
|
||||
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) {
|
||||
defaultAddr = ((ActionJump) actions.get(ip + 1)).getRef(version);
|
||||
ip = adr2ip(actions, defaultAddr, version);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (ip < end);
|
||||
|
||||
for (int i = 0; i < caseBodyIps.size(); i++) {
|
||||
int caseEnd = ip - 1;
|
||||
if (i < caseBodyIps.size() - 1) {
|
||||
caseEnd = caseBodyIps.get(i + 1) - 1;
|
||||
}
|
||||
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, registerNames);
|
||||
}
|
||||
} */ else {
|
||||
try {
|
||||
action.translate(stack, constants, output, registerNames);
|
||||
action.translate(stack, output, registerNames);
|
||||
} catch (EmptyStackException ese) {
|
||||
System.err.println("EMPTYSTACK===========================");
|
||||
Logger.getLogger(Action.class.getName()).log(Level.SEVERE, null, ese);
|
||||
output.add(new UnsupportedTreeItem(action, "Empty stack"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ip++;
|
||||
@@ -1022,7 +844,7 @@ public class Action {
|
||||
}
|
||||
}
|
||||
}
|
||||
output = checkClass(output);
|
||||
//output = checkClass(output);
|
||||
log("Leaving " + start + "-" + end);
|
||||
return output;
|
||||
}
|
||||
@@ -1042,7 +864,7 @@ public class Action {
|
||||
if (v.value instanceof DirectValueTreeItem) {
|
||||
if (((DirectValueTreeItem) v.value).value instanceof String) {
|
||||
if (((DirectValueTreeItem) v.value).value.equals("_global")) {
|
||||
GetVariableTreeItem gvt = new GetVariableTreeItem(null, ((GetMemberTreeItem) t).functionName);
|
||||
GetVariableTreeItem gvt = new GetVariableTreeItem(null, ((GetMemberTreeItem) t).memberName);
|
||||
if (lastMember == null) {
|
||||
return gvt;
|
||||
} else {
|
||||
@@ -1055,7 +877,7 @@ public class Action {
|
||||
return ti;
|
||||
}
|
||||
|
||||
private static List<TreeItem> checkClass(List<TreeItem> output) {
|
||||
public static List<TreeItem> checkClass(List<TreeItem> output) {
|
||||
List<TreeItem> ret = new ArrayList<TreeItem>();
|
||||
List<FunctionTreeItem> functions = new ArrayList<FunctionTreeItem>();
|
||||
List<FunctionTreeItem> staticFunctions = new ArrayList<FunctionTreeItem>();
|
||||
@@ -1071,7 +893,7 @@ public class Action {
|
||||
if (it.expression instanceof NotTreeItem) {
|
||||
NotTreeItem nti = (NotTreeItem) it.expression;
|
||||
if (nti.value instanceof GetMemberTreeItem) {
|
||||
if (it.onFalse.isEmpty()) {
|
||||
if (true) { //it.onFalse.isEmpty()){ //||(it.onFalse.get(0) instanceof UnsupportedTreeItem)) {
|
||||
if ((it.onTrue.size() == 1) && (it.onTrue.get(0) instanceof SetMemberTreeItem) && (((SetMemberTreeItem) it.onTrue.get(0)).value instanceof NewObjectTreeItem)) {
|
||||
//ignore
|
||||
} else {
|
||||
@@ -1085,7 +907,7 @@ public class Action {
|
||||
TreeItem ti2 = ((StoreRegisterTreeItem) parts.get(0)).value;
|
||||
if (ti1 == ti2) {
|
||||
if (((SetMemberTreeItem) parts.get(1)).value instanceof FunctionTreeItem) {
|
||||
((FunctionTreeItem) ((SetMemberTreeItem) parts.get(1)).value).calculatedFunctionName = (className instanceof GetMemberTreeItem) ? ((GetMemberTreeItem) className).functionName : className;
|
||||
((FunctionTreeItem) ((SetMemberTreeItem) parts.get(1)).value).calculatedFunctionName = (className instanceof GetMemberTreeItem) ? ((GetMemberTreeItem) className).memberName : className;
|
||||
functions.add((FunctionTreeItem) ((SetMemberTreeItem) parts.get(1)).value);
|
||||
int pos = 2;
|
||||
if (parts.size() <= pos) {
|
||||
@@ -1171,15 +993,10 @@ public class Action {
|
||||
} else {
|
||||
ok = false;
|
||||
}
|
||||
} else if (parts.get(pos) instanceof VoidTreeItem) {
|
||||
VoidTreeItem v = (VoidTreeItem) parts.get(pos);
|
||||
if (v.value instanceof CallFunctionTreeItem) {
|
||||
//if(((CallFunctionTreeItem)parts.get(pos)).functionName){
|
||||
if (((CallFunctionTreeItem) v.value).functionName instanceof DirectValueTreeItem) {
|
||||
if (((DirectValueTreeItem) ((CallFunctionTreeItem) v.value).functionName).value.equals("ASSetPropFlags")) {
|
||||
} else {
|
||||
ok = false;
|
||||
}
|
||||
} else if (parts.get(pos) instanceof CallFunctionTreeItem) {
|
||||
//if(((CallFunctionTreeItem)parts.get(pos)).functionName){
|
||||
if (((CallFunctionTreeItem) parts.get(pos)).functionName instanceof DirectValueTreeItem) {
|
||||
if (((DirectValueTreeItem) ((CallFunctionTreeItem) parts.get(pos)).functionName).value.equals("ASSetPropFlags")) {
|
||||
} else {
|
||||
ok = false;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,758 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.asdec.action;
|
||||
|
||||
import com.jpexs.asdec.graph.Graph;
|
||||
import com.jpexs.asdec.graph.GraphPart;
|
||||
import com.jpexs.asdec.graph.Loop;
|
||||
import com.jpexs.asdec.graph.GraphPartMulti;
|
||||
import com.jpexs.asdec.action.swf4.ActionIf;
|
||||
import com.jpexs.asdec.action.swf4.ActionJump;
|
||||
import com.jpexs.asdec.action.swf4.Null;
|
||||
import com.jpexs.asdec.action.swf5.ActionReturn;
|
||||
import com.jpexs.asdec.action.swf6.ActionStrictEquals;
|
||||
import com.jpexs.asdec.action.swf7.ActionThrow;
|
||||
import com.jpexs.asdec.action.treemodel.BreakTreeItem;
|
||||
import com.jpexs.asdec.action.treemodel.ContinueTreeItem;
|
||||
import com.jpexs.asdec.action.treemodel.DirectValueTreeItem;
|
||||
import com.jpexs.asdec.action.treemodel.StoreRegisterTreeItem;
|
||||
import com.jpexs.asdec.action.treemodel.TreeItem;
|
||||
import com.jpexs.asdec.action.treemodel.UnsupportedTreeItem;
|
||||
import com.jpexs.asdec.action.treemodel.clauses.DoWhileTreeItem;
|
||||
import com.jpexs.asdec.action.treemodel.clauses.ForTreeItem;
|
||||
import com.jpexs.asdec.action.treemodel.clauses.IfTreeItem;
|
||||
import com.jpexs.asdec.action.treemodel.clauses.SwitchTreeItem;
|
||||
import com.jpexs.asdec.action.treemodel.clauses.TernarOpTreeItem;
|
||||
import com.jpexs.asdec.action.treemodel.clauses.WhileTreeItem;
|
||||
import com.jpexs.asdec.action.treemodel.operations.AndTreeItem;
|
||||
import com.jpexs.asdec.action.treemodel.operations.LogicalOp;
|
||||
import com.jpexs.asdec.action.treemodel.operations.NotTreeItem;
|
||||
import com.jpexs.asdec.action.treemodel.operations.OrTreeItem;
|
||||
import com.jpexs.asdec.action.treemodel.operations.StrictEqTreeItem;
|
||||
import com.jpexs.asdec.helpers.Highlighting;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class ActionGraph extends Graph {
|
||||
|
||||
private List<Action> code;
|
||||
private int version;
|
||||
|
||||
public ActionGraph(List<Action> code, int version) {
|
||||
this.version = version;
|
||||
this.code = code;
|
||||
heads = makeGraph(code, new ArrayList<GraphPart>());
|
||||
for (GraphPart head : heads) {
|
||||
fixGraph(head);
|
||||
makeMulti(head, new ArrayList<GraphPart>());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static List<TreeItem> translateViaGraph(HashMap<Integer, String> registerNames, List<Action> code, int version) {
|
||||
ActionGraph g = new ActionGraph(code, version);
|
||||
List<GraphPart> allParts = new ArrayList<GraphPart>();
|
||||
for (GraphPart head : g.heads) {
|
||||
populateParts(head, allParts);
|
||||
}
|
||||
return Action.checkClass(g.printGraph(registerNames, new Stack<TreeItem>(), allParts, null, g.heads.get(0), null, new ArrayList<Loop>(), new HashMap<Loop, List<TreeItem>>()));
|
||||
}
|
||||
|
||||
private TreeItem translatePartGetStack(GraphPart part, Stack<TreeItem> stack, HashMap<Integer, String> registerNames) {
|
||||
stack = (Stack<TreeItem>) stack.clone();
|
||||
translatePart(part, stack, registerNames);
|
||||
return stack.pop();
|
||||
}
|
||||
|
||||
private List<TreeItem> translatePart(GraphPart part, Stack<TreeItem> stack, HashMap<Integer, String> registerNames) {
|
||||
List<GraphPart> sub = part.getSubParts();
|
||||
List<TreeItem> ret = new ArrayList<TreeItem>();
|
||||
int end = 0;
|
||||
for (GraphPart p : sub) {
|
||||
if (p.end == -1) {
|
||||
p.end = code.size() - 1;
|
||||
}
|
||||
if (p.start == code.size()) {
|
||||
continue;
|
||||
} else if (p.end == code.size()) {
|
||||
p.end--;
|
||||
}
|
||||
end = p.end;
|
||||
int start = p.start;
|
||||
if (code.get(end) instanceof ActionJump) {
|
||||
end--;
|
||||
} else if (code.get(end) instanceof ActionIf) {
|
||||
end--;
|
||||
}
|
||||
ret.addAll(Action.actionsPartToTree(registerNames, stack, code, start, end, version));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private TreeItem checkLoop(GraphPart part, GraphPart stopPart, List<Loop> loops) {
|
||||
if (part == stopPart) {
|
||||
return null;
|
||||
}
|
||||
for (Loop l : loops) {
|
||||
if (l.loopContinue == part) {
|
||||
return (new ContinueTreeItem(null, l.loopBreak == null ? -1 : l.loopBreak.start));
|
||||
}
|
||||
if (l.loopBreak == part) {
|
||||
return (new BreakTreeItem(null, part.start));
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
private boolean doDecompile = true;
|
||||
|
||||
private List<TreeItem> printGraph(HashMap<Integer, String> registerNames, Stack<TreeItem> stack, List<GraphPart> allParts, GraphPart parent, GraphPart part, GraphPart stopPart, List<Loop> loops, HashMap<Loop, List<TreeItem>> forFinalCommands) {
|
||||
List<TreeItem> ret = new ArrayList<TreeItem>();
|
||||
boolean debugMode = false;
|
||||
if (part.start >= code.size()) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!doDecompile) {
|
||||
// ret.add(new CommentTreeItem(null, "not decompiled"));
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (debugMode) {
|
||||
System.err.println("PART " + part);
|
||||
}
|
||||
|
||||
if (part == stopPart) {
|
||||
return ret;
|
||||
}
|
||||
if (part.ignored) {
|
||||
return ret;
|
||||
}
|
||||
List<String> fqn = new ArrayList<String>();
|
||||
HashMap<Integer, String> lrn = new HashMap<Integer, String>();
|
||||
List<TreeItem> output = new ArrayList<TreeItem>();
|
||||
boolean isSwitch = false;
|
||||
List<GraphPart> parts = new ArrayList<GraphPart>();
|
||||
if (part instanceof GraphPartMulti) {
|
||||
parts = ((GraphPartMulti) part).parts;
|
||||
} else {
|
||||
parts.add(part);
|
||||
}
|
||||
boolean isIf = false;
|
||||
int end = part.end;
|
||||
if (end == -1) {
|
||||
end = code.size() - 1;
|
||||
}
|
||||
if (end == code.size()) {
|
||||
end--;
|
||||
}
|
||||
output.addAll(translatePart(part, stack, registerNames));
|
||||
if (end > -1) {
|
||||
if (code.get(end) instanceof ActionJump) {
|
||||
end--;
|
||||
} else if (code.get(end) instanceof ActionIf) {
|
||||
end--;
|
||||
isIf = true;
|
||||
}
|
||||
}
|
||||
if (isIf) {
|
||||
Action ins = code.get(end + 1);
|
||||
if ((stack.size() >= 2) && (stack.get(stack.size() - 1) instanceof NotTreeItem) && (((NotTreeItem) stack.get(stack.size() - 1)).value == stack.get(stack.size() - 2))) {
|
||||
ret.addAll(output);
|
||||
printGraph(registerNames, stack, allParts, parent, part.nextParts.get(1), part.nextParts.get(0), loops, forFinalCommands);
|
||||
TreeItem second = stack.pop();
|
||||
TreeItem first = stack.pop();
|
||||
stack.push(new AndTreeItem(ins, first, second));
|
||||
ret.addAll(printGraph(registerNames, stack, allParts, parent, part.nextParts.get(0), stopPart, loops, forFinalCommands));
|
||||
return ret;
|
||||
} else if ((stack.size() >= 2) && (stack.get(stack.size() - 1) == stack.get(stack.size() - 2))) {
|
||||
ret.addAll(output);
|
||||
printGraph(registerNames, stack, allParts, parent, part.nextParts.get(1), part.nextParts.get(0), loops, forFinalCommands);
|
||||
TreeItem second = stack.pop();
|
||||
TreeItem first = stack.pop();
|
||||
stack.push(new OrTreeItem(ins, first, second));
|
||||
ret.addAll(printGraph(registerNames, stack, allParts, parent, part.nextParts.get(0), stopPart, loops, forFinalCommands));
|
||||
return ret;
|
||||
} else if (stack.peek() instanceof StrictEqTreeItem) {
|
||||
|
||||
TreeItem switchedObject = null;
|
||||
if (!output.isEmpty()) {
|
||||
if (output.get(output.size() - 1) instanceof StoreRegisterTreeItem) {
|
||||
switchedObject = ((StoreRegisterTreeItem) output.get(output.size() - 1)).value;
|
||||
}
|
||||
}
|
||||
if (switchedObject == null) {
|
||||
switchedObject = new DirectValueTreeItem(null,-1, new Null(), null);
|
||||
}
|
||||
HashMap<Integer, TreeItem> caseValuesMap = new HashMap<Integer, TreeItem>();
|
||||
|
||||
int pos = 0;
|
||||
StrictEqTreeItem set = (StrictEqTreeItem) stack.pop();
|
||||
caseValuesMap.put(pos, set.rightSide);
|
||||
|
||||
//GraphPart switchLoc = part.nextParts.get(1).nextParts.get(0);
|
||||
List<GraphPart> caseBodyParts = new ArrayList<GraphPart>();
|
||||
caseBodyParts.add(part.nextParts.get(0));
|
||||
TreeItem top = null;
|
||||
int cnt = 1;
|
||||
while (part.nextParts.size() > 1
|
||||
&& part.nextParts.get(1).getHeight() > 1
|
||||
&& code.get(part.nextParts.get(1).end) instanceof ActionIf
|
||||
&& ((top = translatePartGetStack(part.nextParts.get(1), stack, registerNames)) instanceof StrictEqTreeItem)) {
|
||||
cnt++;
|
||||
part = part.nextParts.get(1);
|
||||
pos++;
|
||||
caseBodyParts.add(part.nextParts.get(0));
|
||||
/*List<GraphPart> subparts=part.getSubParts();
|
||||
for(GraphPart p:subparts){
|
||||
Action.actionsPartToTree(registerNames, stack, code, p.start, p.end - 1, version);
|
||||
}*/
|
||||
set = (StrictEqTreeItem) top;
|
||||
caseValuesMap.put(pos, set.rightSide);
|
||||
}
|
||||
if (cnt == 1) {
|
||||
stack.push(set);
|
||||
} else {
|
||||
part = part.nextParts.get(1);
|
||||
|
||||
GraphPart defaultPart = part;
|
||||
//caseBodyParts.add(defaultPart);
|
||||
|
||||
|
||||
|
||||
List<GraphPart> defaultAndLastPart = new ArrayList<GraphPart>();
|
||||
defaultAndLastPart.add(defaultPart);
|
||||
defaultAndLastPart.add(caseBodyParts.get(caseBodyParts.size() - 1));
|
||||
|
||||
GraphPart defaultPart2 = getCommonPart(defaultAndLastPart);
|
||||
|
||||
List<TreeItem> defaultCommands = new ArrayList<TreeItem>();
|
||||
|
||||
defaultCommands = printGraph(registerNames, stack, allParts, null, defaultPart, defaultPart2, loops, forFinalCommands);
|
||||
|
||||
|
||||
List<GraphPart> loopContinues = new ArrayList<GraphPart>();
|
||||
for (Loop l : loops) {
|
||||
if (l.loopContinue != null) {
|
||||
loopContinues.add(l.loopContinue);
|
||||
}
|
||||
}
|
||||
|
||||
List<GraphPart> breakParts = new ArrayList<GraphPart>();
|
||||
for (int g = 0; g < caseBodyParts.size(); g++) {
|
||||
if (g < caseBodyParts.size() - 1) {
|
||||
if (caseBodyParts.get(g).leadsTo(caseBodyParts.get(g + 1), loopContinues)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
GraphPart nsp = caseBodyParts.get(g).getNextSuperPartPath(loopContinues);
|
||||
if (nsp != null) {
|
||||
breakParts.add(nsp);
|
||||
}
|
||||
}
|
||||
/*GraphPart nspd=defaultPart.getNextSuperPartPath(loopContinues);
|
||||
if(nspd!=null){
|
||||
breakParts.add(nspd);
|
||||
}*/
|
||||
|
||||
Collections.sort(breakParts, new Comparator<GraphPart>() {
|
||||
@Override
|
||||
public int compare(GraphPart o1, GraphPart o2) {
|
||||
return o2.path.length() - o1.path.length();
|
||||
}
|
||||
});
|
||||
|
||||
GraphPart breakPart = breakParts.isEmpty() ? null : breakParts.get(0);
|
||||
if ((defaultPart2 != breakPart) && (defaultCommands.isEmpty())) {
|
||||
defaultPart = defaultPart2;
|
||||
}
|
||||
|
||||
|
||||
List<TreeItem> caseValues = new ArrayList<TreeItem>();
|
||||
for (int i = 0; i < caseBodyParts.size(); i++) {
|
||||
if (caseValuesMap.containsKey(i)) {
|
||||
caseValues.add(caseValuesMap.get(i));
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
List<List<TreeItem>> caseCommands = new ArrayList<List<TreeItem>>();
|
||||
GraphPart next = null;
|
||||
|
||||
|
||||
|
||||
next = breakPart;
|
||||
|
||||
TreeItem ti = checkLoop(next, stopPart, loops);
|
||||
loops.add(new Loop(null, next));
|
||||
//switchLoc.getNextPartPath(new ArrayList<GraphPart>());
|
||||
List<Integer> valuesMapping = new ArrayList<Integer>();
|
||||
List<GraphPart> caseBodies = new ArrayList<GraphPart>();
|
||||
for (int i = 0; i < caseValues.size(); i++) {
|
||||
GraphPart cur = caseBodyParts.get(i);
|
||||
if (!caseBodies.contains(cur)) {
|
||||
caseBodies.add(cur);
|
||||
}
|
||||
valuesMapping.add(caseBodies.indexOf(cur));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if (defaultPart == breakPart) {
|
||||
defaultPart = null;
|
||||
}
|
||||
if ((defaultPart != null) && (defaultCommands.isEmpty())) {
|
||||
defaultCommands = printGraph(registerNames, stack, allParts, null, defaultPart, next, loops, forFinalCommands);
|
||||
}
|
||||
|
||||
List<GraphPart> ignored = new ArrayList<GraphPart>();
|
||||
for (Loop l : loops) {
|
||||
ignored.add(l.loopContinue);
|
||||
}
|
||||
|
||||
for (int i = 0; i < caseBodies.size(); i++) {
|
||||
List<TreeItem> cc = new ArrayList<TreeItem>();
|
||||
GraphPart nextCase = null;
|
||||
nextCase = next;
|
||||
if (next != null) {
|
||||
if (i < caseBodies.size() - 1) {
|
||||
if (!caseBodies.get(i).leadsTo(caseBodies.get(i + 1), ignored)) {
|
||||
cc.add(new BreakTreeItem(null, next.start));
|
||||
} else {
|
||||
nextCase = caseBodies.get(i + 1);
|
||||
}
|
||||
} else if (!defaultCommands.isEmpty()) {
|
||||
if (!caseBodies.get(i).leadsTo(defaultPart, ignored)) {
|
||||
cc.add(new BreakTreeItem(null, next.start));
|
||||
} else {
|
||||
nextCase = defaultPart;
|
||||
}
|
||||
}
|
||||
}
|
||||
cc.addAll(0, printGraph(registerNames, stack, allParts, null, caseBodies.get(i), nextCase, loops, forFinalCommands));
|
||||
if (cc.size() >= 2) {
|
||||
if (cc.get(cc.size() - 1) instanceof BreakTreeItem) {
|
||||
if ((cc.get(cc.size() - 2) instanceof ContinueTreeItem) || (cc.get(cc.size() - 2) instanceof BreakTreeItem)) {
|
||||
cc.remove(cc.size() - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
caseCommands.add(cc);
|
||||
}
|
||||
|
||||
SwitchTreeItem sti = new SwitchTreeItem(null, next == null ? -1 : next.start, switchedObject, caseValues, caseCommands, defaultCommands, valuesMapping);
|
||||
ret.add(sti);
|
||||
|
||||
if (next != null) {
|
||||
if (ti != null) {
|
||||
ret.add(ti);
|
||||
} else {
|
||||
ret.addAll(printGraph(registerNames, stack, allParts, null, next, stopPart, loops, forFinalCommands));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
/*ins.translate*/
|
||||
}
|
||||
//((IfTypeIns)ins.definition).translateInverted(new HashMap<Integer,TreeItem>(), co.stack, ins);
|
||||
}
|
||||
|
||||
int ip = part.start;
|
||||
List<GraphPart> loopContinues = new ArrayList<GraphPart>();
|
||||
for (Loop l : loops) {
|
||||
if (l.loopContinue != null) {
|
||||
loopContinues.add(l.loopContinue);
|
||||
}
|
||||
}
|
||||
boolean loop = false;
|
||||
boolean reversed = false;
|
||||
if ((!part.nextParts.isEmpty()) && part.nextParts.get(0).leadsTo(part, loopContinues)) {
|
||||
loop = true;
|
||||
} else if ((part.nextParts.size() > 1) && part.nextParts.get(1).leadsTo(part, loopContinues)) {
|
||||
loop = true;
|
||||
reversed = true;
|
||||
}
|
||||
if (((part.nextParts.size() == 2) || ((part.nextParts.size() == 1) && loop)) && (!isSwitch)) {
|
||||
|
||||
boolean doWhile = loop;
|
||||
if (loop && output.isEmpty()) {
|
||||
doWhile = false;
|
||||
}
|
||||
Loop currentLoop = new Loop(part, null);
|
||||
if (loop) {
|
||||
loops.add(currentLoop);
|
||||
}
|
||||
|
||||
|
||||
|
||||
loopContinues = new ArrayList<GraphPart>();
|
||||
for (Loop l : loops) {
|
||||
if (l.loopContinue != null) {
|
||||
loopContinues.add(l.loopContinue);
|
||||
}
|
||||
}
|
||||
|
||||
if (part.nextParts.size() > 1) {
|
||||
currentLoop.loopBreak = part.nextParts.get(reversed ? 0 : 1);
|
||||
}
|
||||
|
||||
forFinalCommands.put(currentLoop, new ArrayList<TreeItem>());
|
||||
|
||||
int breakIp = -1;
|
||||
if (currentLoop.loopBreak != null) {
|
||||
breakIp = currentLoop.loopBreak.start;
|
||||
}
|
||||
TreeItem expr = null;
|
||||
if ((code.get(part.end) instanceof ActionJump) || (!(code.get(part.end) instanceof ActionIf))) {
|
||||
expr = new DirectValueTreeItem(null,-1, (Boolean) true, new ArrayList<String>());
|
||||
} else {
|
||||
if (stack.isEmpty()) {
|
||||
}
|
||||
expr = stack.pop();
|
||||
}
|
||||
if (doWhile) {
|
||||
ret.add(new DoWhileTreeItem(null, breakIp, part.start, output, expr));
|
||||
} else {
|
||||
ret.addAll(output);
|
||||
}
|
||||
|
||||
GraphPart next = part.getNextPartPath(loopContinues);
|
||||
|
||||
if (loop && (!doWhile)) {
|
||||
|
||||
if (reversed && (expr instanceof LogicalOp)) {
|
||||
expr = ((LogicalOp) expr).invert();
|
||||
}
|
||||
List<TreeItem> loopBody = null;
|
||||
List<TreeItem> finalCommands = null;
|
||||
GraphPart finalPart = null;
|
||||
loopBody = printGraph(registerNames, stack, allParts, part, part.nextParts.get(reversed ? 1 : 0), stopPart, loops, forFinalCommands);
|
||||
|
||||
finalCommands = forFinalCommands.get(currentLoop);
|
||||
if (!finalCommands.isEmpty()) {
|
||||
ret.add(new ForTreeItem(null, breakIp, currentLoop.loopContinue.start, new ArrayList<TreeItem>(), expr, finalCommands, loopBody));
|
||||
} /*else if ((expr instanceof HasNextTreeItem) && (!loopBody.isEmpty()) && (loopBody.get(0) instanceof SetTypeTreeItem) && (((SetTypeTreeItem) loopBody.get(0)).getValue().getNotCoerced() instanceof NextValueTreeItem)) {
|
||||
TreeItem obj = ((SetTypeTreeItem) loopBody.get(0)).getObject();
|
||||
loopBody.remove(0);
|
||||
ret.add(new ForEachInTreeItem(null, breakIp, part.start, new InTreeItem(expr.instruction, obj, ((HasNextTreeItem) expr).collection), loopBody));
|
||||
} else if ((expr instanceof HasNextTreeItem) && (!loopBody.isEmpty()) && (loopBody.get(0) instanceof SetTypeTreeItem) && (((SetTypeTreeItem) loopBody.get(0)).getValue().getNotCoerced() instanceof NextNameTreeItem)) {
|
||||
TreeItem obj = ((SetTypeTreeItem) loopBody.get(0)).getObject();
|
||||
loopBody.remove(0);
|
||||
ret.add(new ForInTreeItem(null, breakIp, part.start, new InTreeItem(expr.instruction, obj, ((HasNextTreeItem) expr).collection), loopBody));
|
||||
}*/ else {
|
||||
ret.add(new WhileTreeItem(null, breakIp, part.start, expr, loopBody));
|
||||
}
|
||||
} else if (!loop) {
|
||||
if (expr instanceof LogicalOp) {
|
||||
expr = ((LogicalOp) expr).invert();
|
||||
} else {
|
||||
expr = new NotTreeItem(null, expr);
|
||||
}
|
||||
|
||||
int stackSizeBefore = stack.size();
|
||||
Stack<TreeItem> trueStack = (Stack<TreeItem>) stack.clone();
|
||||
Stack<TreeItem> falseStack = (Stack<TreeItem>) stack.clone();
|
||||
TreeItem lopTrue = checkLoop(part.nextParts.get(1), stopPart, loops);
|
||||
TreeItem lopFalse = null;
|
||||
if (next != part.nextParts.get(0)) {
|
||||
lopFalse = checkLoop(part.nextParts.get(0), stopPart, loops);
|
||||
}
|
||||
List<TreeItem> onTrue = new ArrayList<TreeItem>();
|
||||
if (lopTrue != null) {
|
||||
onTrue.add(lopTrue);
|
||||
} else {
|
||||
if (debugMode) {
|
||||
System.err.println("ONTRUE: (inside " + part + ")");
|
||||
}
|
||||
onTrue = printGraph(registerNames, trueStack, allParts, part, part.nextParts.get(1), next == null ? stopPart : next, loops, forFinalCommands);
|
||||
if (debugMode) {
|
||||
System.err.println("/ONTRUE (inside " + part + ")");
|
||||
}
|
||||
}
|
||||
List<TreeItem> onFalse = new ArrayList<TreeItem>();
|
||||
if (lopFalse != null) {
|
||||
onFalse.add(lopFalse);
|
||||
} else {
|
||||
if (debugMode) {
|
||||
System.err.println("ONFALSE: (inside " + part + ")");
|
||||
}
|
||||
onFalse = (((next == part.nextParts.get(0)) || (part.nextParts.get(0).path.equals(part.path) || part.nextParts.get(0).path.length() < part.path.length())) ? new ArrayList<TreeItem>() : printGraph(registerNames, falseStack, allParts, part, part.nextParts.get(0), next == null ? stopPart : next, loops, forFinalCommands));
|
||||
if (debugMode) {
|
||||
System.err.println("/ONFALSE (inside " + part + ")");
|
||||
}
|
||||
}
|
||||
|
||||
if (onTrue.isEmpty() && onFalse.isEmpty() && (trueStack.size() > stackSizeBefore) && (falseStack.size() > stackSizeBefore)) {
|
||||
stack.push(new TernarOpTreeItem(null, expr, trueStack.pop(), falseStack.pop()));
|
||||
} else {
|
||||
ret.add(new IfTreeItem(null, expr, onTrue, onFalse));
|
||||
|
||||
//Same continues in onTrue and onFalse gets continue on parent level
|
||||
if ((!onTrue.isEmpty()) && (!onFalse.isEmpty())) {
|
||||
if (onTrue.get(onTrue.size() - 1) instanceof ContinueTreeItem) {
|
||||
if (onFalse.get(onFalse.size() - 1) instanceof ContinueTreeItem) {
|
||||
if (((ContinueTreeItem) onTrue.get(onTrue.size() - 1)).loopPos == ((ContinueTreeItem) onFalse.get(onFalse.size() - 1)).loopPos) {
|
||||
onTrue.remove(onTrue.size() - 1);
|
||||
ret.add(onFalse.remove(onFalse.size() - 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (loop && (part.nextParts.size() > 1)) {
|
||||
loops.remove(currentLoop); //remove loop so no break shows up
|
||||
ret.addAll(printGraph(registerNames, stack, allParts, part, part.nextParts.get(reversed ? 0 : 1), stopPart, loops, forFinalCommands));
|
||||
}
|
||||
|
||||
if (next != null) {
|
||||
TreeItem ti = checkLoop(next, stopPart, loops);
|
||||
if (ti != null) {
|
||||
ret.add(ti);
|
||||
} else {
|
||||
if (debugMode) {
|
||||
System.err.println("NEXT: (inside " + part + ")");
|
||||
}
|
||||
ret.addAll(printGraph(registerNames, stack, allParts, part, next, stopPart, loops, forFinalCommands));
|
||||
if (debugMode) {
|
||||
System.err.println("/NEXT: (inside " + part + ")");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
ret.addAll(output);
|
||||
}
|
||||
onepart:
|
||||
if (part.nextParts.size() == 1 && (!loop)) {
|
||||
|
||||
|
||||
GraphPart p = part.nextParts.get(0);
|
||||
TreeItem lop = checkLoop(p, stopPart, loops);
|
||||
if (lop == null) {
|
||||
if (p.path.length() == part.path.length()) {
|
||||
ret.addAll(printGraph(registerNames, stack, allParts, part, p, stopPart, loops, forFinalCommands));
|
||||
} else {
|
||||
if ((p != stopPart) && (p.refs.size() > 1)) {
|
||||
List<GraphPart> nextList = new ArrayList<GraphPart>();
|
||||
populateParts(p, nextList);
|
||||
Loop nearestLoop = null;
|
||||
loopn:
|
||||
for (GraphPart n : nextList) {
|
||||
for (Loop l : loops) {
|
||||
if (l.loopContinue == n) {
|
||||
nearestLoop = l;
|
||||
break loopn;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((nearestLoop != null) && (nearestLoop.loopBreak != null)) {
|
||||
List<TreeItem> finalCommands = printGraph(registerNames, stack, allParts, part, p, nearestLoop.loopContinue, loops, forFinalCommands);
|
||||
nearestLoop.loopContinue = p;
|
||||
forFinalCommands.put(nearestLoop, finalCommands);
|
||||
ContinueTreeItem cti = new ContinueTreeItem(null, nearestLoop.loopBreak.start);
|
||||
ret.add(cti);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ret.add(lop);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
private List<Integer> posCache;
|
||||
|
||||
private void buildCache() {
|
||||
posCache = new ArrayList<Integer>();
|
||||
int pos = 0;
|
||||
for (int i = 0; i < code.size(); i++) {
|
||||
posCache.add(pos);
|
||||
pos += code.get(i).getBytes(version).length;
|
||||
}
|
||||
posCache.add(pos);
|
||||
}
|
||||
|
||||
private int pos2adr(int pos) {
|
||||
if (posCache == null) {
|
||||
buildCache();
|
||||
}
|
||||
return posCache.get(pos);
|
||||
}
|
||||
|
||||
private int adr2pos(int adr) {
|
||||
if (posCache == null) {
|
||||
buildCache();
|
||||
}
|
||||
return posCache.indexOf(adr);
|
||||
}
|
||||
|
||||
private void visitCode(int ip, int lastIp, HashMap<Integer, List<Integer>> refs) {
|
||||
while (ip < code.size()) {
|
||||
refs.get(ip).add(lastIp);
|
||||
lastIp = ip;
|
||||
if (refs.get(ip).size() > 1) {
|
||||
break;
|
||||
}
|
||||
Action ins = code.get(ip);
|
||||
if (ins instanceof ActionThrow) {
|
||||
break;
|
||||
}
|
||||
if (ins instanceof ActionReturn) {
|
||||
break;
|
||||
}
|
||||
|
||||
/*if (ins.definition instanceof LookupSwitchIns) {
|
||||
try {
|
||||
for (int i = 2; i < ins.operands.length; i++) {
|
||||
visitCode(adr2pos(pos2adr(ip) + ins.operands[i]), ip, refs);
|
||||
}
|
||||
ip = adr2pos(pos2adr(ip) + ins.operands[0]);
|
||||
continue;
|
||||
} catch (ConvertException ex) {
|
||||
}
|
||||
}*/
|
||||
if (ins instanceof ActionJump) {
|
||||
ip = adr2pos(pos2adr(ip) + ins.getBytes(version).length + ((ActionJump) ins).offset);
|
||||
continue;
|
||||
} else if (ins instanceof ActionIf) {
|
||||
visitCode(adr2pos(pos2adr(ip) + ins.getBytes(version).length + ((ActionIf) ins).offset), ip, refs);
|
||||
}
|
||||
ip++;
|
||||
};
|
||||
}
|
||||
|
||||
public HashMap<Integer, List<Integer>> visitCode() {
|
||||
HashMap<Integer, List<Integer>> refs = new HashMap<Integer, List<Integer>>();
|
||||
for (int i = 0; i < code.size(); i++) {
|
||||
refs.put(i, new ArrayList<Integer>());
|
||||
}
|
||||
visitCode(0, 0, refs);
|
||||
return refs;
|
||||
}
|
||||
|
||||
private List<GraphPart> makeGraph(List<Action> actions, List<GraphPart> allBlocks) {
|
||||
HashMap<Integer, List<Integer>> refs = visitCode();
|
||||
List<GraphPart> ret = new ArrayList<GraphPart>();
|
||||
boolean visited[] = new boolean[code.size()];
|
||||
ret.add(makeGraph(null, "0", code, 0, 0, allBlocks, refs, visited));
|
||||
return ret;
|
||||
}
|
||||
|
||||
private GraphPart makeGraph(GraphPart parent, String path, List<Action> code, int startip, int lastIp, List<GraphPart> allBlocks, HashMap<Integer, List<Integer>> refs, boolean visited2[]) {
|
||||
|
||||
int ip = startip;
|
||||
for (GraphPart p : allBlocks) {
|
||||
if (p.start == ip) {
|
||||
p.refs.add(parent);
|
||||
return p;
|
||||
}
|
||||
}
|
||||
GraphPart g;
|
||||
GraphPart ret = new GraphPart(ip, -1);
|
||||
ret.path = path;
|
||||
GraphPart part = ret;
|
||||
while (ip < code.size()) {
|
||||
if (visited2[ip] || ((ip != startip) && (refs.get(ip).size() > 1))) {
|
||||
part.end = lastIp;
|
||||
GraphPart found = null;
|
||||
for (GraphPart p : allBlocks) {
|
||||
if (p.start == ip) {
|
||||
found = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
allBlocks.add(part);
|
||||
|
||||
if (found != null) {
|
||||
part.nextParts.add(found);
|
||||
found.refs.add(part);
|
||||
break;
|
||||
} else {
|
||||
GraphPart gp = new GraphPart(ip, -1);
|
||||
gp.path = path;
|
||||
part.nextParts.add(gp);
|
||||
gp.refs.add(part);
|
||||
part = gp;
|
||||
}
|
||||
}
|
||||
lastIp = ip;
|
||||
Action ins = code.get(ip);
|
||||
if ((ins instanceof ActionThrow) || (ins instanceof ActionReturn)) {
|
||||
part.end = ip;
|
||||
allBlocks.add(part);
|
||||
break;
|
||||
}
|
||||
/*if (ins.definition instanceof LookupSwitchIns) {
|
||||
part.end = ip;
|
||||
allBlocks.add(part);
|
||||
try {
|
||||
part.nextParts.add(g = makeGraph(part, path + "0", code, code.adr2pos(code.pos2adr(ip) + ins.operands[0]), ip, allBlocks, refs, visited2));
|
||||
g.refs.add(part);
|
||||
for (int i = 2; i < ins.operands.length; i++) {
|
||||
part.nextParts.add(g = makeGraph(part, path + (i - 1), code, code.adr2pos(code.pos2adr(ip) + ins.operands[i]), ip, allBlocks, refs, visited2));
|
||||
g.refs.add(part);
|
||||
}
|
||||
break;
|
||||
} catch (ConvertException ex) {
|
||||
}
|
||||
}*/
|
||||
if (ins instanceof ActionJump) {
|
||||
part.end = ip;
|
||||
allBlocks.add(part);
|
||||
int newip = adr2pos(pos2adr(ip) + ins.getBytes(version).length + ((ActionJump) ins).offset);
|
||||
part.nextParts.add(g = makeGraph(part, path, code, newip, lastIp, allBlocks, refs, visited2));
|
||||
g.refs.add(part);
|
||||
break;
|
||||
} else if (ins instanceof ActionIf) {
|
||||
part.end = ip;
|
||||
allBlocks.add(part);
|
||||
part.nextParts.add(g = makeGraph(part, path + "0", code, adr2pos(pos2adr(ip) + ins.getBytes(version).length + ((ActionIf) ins).offset), ip, allBlocks, refs, visited2));
|
||||
g.refs.add(part);
|
||||
part.nextParts.add(g = makeGraph(part, path + "1", code, ip + 1, ip, allBlocks, refs, visited2));
|
||||
g.refs.add(part);
|
||||
|
||||
break;
|
||||
}
|
||||
ip++;
|
||||
};
|
||||
if (ip == code.size()) {
|
||||
allBlocks.add(part);
|
||||
if (part.start == ip) {
|
||||
part.end = ip;
|
||||
} else {
|
||||
part.end = code.size() - 1;
|
||||
part.nextParts.add(makeGraph(part, path, code, ip, ip, allBlocks, refs, visited2));
|
||||
}
|
||||
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.jpexs.asdec.action;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class IgnoredPair {
|
||||
public Action action;
|
||||
public int pos;
|
||||
|
||||
public IgnoredPair(Action action, int pos) {
|
||||
this.action = action;
|
||||
this.pos = pos;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -36,7 +36,7 @@ public class ActionFSCommand2 extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
long numArgs = popLong(stack);
|
||||
TreeItem command = stack.pop();
|
||||
List<TreeItem> args = new ArrayList<TreeItem>();
|
||||
|
||||
@@ -61,7 +61,7 @@ public class ActionStrictMode extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
output.add(new StrictModeTreeItem(this, mode));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,9 @@ package com.jpexs.asdec.action.gui;
|
||||
|
||||
import com.jpexs.asdec.Main;
|
||||
import com.jpexs.asdec.SWF;
|
||||
import com.jpexs.asdec.abc.gui.GraphFrame;
|
||||
import com.jpexs.asdec.abc.gui.LineMarkedEditorPane;
|
||||
import com.jpexs.asdec.action.ActionGraph;
|
||||
import com.jpexs.asdec.action.TagNode;
|
||||
import com.jpexs.asdec.action.parser.ASMParser;
|
||||
import com.jpexs.asdec.action.parser.ParseException;
|
||||
@@ -54,6 +56,7 @@ public class ActionPanel extends JPanel implements TreeSelectionListener, Action
|
||||
public JButton saveButton = new JButton("Save");
|
||||
public JButton editButton = new JButton("Edit");
|
||||
public JButton cancelButton = new JButton("Cancel");
|
||||
public JButton graphButton = new JButton("Graph");
|
||||
public JButton saveHexButton = new JButton("Save hex");
|
||||
public JButton loadHexButton = new JButton("Load hex");
|
||||
public JLabel asmLabel = new JLabel("P-code source");
|
||||
@@ -63,6 +66,7 @@ public class ActionPanel extends JPanel implements TreeSelectionListener, Action
|
||||
private String lastDisasm = "";
|
||||
private boolean ignoreCarret = false;
|
||||
private boolean editMode = false;
|
||||
private List<com.jpexs.asdec.action.Action> lastCode;
|
||||
|
||||
public ActionPanel(List<Tag> list) {
|
||||
this.list = list;
|
||||
@@ -92,10 +96,13 @@ public class ActionPanel extends JPanel implements TreeSelectionListener, Action
|
||||
buttonsPan.add(editButton);
|
||||
buttonsPan.add(saveButton);
|
||||
buttonsPan.add(cancelButton);
|
||||
buttonsPan.add(graphButton);
|
||||
//buttonsPan.add(saveHexButton);
|
||||
//buttonsPan.add(loadHexButton);
|
||||
panB.add(buttonsPan, BorderLayout.SOUTH);
|
||||
|
||||
graphButton.addActionListener(this);
|
||||
graphButton.setActionCommand("GRAPH");
|
||||
saveHexButton.addActionListener(this);
|
||||
saveHexButton.setActionCommand("SAVEHEXACTION");
|
||||
loadHexButton.addActionListener(this);
|
||||
@@ -207,6 +214,7 @@ public class ActionPanel extends JPanel implements TreeSelectionListener, Action
|
||||
editor.setText(lastDisasm);
|
||||
if (Main.DO_DECOMPILE) {
|
||||
List<com.jpexs.asdec.action.Action> as = asm.getActions(SWF.DEFAULT_VERSION);
|
||||
lastCode = as;
|
||||
com.jpexs.asdec.action.Action.setActionsAddresses(as, 0, SWF.DEFAULT_VERSION);
|
||||
decompiledEditor.setText("//Decompiling...");
|
||||
String s = com.jpexs.asdec.action.Action.actionsToSource(as, SWF.DEFAULT_VERSION);
|
||||
@@ -258,7 +266,12 @@ public class ActionPanel extends JPanel implements TreeSelectionListener, Action
|
||||
}
|
||||
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (e.getActionCommand().equals("EDITACTION")) {
|
||||
if (e.getActionCommand().equals("GRAPH")) {
|
||||
if (lastCode != null) {
|
||||
GraphFrame gf = new GraphFrame(new ActionGraph(lastCode, SWF.DEFAULT_VERSION), "");
|
||||
gf.setVisible(true);
|
||||
}
|
||||
} else if (e.getActionCommand().equals("EDITACTION")) {
|
||||
setEditMode(true);
|
||||
} else if (e.getActionCommand().equals("CANCELACTION")) {
|
||||
setEditMode(false);
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.jpexs.asdec.action.parser;
|
||||
import com.jpexs.asdec.action.Action;
|
||||
import com.jpexs.asdec.action.flashlite.ActionFSCommand2;
|
||||
import com.jpexs.asdec.action.flashlite.ActionStrictMode;
|
||||
import com.jpexs.asdec.action.special.ActionNop;
|
||||
import com.jpexs.asdec.action.swf3.*;
|
||||
import com.jpexs.asdec.action.swf4.*;
|
||||
import com.jpexs.asdec.action.swf5.*;
|
||||
@@ -243,6 +244,8 @@ public class ASMParser {
|
||||
list.add(new ActionFSCommand2());
|
||||
} else if (instructionName.equals("StrictMode".toLowerCase())) {
|
||||
list.add(new ActionStrictMode(lexer));
|
||||
} else if (instructionName.equals("Nop".toLowerCase())) {
|
||||
list.add(new ActionNop());
|
||||
} else {
|
||||
throw new ParseException("Unknown instruction name :" + instructionName, lexer.yyline());
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionNop extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
output.add(new SimpleActionTreeItem(this, "nop();"));
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
//output.add(new SimpleActionTreeItem(this, "nop();"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ public class ActionGetURL extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
output.add(new GetURLTreeItem(this, urlString, targetString));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ public class ActionGoToLabel extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
output.add(new GotoLabelTreeItem(this, label));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ public class ActionGotoFrame extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
output.add(new GotoFrameTreeItem(this, frame));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionNextFrame extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
output.add(new SimpleActionTreeItem(this, "nextFrame();"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionPlay extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
output.add(new SimpleActionTreeItem(this, "Play();"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionPrevFrame extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
output.add(new SimpleActionTreeItem(this, "prevFrame();"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ public class ActionSetTarget extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
output.add(new SetTargetTreeItem(this, targetName));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionStop extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
output.add(new SimpleActionTreeItem(this, "stop();"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionStopSounds extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
output.add(new SimpleActionTreeItem(this, "stopAllSounds();"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionToggleQuality extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
output.add(new SimpleActionTreeItem(this, "toggleHighQuality();"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ public class ActionWaitForFrame extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
output.add(new WaitForFrameTreeItem(this, frame, skipCount));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionAdd extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem a = stack.pop();
|
||||
TreeItem b = stack.pop();
|
||||
stack.push(new AddTreeItem(this, b, a));
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionAnd extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem a = stack.pop();
|
||||
TreeItem b = stack.pop();
|
||||
stack.push(new AndTreeItem(this, b, a));
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionAsciiToChar extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem a = stack.pop();
|
||||
stack.push(new AsciiToCharTreeItem(this, a));
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionCall extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
output.add(new CallTreeItem(this, stack.pop()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionCharToAscii extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem a = stack.pop();
|
||||
stack.push(new CharToAsciiTreeItem(this, a));
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionCloneSprite extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem depth = stack.pop();
|
||||
TreeItem target = stack.pop();
|
||||
TreeItem source = stack.pop();
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionDivide extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem a = stack.pop();
|
||||
TreeItem b = stack.pop();
|
||||
stack.push(new DivideTreeItem(this, b, a));
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionEndDrag extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
output.add(new SimpleActionTreeItem(this, "stopDrag();"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionEquals extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem a = stack.pop();
|
||||
TreeItem b = stack.pop();
|
||||
stack.push(new EqTreeItem(this, b, a));
|
||||
|
||||
@@ -36,7 +36,7 @@ public class ActionGetProperty extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem index = stack.pop();
|
||||
TreeItem target = stack.pop();
|
||||
int indexInt = 0;
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionGetTime extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
stack.push(new SimpleActionTreeItem(this, "getTimer()"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ public class ActionGetURL2 extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem targetString = stack.pop();
|
||||
TreeItem urlString = stack.pop();
|
||||
output.add(new GetURL2TreeItem(this, urlString, targetString, sendVarsMethod, loadTargetFlag, loadTargetFlag));
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionGetVariable extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem value = stack.pop();
|
||||
stack.push(new GetVariableTreeItem(this, value));
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ public class ActionGotoFrame2 extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem frame = stack.pop();
|
||||
output.add(new GotoFrame2TreeItem(this, frame, sceneBiasFlag, playFlag, sceneBias));
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionLess extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem a = stack.pop();
|
||||
TreeItem b = stack.pop();
|
||||
stack.push(new LtTreeItem(this, b, a));
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionMBAsciiToChar extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem a = stack.pop();
|
||||
stack.push(new MBAsciiToCharTreeItem(this, a));
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionMBCharToAscii extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem a = stack.pop();
|
||||
stack.push(new MBCharToAsciiTreeItem(this, a));
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionMBStringExtract extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem count = stack.pop();
|
||||
TreeItem index = stack.pop();
|
||||
TreeItem value = stack.pop();
|
||||
|
||||
@@ -19,7 +19,7 @@ package com.jpexs.asdec.action.swf4;
|
||||
import com.jpexs.asdec.action.Action;
|
||||
import com.jpexs.asdec.action.treemodel.ConstantPool;
|
||||
import com.jpexs.asdec.action.treemodel.TreeItem;
|
||||
import com.jpexs.asdec.action.treemodel.operations.MBStringLengthTreeItem;
|
||||
import com.jpexs.asdec.action.treemodel.MBStringLengthTreeItem;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionMBStringLength extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem a = stack.pop();
|
||||
stack.push(new MBStringLengthTreeItem(this, a));
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionMultiply extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem a = stack.pop();
|
||||
TreeItem b = stack.pop();
|
||||
stack.push(new MultiplyTreeItem(this, b, a));
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionNot extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem a = stack.pop();
|
||||
stack.push(new NotTreeItem(this, a));
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionOr extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem a = stack.pop();
|
||||
TreeItem b = stack.pop();
|
||||
stack.push(new OrTreeItem(this, b, a));
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
package com.jpexs.asdec.action.swf4;
|
||||
|
||||
import com.jpexs.asdec.action.Action;
|
||||
import com.jpexs.asdec.action.treemodel.CallFunctionTreeItem;
|
||||
import com.jpexs.asdec.action.treemodel.CallMethodTreeItem;
|
||||
import com.jpexs.asdec.action.treemodel.ConstantPool;
|
||||
import com.jpexs.asdec.action.treemodel.DirectValueTreeItem;
|
||||
import com.jpexs.asdec.action.treemodel.TreeItem;
|
||||
@@ -36,13 +38,16 @@ public class ActionPop extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
if (stack.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
TreeItem val = stack.pop();
|
||||
if (!(val instanceof DirectValueTreeItem)) {
|
||||
output.add(new VoidTreeItem(this, val));
|
||||
if((val instanceof CallFunctionTreeItem)||(val instanceof CallMethodTreeItem)){
|
||||
output.add(val);
|
||||
}
|
||||
/*if (!(val instanceof DirectValueTreeItem)) {
|
||||
output.add(new VoidTreeItem(this, val));
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ public class ActionPush extends Action {
|
||||
|
||||
public List<Object> values;
|
||||
public List<String> constantPool;
|
||||
public List<Integer> ignoredParts=new ArrayList<Integer>();
|
||||
|
||||
public ActionPush(int actionLength, SWFInputStream sis, int version) throws IOException {
|
||||
super(0x96, actionLength);
|
||||
@@ -177,10 +178,15 @@ public class ActionPush extends Action {
|
||||
@Override
|
||||
public String toString() {
|
||||
String ret = "Push ";
|
||||
int pos=0;
|
||||
for (int i = 0; i < values.size(); i++) {
|
||||
if (i > 0) {
|
||||
if(ignoredParts.contains(i)){
|
||||
continue;
|
||||
}
|
||||
if (pos > 0) {
|
||||
ret += " ";
|
||||
}
|
||||
pos++;
|
||||
if (values.get(i) instanceof ConstantIndex) {
|
||||
((ConstantIndex) values.get(i)).constantPool = constantPool;
|
||||
ret += ((ConstantIndex) values.get(i)).toString();
|
||||
@@ -198,13 +204,14 @@ public class ActionPush extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
int pos=0;
|
||||
for (Object o : values) {
|
||||
if (o instanceof ConstantIndex) {
|
||||
if((constants==null)||(((ConstantIndex) o).index>=constants.constants.size())){
|
||||
if((constantPool==null)||(((ConstantIndex) o).index>=constantPool.size())){
|
||||
o="CONSTNOTFOUND";
|
||||
}else{
|
||||
o = constants.constants.get(((ConstantIndex) o).index);
|
||||
o = constantPool.get(((ConstantIndex) o).index);
|
||||
}
|
||||
}
|
||||
if (o instanceof RegisterNumber) {
|
||||
@@ -212,7 +219,8 @@ public class ActionPush extends Action {
|
||||
((RegisterNumber) o).name = regNames.get(((RegisterNumber) o).number);
|
||||
}
|
||||
}
|
||||
stack.push(new DirectValueTreeItem(this, o, constants));
|
||||
stack.push(new DirectValueTreeItem(this, pos,o, constantPool));
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionRandomNumber extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem maximum = stack.pop();
|
||||
stack.push(new RandomNumberTreeItem(this, maximum));
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionRemoveSprite extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem target = stack.pop();
|
||||
output.add(new RemoveSpriteTreeItem(this, target));
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ public class ActionSetProperty extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem value = stack.pop();
|
||||
TreeItem index = stack.pop();
|
||||
TreeItem target = stack.pop();
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionSetTarget2 extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem target = stack.pop();
|
||||
output.add(new SetTarget2TreeItem(this, target));
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionSetVariable extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem value = stack.pop();
|
||||
TreeItem name = stack.pop();
|
||||
output.add(new SetVariableTreeItem(this, name, value));
|
||||
|
||||
@@ -36,7 +36,7 @@ public class ActionStartDrag extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem target = stack.pop();
|
||||
TreeItem lockCenter = stack.pop();
|
||||
TreeItem constrain = stack.pop();
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionStringAdd extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem a = stack.pop();
|
||||
TreeItem b = stack.pop();
|
||||
stack.push(new StringAddTreeItem(this, b, a));
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionStringEquals extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem a = stack.pop();
|
||||
TreeItem b = stack.pop();
|
||||
stack.push(new StringEqTreeItem(this, b, a));
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionStringExtract extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem count = stack.pop();
|
||||
TreeItem index = stack.pop();
|
||||
TreeItem value = stack.pop();
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionStringLength extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem a = stack.pop();
|
||||
stack.push(new StringLengthTreeItem(this, a));
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionStringLess extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem a = stack.pop();
|
||||
TreeItem b = stack.pop();
|
||||
stack.push(new StringLtTreeItem(this, b, a));
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionSubtract extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem a = stack.pop();
|
||||
TreeItem b = stack.pop();
|
||||
stack.push(new SubtractTreeItem(this, b, a));
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionToInteger extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem a = stack.pop();
|
||||
stack.push(new ToIntegerTreeItem(this, a));
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionTrace extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem value = stack.pop();
|
||||
output.add(new TraceTreeItem(this, value));
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ public class ActionWaitForFrame2 extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem frame = stack.pop();
|
||||
output.add(new WaitForFrame2TreeItem(this, frame, skipCount));
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ public class RegisterNumber {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (name == null) {
|
||||
if (name == null || name.trim().equals("")) {
|
||||
return "register" + number;
|
||||
}
|
||||
return name;
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionAdd2 extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem a = stack.pop();
|
||||
TreeItem b = stack.pop();
|
||||
stack.push(new AddTreeItem(this, b, a));
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionBitAnd extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem a = stack.pop();
|
||||
TreeItem b = stack.pop();
|
||||
stack.push(new BitAndTreeItem(this, b, a));
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionBitLShift extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem a = stack.pop();
|
||||
TreeItem b = stack.pop();
|
||||
stack.push(new LShiftTreeItem(this, b, a));
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionBitOr extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem a = stack.pop();
|
||||
TreeItem b = stack.pop();
|
||||
stack.push(new BitOrTreeItem(this, b, a));
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionBitRShift extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem a = stack.pop();
|
||||
TreeItem b = stack.pop();
|
||||
stack.push(new RShiftTreeItem(this, b, a));
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionBitURShift extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem a = stack.pop();
|
||||
TreeItem b = stack.pop();
|
||||
stack.push(new URShiftTreeItem(this, b, a));
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionBitXor extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem a = stack.pop();
|
||||
TreeItem b = stack.pop();
|
||||
stack.push(new BitXorTreeItem(this, b, a));
|
||||
|
||||
@@ -36,7 +36,7 @@ public class ActionCallFunction extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem functionName = stack.pop();
|
||||
long numArgs = popLong(stack);
|
||||
List<TreeItem> args = new ArrayList<TreeItem>();
|
||||
|
||||
@@ -36,7 +36,7 @@ public class ActionCallMethod extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem methodName = stack.pop();
|
||||
TreeItem scriptObject = stack.pop();
|
||||
long numArgs = popLong(stack);
|
||||
|
||||
@@ -86,7 +86,7 @@ public class ActionConstantPool extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
constants.constants = constantPool;
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionDecrement extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem a = stack.pop();
|
||||
stack.push(new DecrementTreeItem(this, a));
|
||||
}
|
||||
|
||||
@@ -44,8 +44,10 @@ public class ActionDefineFunction extends Action {
|
||||
public List<Action> code;
|
||||
public int codeSize;
|
||||
private int version;
|
||||
public List<String> constantPool;
|
||||
|
||||
public void setConstantPool(List<String> constantPool){
|
||||
this.constantPool=constantPool;
|
||||
for(Action a:code){
|
||||
if(a instanceof ActionPush){
|
||||
((ActionPush)a).constantPool=constantPool;
|
||||
@@ -152,7 +154,14 @@ public class ActionDefineFunction extends Action {
|
||||
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, HashMap<Integer, String> regNames) {
|
||||
stack.push(new FunctionTreeItem(this, functionName, paramNames, Action.actionsToTree(regNames, code,version ), constants));
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, HashMap<Integer, String> regNames) {
|
||||
stack.push(new FunctionTreeItem(this, functionName, paramNames, Action.actionsToTree(regNames, code,version ), constantPool,1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DefineFunction";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionDefineLocal extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem value = stack.pop();
|
||||
TreeItem name = stack.pop();
|
||||
output.add(new DefineLocalTreeItem(this, name, value));
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionDefineLocal2 extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem name = stack.pop();
|
||||
output.add(new DefineLocalTreeItem(this, name, null));
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.jpexs.asdec.action.treemodel.ConstantPool;
|
||||
import com.jpexs.asdec.action.treemodel.DeleteTreeItem;
|
||||
import com.jpexs.asdec.action.treemodel.DirectValueTreeItem;
|
||||
import com.jpexs.asdec.action.treemodel.TreeItem;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
@@ -36,11 +37,11 @@ public class ActionDelete extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem propertyName = stack.pop();
|
||||
TreeItem object = stack.pop();
|
||||
|
||||
output.add(new DeleteTreeItem(this, object, propertyName));
|
||||
stack.push(new DirectValueTreeItem(this, Boolean.TRUE, constants));
|
||||
stack.push(new DirectValueTreeItem(this,-1, Boolean.TRUE, new ArrayList<String>()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.jpexs.asdec.action.treemodel.ConstantPool;
|
||||
import com.jpexs.asdec.action.treemodel.DeleteTreeItem;
|
||||
import com.jpexs.asdec.action.treemodel.DirectValueTreeItem;
|
||||
import com.jpexs.asdec.action.treemodel.TreeItem;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
@@ -36,10 +37,10 @@ public class ActionDelete2 extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem propertyName = stack.pop();
|
||||
|
||||
output.add(new DeleteTreeItem(this, null, propertyName));
|
||||
stack.push(new DirectValueTreeItem(this, Boolean.TRUE, constants));
|
||||
stack.push(new DirectValueTreeItem(this,-1, Boolean.TRUE, new ArrayList<String>()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionEnumerate extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem object = stack.pop();
|
||||
stack.push(new EnumerateTreeItem(this, object));
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionEquals2 extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem a = stack.pop();
|
||||
TreeItem b = stack.pop();
|
||||
stack.push(new EqTreeItem(this, b, a));
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionGetMember extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem functionName = stack.pop();
|
||||
TreeItem object = stack.pop();
|
||||
stack.push(new GetMemberTreeItem(this, object, functionName));
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionIncrement extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem a = stack.pop();
|
||||
stack.push(new IncrementTreeItem(this, a));
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ public class ActionInitArray extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
long numArgs = popLong(stack);
|
||||
List<TreeItem> args = new ArrayList<TreeItem>();
|
||||
for (int l = 0; l < numArgs; l++) {
|
||||
|
||||
@@ -36,7 +36,7 @@ public class ActionInitObject extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
long numArgs = popLong(stack);
|
||||
List<TreeItem> values = new ArrayList<TreeItem>();
|
||||
List<TreeItem> names = new ArrayList<TreeItem>();
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionLess2 extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem a = stack.pop();
|
||||
TreeItem b = stack.pop();
|
||||
stack.push(new LtTreeItem(this, b, a));
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionModulo extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem a = stack.pop();
|
||||
TreeItem b = stack.pop();
|
||||
stack.push(new ModuloTreeItem(this, b, a));
|
||||
|
||||
@@ -36,7 +36,7 @@ public class ActionNewMethod extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem methodName = stack.pop();
|
||||
TreeItem scriptObject = stack.pop();
|
||||
long numArgs = popLong(stack);
|
||||
|
||||
@@ -36,7 +36,7 @@ public class ActionNewObject extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem objectName = stack.pop();
|
||||
long numArgs = popLong(stack);
|
||||
List<TreeItem> args = new ArrayList<TreeItem>();
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.jpexs.asdec.action.swf5;
|
||||
|
||||
import com.jpexs.asdec.action.Action;
|
||||
import com.jpexs.asdec.action.IgnoredPair;
|
||||
import com.jpexs.asdec.action.treemodel.ConstantPool;
|
||||
import com.jpexs.asdec.action.treemodel.TreeItem;
|
||||
import java.util.List;
|
||||
@@ -34,9 +35,10 @@ public class ActionPushDuplicate extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem value = stack.pop();
|
||||
stack.push(value);
|
||||
stack.push(value);
|
||||
value.moreInstructions.add(new IgnoredPair(this,0));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionReturn extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem value = stack.pop();
|
||||
output.add(new ReturnTreeItem(this, value));
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionSetMember extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem value = stack.pop();
|
||||
TreeItem objectName = stack.pop();
|
||||
TreeItem object = stack.pop();
|
||||
|
||||
@@ -34,7 +34,7 @@ public class ActionStackSwap extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem a = stack.pop();
|
||||
TreeItem b = stack.pop();
|
||||
stack.push(a);
|
||||
|
||||
@@ -62,7 +62,7 @@ public class ActionStoreRegister extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem item = stack.peek();
|
||||
RegisterNumber rn = new RegisterNumber(registerNumber);
|
||||
if (regNames.containsKey(registerNumber)) {
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionTargetPath extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem object = stack.pop();
|
||||
stack.push(new TargetPathTreeItem(this, object));
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionToNumber extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem object = stack.pop();
|
||||
stack.push(new ToNumberTreeItem(this, object));
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionToString extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem object = stack.pop();
|
||||
stack.push(new ToStringTreeItem(this, object));
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionTypeOf extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem object = stack.pop();
|
||||
stack.push(new TypeOfTreeItem(this, object));
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionEnumerate2 extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem object = stack.pop();
|
||||
stack.push(new EnumerateTreeItem(this, object));
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionGreater extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem a = stack.pop();
|
||||
TreeItem b = stack.pop();
|
||||
stack.push(new GtTreeItem(this, b, a));
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ActionInstanceOf extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
public void translate(Stack<TreeItem> stack, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
TreeItem a = stack.pop();
|
||||
TreeItem b = stack.pop();
|
||||
stack.push(new InstanceOfTreeItem(this, b, a));
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user