mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-09-28 18:50:44 +00:00
A fix ?
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1,487 +1,487 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action;
|
||||
|
||||
import com.jpexs.decompiler.flash.BaseLocalData;
|
||||
import com.jpexs.decompiler.flash.FinalProcessLocalData;
|
||||
import com.jpexs.decompiler.flash.action.model.DirectValueActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.EnumerateActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.FunctionActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.SetTarget2ActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.SetTargetActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.SetTypeActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.StoreRegisterActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.clauses.ForInActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.clauses.TellTargetActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.operations.NeqActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.operations.StrictEqActionItem;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionEquals;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionIf;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionNot;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionPush;
|
||||
import com.jpexs.decompiler.flash.action.swf4.RegisterNumber;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionEquals2;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionStoreRegister;
|
||||
import com.jpexs.decompiler.flash.action.swf6.ActionStrictEquals;
|
||||
import com.jpexs.decompiler.flash.ecma.Null;
|
||||
import com.jpexs.decompiler.graph.Graph;
|
||||
import com.jpexs.decompiler.graph.GraphPart;
|
||||
import com.jpexs.decompiler.graph.GraphSource;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.Loop;
|
||||
import com.jpexs.decompiler.graph.TranslateStack;
|
||||
import com.jpexs.decompiler.graph.model.BreakItem;
|
||||
import com.jpexs.decompiler.graph.model.ContinueItem;
|
||||
import com.jpexs.decompiler.graph.model.SwitchItem;
|
||||
import com.jpexs.decompiler.graph.model.WhileItem;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class ActionGraph extends Graph {
|
||||
|
||||
public ActionGraph(List<Action> code, HashMap<Integer, String> registerNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int version) {
|
||||
super(new ActionGraphSource(code, version, registerNames, variables, functions), new ArrayList<Integer>());
|
||||
//this.version = version;
|
||||
/*heads = makeGraph(code, new ArrayList<GraphPart>());
|
||||
for (GraphPart head : heads) {
|
||||
fixGraph(head);
|
||||
makeMulti(head, new ArrayList<GraphPart>());
|
||||
}*/
|
||||
}
|
||||
|
||||
public static List<GraphTargetItem> translateViaGraph(HashMap<Integer, String> registerNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, List<Action> code, int version, int staticOperation, String path) throws InterruptedException {
|
||||
|
||||
ActionGraph g = new ActionGraph(code, registerNames, variables, functions, version);
|
||||
ActionLocalData localData = new ActionLocalData(registerNames);
|
||||
g.init(localData);
|
||||
return g.translate(localData, staticOperation, path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finalProcessStack(TranslateStack stack, List<GraphTargetItem> output) {
|
||||
if (stack.size() > 0) {
|
||||
for (int i = stack.size() - 1; i >= 0; i--) {
|
||||
//System.err.println(stack.get(i));
|
||||
if (stack.get(i) instanceof FunctionActionItem) {
|
||||
FunctionActionItem f = (FunctionActionItem) stack.remove(i);
|
||||
if (!output.contains(f)) {
|
||||
output.add(0, f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalProcess(List<GraphTargetItem> list, int level, FinalProcessLocalData localData) {
|
||||
super.finalProcess(list, level, localData);
|
||||
List<GraphTargetItem> ret = Action.checkClass(list);
|
||||
if (ret != list) {
|
||||
list.clear();
|
||||
list.addAll(ret);
|
||||
}
|
||||
int targetStart;
|
||||
int targetEnd;
|
||||
|
||||
boolean again;
|
||||
do {
|
||||
again = false;
|
||||
targetStart = -1;
|
||||
targetEnd = -1;
|
||||
GraphTargetItem targetStartItem = null;
|
||||
GraphTargetItem target = null;
|
||||
for (int t = 0; t < list.size(); t++) {
|
||||
GraphTargetItem it = list.get(t);
|
||||
if (it instanceof SetTargetActionItem) {
|
||||
SetTargetActionItem st = (SetTargetActionItem) it;
|
||||
if (st.target.isEmpty()) {
|
||||
if (targetStart > -1) {
|
||||
targetEnd = t;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
target = new DirectValueActionItem(null, 0, st.target, new ArrayList<>());
|
||||
targetStart = t;
|
||||
targetStartItem = it;
|
||||
}
|
||||
}
|
||||
if (it instanceof SetTarget2ActionItem) {
|
||||
SetTarget2ActionItem st = (SetTarget2ActionItem) it;
|
||||
if ((st.target instanceof DirectValueActionItem) && st.target.getResult().equals("")) {
|
||||
if (targetStart > -1) {
|
||||
targetEnd = t;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
targetStart = t;
|
||||
target = st.target;
|
||||
targetStartItem = it;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((targetStart > -1) && (targetEnd > -1)) {
|
||||
List<GraphTargetItem> newlist = new ArrayList<>();
|
||||
for (int i = 0; i < targetStart; i++) {
|
||||
newlist.add(list.get(i));
|
||||
}
|
||||
List<GraphTargetItem> tellist = new ArrayList<>();
|
||||
for (int i = targetStart + 1; i < targetEnd; i++) {
|
||||
tellist.add(list.get(i));
|
||||
}
|
||||
newlist.add(new TellTargetActionItem(targetStartItem.src, target, tellist));
|
||||
for (int i = targetEnd + 1; i < list.size(); i++) {
|
||||
newlist.add(list.get(i));
|
||||
}
|
||||
list.clear();
|
||||
list.addAll(newlist);
|
||||
again = true;
|
||||
}
|
||||
} while (again);
|
||||
for (int t = 0; t < list.size(); t++) {
|
||||
GraphTargetItem it = list.get(t);
|
||||
|
||||
if (it instanceof WhileItem) {
|
||||
WhileItem wi = (WhileItem) it;
|
||||
if ((!wi.commands.isEmpty()) && (wi.commands.get(0) instanceof SetTypeActionItem)) {
|
||||
SetTypeActionItem sti = (SetTypeActionItem) wi.commands.get(0);
|
||||
if (wi.expression.get(wi.expression.size() - 1) instanceof NeqActionItem) {
|
||||
NeqActionItem ne = (NeqActionItem) wi.expression.get(wi.expression.size() - 1);
|
||||
if (ne.rightSide instanceof DirectValueActionItem) {
|
||||
DirectValueActionItem dv = (DirectValueActionItem) ne.rightSide;
|
||||
if (dv.value instanceof Null) {
|
||||
GraphTargetItem en = ne.leftSide;
|
||||
if (en instanceof StoreRegisterActionItem) {
|
||||
en = ((StoreRegisterActionItem) en).value;
|
||||
}
|
||||
if (en instanceof EnumerateActionItem) {
|
||||
EnumerateActionItem eti = (EnumerateActionItem) en;
|
||||
list.remove(t);
|
||||
wi.commands.remove(0);
|
||||
list.add(t, new ForInActionItem(null, wi.loop, sti.getObject(), eti.object, wi.commands));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
//detectChained(list, temporaryRegisters);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<GraphPart> checkPrecoNextParts(GraphPart part) {
|
||||
List<GraphSourceItem> items = getPartItems(part);
|
||||
part = makeMultiPart(part);
|
||||
if (items.size() > 1) {
|
||||
if (items.get(items.size() - 1) instanceof ActionIf) {
|
||||
if (items.get(items.size() - 2) instanceof ActionStrictEquals) {
|
||||
List<Integer> storeRegisters = new ArrayList<>();
|
||||
for (GraphSourceItem s : items) {
|
||||
if (s instanceof ActionStoreRegister) {
|
||||
ActionStoreRegister sr = (ActionStoreRegister) s;
|
||||
storeRegisters.add(sr.registerNumber);
|
||||
}
|
||||
}
|
||||
if (!storeRegisters.isEmpty()) {
|
||||
List<GraphPart> caseBodies = new ArrayList<>();
|
||||
boolean proceed = false;
|
||||
do {
|
||||
proceed = false;
|
||||
caseBodies.add(part.nextParts.get(0)); //jump
|
||||
part = part.nextParts.get(1); //nojump
|
||||
items = getPartItems(part);
|
||||
part = makeMultiPart(part);
|
||||
if (!items.isEmpty()) {
|
||||
if (items.get(0) instanceof ActionPush) {
|
||||
ActionPush pu = (ActionPush) items.get(0);
|
||||
if (!pu.values.isEmpty()) {
|
||||
if (pu.values.get(0) instanceof RegisterNumber) {
|
||||
RegisterNumber rn = (RegisterNumber) pu.values.get(0);
|
||||
if (storeRegisters.contains(rn.number)) {
|
||||
storeRegisters.clear();
|
||||
storeRegisters.add(rn.number);
|
||||
if (items.get(items.size() - 1) instanceof ActionIf) {
|
||||
if (items.size() > 1) {
|
||||
if (items.get(items.size() - 2) instanceof ActionStrictEquals) {
|
||||
proceed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (proceed);
|
||||
|
||||
if (caseBodies.size() > 1) {
|
||||
caseBodies.add(part); //TODO: properly detect default clause (?)
|
||||
return caseBodies;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<GraphTargetItem> check(GraphSource code, BaseLocalData localData, List<GraphPart> allParts, TranslateStack stack, GraphPart parent, GraphPart part, List<GraphPart> stopPart, List<Loop> loops, List<GraphTargetItem> output, Loop currentLoop, int staticOperation, String path) throws InterruptedException {
|
||||
if (!output.isEmpty()) {
|
||||
if (output.get(output.size() - 1) instanceof StoreRegisterActionItem) {
|
||||
StoreRegisterActionItem str = (StoreRegisterActionItem) output.get(output.size() - 1);
|
||||
if (str.value instanceof EnumerateActionItem) {
|
||||
output.remove(output.size() - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
List<GraphTargetItem> ret = null;
|
||||
if ((part.nextParts.size() == 2) && (!stack.isEmpty()) && (stack.peek() instanceof StrictEqActionItem)) {
|
||||
|
||||
GraphTargetItem switchedObject = null;
|
||||
if (!output.isEmpty()) {
|
||||
if (output.get(output.size() - 1) instanceof StoreRegisterActionItem) {
|
||||
switchedObject = ((StoreRegisterActionItem) output.get(output.size() - 1)).value;
|
||||
}
|
||||
}
|
||||
if (switchedObject == null) {
|
||||
switchedObject = new DirectValueActionItem(null, -1, new Null(), null);
|
||||
}
|
||||
HashMap<Integer, GraphTargetItem> caseValuesMap = new HashMap<>();
|
||||
|
||||
int pos = 0;
|
||||
StrictEqActionItem set = (StrictEqActionItem) stack.pop();
|
||||
caseValuesMap.put(pos, set.rightSide);
|
||||
if (set.leftSide instanceof StoreRegisterActionItem) {
|
||||
switchedObject = ((StoreRegisterActionItem) set.leftSide).value;
|
||||
}
|
||||
//GraphPart switchLoc = part.nextParts.get(1).nextParts.get(0);
|
||||
List<GraphPart> caseBodyParts = new ArrayList<>();
|
||||
caseBodyParts.add(part.nextParts.get(0));
|
||||
GraphTargetItem top = null;
|
||||
int cnt = 1;
|
||||
while (part.nextParts.size() > 1
|
||||
&& part.nextParts.get(1).getHeight() > 1
|
||||
&& code.get(part.nextParts.get(1).end >= code.size() ? code.size() - 1 : part.nextParts.get(1).end) instanceof ActionIf
|
||||
&& ((top = translatePartGetStack(localData, part.nextParts.get(1), stack, staticOperation)) instanceof StrictEqActionItem)) {
|
||||
cnt++;
|
||||
part = part.nextParts.get(1);
|
||||
pos++;
|
||||
caseBodyParts.add(part.nextParts.get(0));
|
||||
|
||||
set = (StrictEqActionItem) top;
|
||||
caseValuesMap.put(pos, set.rightSide);
|
||||
}
|
||||
if (cnt == 1) {
|
||||
stack.push(set);
|
||||
} else {
|
||||
part = part.nextParts.get(1);
|
||||
|
||||
GraphPart defaultPart = part; //21-21
|
||||
//caseBodyParts.add(defaultPart);
|
||||
|
||||
List<GraphPart> defaultAndLastPart = new ArrayList<>();
|
||||
defaultAndLastPart.add(defaultPart);
|
||||
defaultAndLastPart.add(caseBodyParts.get(caseBodyParts.size() - 1));
|
||||
|
||||
GraphPart defaultPart2 = getCommonPart(localData, defaultAndLastPart, loops);//34-37
|
||||
|
||||
List<GraphTargetItem> defaultCommands = new ArrayList<>();
|
||||
List<GraphPart> stopPart2 = new ArrayList<>(stopPart);
|
||||
stopPart2.add(defaultPart2);
|
||||
defaultCommands = printGraph(localData, stack, allParts, null, defaultPart, stopPart2, loops, staticOperation, path);
|
||||
|
||||
List<GraphPart> loopContinues = new ArrayList<>();
|
||||
for (Loop l : loops) {
|
||||
if (l.loopContinue != null) {
|
||||
loopContinues.add(l.loopContinue);
|
||||
}
|
||||
}
|
||||
|
||||
List<GraphPart> breakParts = new ArrayList<>();
|
||||
/*for (int g = 0; g < caseBodyParts.size(); g++) {
|
||||
if (g < caseBodyParts.size() - 1) {
|
||||
if (caseBodyParts.get(g).leadsTo(code, caseBodyParts.get(g + 1), loops)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
GraphPart nsp = caseBodyParts.get(g).getNextSuperPartPath(loopContinues);
|
||||
if (nsp != null) {
|
||||
breakParts.add(nsp);
|
||||
}
|
||||
}
|
||||
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);
|
||||
List<GraphPart> mcp = new ArrayList<>();
|
||||
mcp.addAll(caseBodyParts);
|
||||
if (defaultPart2 != null) {
|
||||
mcp.add(defaultPart2);
|
||||
}
|
||||
GraphPart breakPart = getMostCommonPart(localData, mcp, loops);
|
||||
if ((defaultPart2 != breakPart) && (defaultCommands.isEmpty())) {
|
||||
defaultPart = defaultPart2;
|
||||
}
|
||||
|
||||
List<GraphTargetItem> caseValues = new ArrayList<>();
|
||||
for (int i = 0; i < caseBodyParts.size(); i++) {
|
||||
if (caseValuesMap.containsKey(i)) {
|
||||
caseValues.add(caseValuesMap.get(i));
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
List<List<GraphTargetItem>> caseCommands = new ArrayList<>();
|
||||
GraphPart next = null;
|
||||
|
||||
next = breakPart;
|
||||
|
||||
GraphTargetItem ti = checkLoop(next, stopPart, loops);
|
||||
currentLoop = new Loop(loops.size(), null, next);
|
||||
currentLoop.phase = 1;
|
||||
loops.add(currentLoop);
|
||||
//switchLoc.getNextPartPath(new ArrayList<GraphPart>());
|
||||
List<Integer> valuesMapping = new ArrayList<>();
|
||||
List<GraphPart> caseBodies = new ArrayList<>();
|
||||
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())) {
|
||||
List<GraphPart> stopPart2x = new ArrayList<>(stopPart);
|
||||
stopPart2x.add(next);
|
||||
defaultCommands = printGraph(localData, stack, allParts, null, defaultPart, stopPart2x, loops, staticOperation, path);
|
||||
}
|
||||
|
||||
if (!defaultCommands.isEmpty()) {
|
||||
if (defaultCommands.get(defaultCommands.size() - 1) instanceof BreakItem) {
|
||||
BreakItem bi = (BreakItem) defaultCommands.get(defaultCommands.size() - 1);
|
||||
if (bi.loopId == currentLoop.id) {
|
||||
defaultCommands.remove(defaultCommands.size() - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<GraphPart> ignored = new ArrayList<>();
|
||||
for (Loop l : loops) {
|
||||
ignored.add(l.loopContinue);
|
||||
}
|
||||
|
||||
for (int i = 0; i < caseBodies.size(); i++) {
|
||||
List<GraphTargetItem> cc = new ArrayList<>();
|
||||
GraphPart nextCase = null;
|
||||
nextCase = next;
|
||||
if (next != null) {
|
||||
if (i < caseBodies.size() - 1) {
|
||||
if (!caseBodies.get(i).leadsTo(localData, this, code, caseBodies.get(i + 1), loops)) {
|
||||
cc.add(new BreakItem(null, currentLoop.id));
|
||||
} else {
|
||||
nextCase = caseBodies.get(i + 1);
|
||||
}
|
||||
} else if (!defaultCommands.isEmpty()) {
|
||||
if (!caseBodies.get(i).leadsTo(localData, this, code, defaultPart, loops)) {
|
||||
cc.add(new BreakItem(null, currentLoop.id));
|
||||
} else {
|
||||
nextCase = defaultPart;
|
||||
}
|
||||
}
|
||||
}
|
||||
List<GraphPart> stopPart2x = new ArrayList<>(stopPart);
|
||||
//stopPart2.add(nextCase);
|
||||
for (GraphPart b : caseBodies) {
|
||||
if (b != caseBodies.get(i)) {
|
||||
stopPart2x.add(b);
|
||||
}
|
||||
}
|
||||
if (defaultPart != null) {
|
||||
stopPart2x.add(defaultPart);
|
||||
}
|
||||
if (breakPart != null) {
|
||||
stopPart2x.add(breakPart);
|
||||
}
|
||||
cc.addAll(0, printGraph(localData, stack, allParts, null, caseBodies.get(i), stopPart2x, loops, staticOperation, path));
|
||||
if (cc.size() >= 2) {
|
||||
if (cc.get(cc.size() - 1) instanceof BreakItem) {
|
||||
if ((cc.get(cc.size() - 2) instanceof ContinueItem) || (cc.get(cc.size() - 2) instanceof BreakItem)) {
|
||||
cc.remove(cc.size() - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
caseCommands.add(cc);
|
||||
}
|
||||
ret = new ArrayList<>();
|
||||
ret.addAll(output);
|
||||
SwitchItem sti = new SwitchItem(null, currentLoop, switchedObject, caseValues, caseCommands, defaultCommands, valuesMapping);
|
||||
ret.add(sti);
|
||||
currentLoop.phase = 2;
|
||||
if (next != null) {
|
||||
if (ti != null) {
|
||||
ret.add(ti);
|
||||
} else {
|
||||
ret.addAll(printGraph(localData, stack, allParts, null, next, stopPart, loops, staticOperation, path));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int checkIp(int ip) {
|
||||
int oldIp = ip;
|
||||
//return in for..in
|
||||
GraphSourceItem action = code.get(ip);
|
||||
if ((action instanceof ActionPush) && (((ActionPush) action).values.size() == 1) && (((ActionPush) action).values.get(0) instanceof Null)) {
|
||||
if (ip + 3 < code.size()) {
|
||||
if ((code.get(ip + 1) instanceof ActionEquals) || (code.get(ip + 1) instanceof ActionEquals2)) {
|
||||
if (code.get(ip + 2) instanceof ActionNot) {
|
||||
if (code.get(ip + 3) instanceof ActionIf) {
|
||||
ActionIf aif = (ActionIf) code.get(ip + 3);
|
||||
if (code.adr2pos(code.pos2adr(ip + 4) + aif.getJumpOffset()) == ip) {
|
||||
ip += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (oldIp != ip) {
|
||||
return checkIp(ip);
|
||||
}
|
||||
return ip;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action;
|
||||
|
||||
import com.jpexs.decompiler.flash.BaseLocalData;
|
||||
import com.jpexs.decompiler.flash.FinalProcessLocalData;
|
||||
import com.jpexs.decompiler.flash.action.model.DirectValueActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.EnumerateActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.FunctionActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.SetTarget2ActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.SetTargetActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.SetTypeActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.StoreRegisterActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.clauses.ForInActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.clauses.TellTargetActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.operations.NeqActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.operations.StrictEqActionItem;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionEquals;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionIf;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionNot;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionPush;
|
||||
import com.jpexs.decompiler.flash.action.swf4.RegisterNumber;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionEquals2;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionStoreRegister;
|
||||
import com.jpexs.decompiler.flash.action.swf6.ActionStrictEquals;
|
||||
import com.jpexs.decompiler.flash.ecma.Null;
|
||||
import com.jpexs.decompiler.graph.Graph;
|
||||
import com.jpexs.decompiler.graph.GraphPart;
|
||||
import com.jpexs.decompiler.graph.GraphSource;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.Loop;
|
||||
import com.jpexs.decompiler.graph.TranslateStack;
|
||||
import com.jpexs.decompiler.graph.model.BreakItem;
|
||||
import com.jpexs.decompiler.graph.model.ContinueItem;
|
||||
import com.jpexs.decompiler.graph.model.SwitchItem;
|
||||
import com.jpexs.decompiler.graph.model.WhileItem;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class ActionGraph extends Graph {
|
||||
|
||||
public ActionGraph(List<Action> code, HashMap<Integer, String> registerNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int version) {
|
||||
super(new ActionGraphSource(code, version, registerNames, variables, functions), new ArrayList<Integer>());
|
||||
//this.version = version;
|
||||
/*heads = makeGraph(code, new ArrayList<GraphPart>());
|
||||
for (GraphPart head : heads) {
|
||||
fixGraph(head);
|
||||
makeMulti(head, new ArrayList<GraphPart>());
|
||||
}*/
|
||||
}
|
||||
|
||||
public static List<GraphTargetItem> translateViaGraph(HashMap<Integer, String> registerNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, List<Action> code, int version, int staticOperation, String path) throws InterruptedException {
|
||||
|
||||
ActionGraph g = new ActionGraph(code, registerNames, variables, functions, version);
|
||||
ActionLocalData localData = new ActionLocalData(registerNames);
|
||||
g.init(localData);
|
||||
return g.translate(localData, staticOperation, path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finalProcessStack(TranslateStack stack, List<GraphTargetItem> output) {
|
||||
if (stack.size() > 0) {
|
||||
for (int i = stack.size() - 1; i >= 0; i--) {
|
||||
//System.err.println(stack.get(i));
|
||||
if (stack.get(i) instanceof FunctionActionItem) {
|
||||
FunctionActionItem f = (FunctionActionItem) stack.remove(i);
|
||||
if (!output.contains(f)) {
|
||||
output.add(0, f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalProcess(List<GraphTargetItem> list, int level, FinalProcessLocalData localData) {
|
||||
super.finalProcess(list, level, localData);
|
||||
List<GraphTargetItem> ret = Action.checkClass(list);
|
||||
if (ret != list) {
|
||||
list.clear();
|
||||
list.addAll(ret);
|
||||
}
|
||||
int targetStart;
|
||||
int targetEnd;
|
||||
|
||||
boolean again;
|
||||
do {
|
||||
again = false;
|
||||
targetStart = -1;
|
||||
targetEnd = -1;
|
||||
GraphTargetItem targetStartItem = null;
|
||||
GraphTargetItem target = null;
|
||||
for (int t = 0; t < list.size(); t++) {
|
||||
GraphTargetItem it = list.get(t);
|
||||
if (it instanceof SetTargetActionItem) {
|
||||
SetTargetActionItem st = (SetTargetActionItem) it;
|
||||
if (st.target.isEmpty()) {
|
||||
if (targetStart > -1) {
|
||||
targetEnd = t;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
target = new DirectValueActionItem(null, 0, st.target, new ArrayList<>());
|
||||
targetStart = t;
|
||||
targetStartItem = it;
|
||||
}
|
||||
}
|
||||
if (it instanceof SetTarget2ActionItem) {
|
||||
SetTarget2ActionItem st = (SetTarget2ActionItem) it;
|
||||
if ((st.target instanceof DirectValueActionItem) && st.target.getResult().equals("")) {
|
||||
if (targetStart > -1) {
|
||||
targetEnd = t;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
targetStart = t;
|
||||
target = st.target;
|
||||
targetStartItem = it;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((targetStart > -1) && (targetEnd > -1)) {
|
||||
List<GraphTargetItem> newlist = new ArrayList<>();
|
||||
for (int i = 0; i < targetStart; i++) {
|
||||
newlist.add(list.get(i));
|
||||
}
|
||||
List<GraphTargetItem> tellist = new ArrayList<>();
|
||||
for (int i = targetStart + 1; i < targetEnd; i++) {
|
||||
tellist.add(list.get(i));
|
||||
}
|
||||
newlist.add(new TellTargetActionItem(targetStartItem.src, target, tellist));
|
||||
for (int i = targetEnd + 1; i < list.size(); i++) {
|
||||
newlist.add(list.get(i));
|
||||
}
|
||||
list.clear();
|
||||
list.addAll(newlist);
|
||||
again = true;
|
||||
}
|
||||
} while (again);
|
||||
for (int t = 0; t < list.size(); t++) {
|
||||
GraphTargetItem it = list.get(t);
|
||||
|
||||
if (it instanceof WhileItem) {
|
||||
WhileItem wi = (WhileItem) it;
|
||||
if ((!wi.commands.isEmpty()) && (wi.commands.get(0) instanceof SetTypeActionItem)) {
|
||||
SetTypeActionItem sti = (SetTypeActionItem) wi.commands.get(0);
|
||||
if (wi.expression.get(wi.expression.size() - 1) instanceof NeqActionItem) {
|
||||
NeqActionItem ne = (NeqActionItem) wi.expression.get(wi.expression.size() - 1);
|
||||
if (ne.rightSide instanceof DirectValueActionItem) {
|
||||
DirectValueActionItem dv = (DirectValueActionItem) ne.rightSide;
|
||||
if (dv.value instanceof Null) {
|
||||
GraphTargetItem en = ne.leftSide;
|
||||
if (en instanceof StoreRegisterActionItem) {
|
||||
en = ((StoreRegisterActionItem) en).value;
|
||||
}
|
||||
if (en instanceof EnumerateActionItem) {
|
||||
EnumerateActionItem eti = (EnumerateActionItem) en;
|
||||
list.remove(t);
|
||||
wi.commands.remove(0);
|
||||
list.add(t, new ForInActionItem(null, wi.loop, sti.getObject(), eti.object, wi.commands));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
//detectChained(list, temporaryRegisters);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<GraphPart> checkPrecoNextParts(GraphPart part) {
|
||||
List<GraphSourceItem> items = getPartItems(part);
|
||||
part = makeMultiPart(part);
|
||||
if (items.size() > 1) {
|
||||
if (items.get(items.size() - 1) instanceof ActionIf) {
|
||||
if (items.get(items.size() - 2) instanceof ActionStrictEquals) {
|
||||
List<Integer> storeRegisters = new ArrayList<>();
|
||||
for (GraphSourceItem s : items) {
|
||||
if (s instanceof ActionStoreRegister) {
|
||||
ActionStoreRegister sr = (ActionStoreRegister) s;
|
||||
storeRegisters.add(sr.registerNumber);
|
||||
}
|
||||
}
|
||||
if (!storeRegisters.isEmpty()) {
|
||||
List<GraphPart> caseBodies = new ArrayList<>();
|
||||
boolean proceed = false;
|
||||
do {
|
||||
proceed = false;
|
||||
caseBodies.add(part.nextParts.get(0)); //jump
|
||||
part = part.nextParts.get(1); //nojump
|
||||
items = getPartItems(part);
|
||||
part = makeMultiPart(part);
|
||||
if (!items.isEmpty()) {
|
||||
if (items.get(0) instanceof ActionPush) {
|
||||
ActionPush pu = (ActionPush) items.get(0);
|
||||
if (!pu.values.isEmpty()) {
|
||||
if (pu.values.get(0) instanceof RegisterNumber) {
|
||||
RegisterNumber rn = (RegisterNumber) pu.values.get(0);
|
||||
if (storeRegisters.contains(rn.number)) {
|
||||
storeRegisters.clear();
|
||||
storeRegisters.add(rn.number);
|
||||
if (items.get(items.size() - 1) instanceof ActionIf) {
|
||||
if (items.size() > 1) {
|
||||
if (items.get(items.size() - 2) instanceof ActionStrictEquals) {
|
||||
proceed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (proceed);
|
||||
|
||||
if (caseBodies.size() > 1) {
|
||||
caseBodies.add(part); //TODO: properly detect default clause (?)
|
||||
return caseBodies;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<GraphTargetItem> check(GraphSource code, BaseLocalData localData, List<GraphPart> allParts, TranslateStack stack, GraphPart parent, GraphPart part, List<GraphPart> stopPart, List<Loop> loops, List<GraphTargetItem> output, Loop currentLoop, int staticOperation, String path) throws InterruptedException {
|
||||
if (!output.isEmpty()) {
|
||||
if (output.get(output.size() - 1) instanceof StoreRegisterActionItem) {
|
||||
StoreRegisterActionItem str = (StoreRegisterActionItem) output.get(output.size() - 1);
|
||||
if (str.value instanceof EnumerateActionItem) {
|
||||
output.remove(output.size() - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
List<GraphTargetItem> ret = null;
|
||||
if ((part.nextParts.size() == 2) && (!stack.isEmpty()) && (stack.peek() instanceof StrictEqActionItem)) {
|
||||
|
||||
GraphTargetItem switchedObject = null;
|
||||
if (!output.isEmpty()) {
|
||||
if (output.get(output.size() - 1) instanceof StoreRegisterActionItem) {
|
||||
switchedObject = ((StoreRegisterActionItem) output.get(output.size() - 1)).value;
|
||||
}
|
||||
}
|
||||
if (switchedObject == null) {
|
||||
switchedObject = new DirectValueActionItem(null, -1, new Null(), null);
|
||||
}
|
||||
HashMap<Integer, GraphTargetItem> caseValuesMap = new HashMap<>();
|
||||
|
||||
int pos = 0;
|
||||
StrictEqActionItem set = (StrictEqActionItem) stack.pop();
|
||||
caseValuesMap.put(pos, set.rightSide);
|
||||
if (set.leftSide instanceof StoreRegisterActionItem) {
|
||||
switchedObject = ((StoreRegisterActionItem) set.leftSide).value;
|
||||
}
|
||||
//GraphPart switchLoc = part.nextParts.get(1).nextParts.get(0);
|
||||
List<GraphPart> caseBodyParts = new ArrayList<>();
|
||||
caseBodyParts.add(part.nextParts.get(0));
|
||||
GraphTargetItem top = null;
|
||||
int cnt = 1;
|
||||
while (part.nextParts.size() > 1
|
||||
&& part.nextParts.get(1).getHeight() > 1
|
||||
&& code.get(part.nextParts.get(1).end >= code.size() ? code.size() - 1 : part.nextParts.get(1).end) instanceof ActionIf
|
||||
&& ((top = translatePartGetStack(localData, part.nextParts.get(1), stack, staticOperation)) instanceof StrictEqActionItem)) {
|
||||
cnt++;
|
||||
part = part.nextParts.get(1);
|
||||
pos++;
|
||||
caseBodyParts.add(part.nextParts.get(0));
|
||||
|
||||
set = (StrictEqActionItem) top;
|
||||
caseValuesMap.put(pos, set.rightSide);
|
||||
}
|
||||
if (cnt == 1) {
|
||||
stack.push(set);
|
||||
} else {
|
||||
part = part.nextParts.get(1);
|
||||
|
||||
GraphPart defaultPart = part; //21-21
|
||||
//caseBodyParts.add(defaultPart);
|
||||
|
||||
List<GraphPart> defaultAndLastPart = new ArrayList<>();
|
||||
defaultAndLastPart.add(defaultPart);
|
||||
defaultAndLastPart.add(caseBodyParts.get(caseBodyParts.size() - 1));
|
||||
|
||||
GraphPart defaultPart2 = getCommonPart(localData, defaultAndLastPart, loops);//34-37
|
||||
|
||||
List<GraphTargetItem> defaultCommands = new ArrayList<>();
|
||||
List<GraphPart> stopPart2 = new ArrayList<>(stopPart);
|
||||
stopPart2.add(defaultPart2);
|
||||
defaultCommands = printGraph(localData, stack, allParts, null, defaultPart, stopPart2, loops, staticOperation, path);
|
||||
|
||||
List<GraphPart> loopContinues = new ArrayList<>();
|
||||
for (Loop l : loops) {
|
||||
if (l.loopContinue != null) {
|
||||
loopContinues.add(l.loopContinue);
|
||||
}
|
||||
}
|
||||
|
||||
List<GraphPart> breakParts = new ArrayList<>();
|
||||
/*for (int g = 0; g < caseBodyParts.size(); g++) {
|
||||
if (g < caseBodyParts.size() - 1) {
|
||||
if (caseBodyParts.get(g).leadsTo(code, caseBodyParts.get(g + 1), loops)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
GraphPart nsp = caseBodyParts.get(g).getNextSuperPartPath(loopContinues);
|
||||
if (nsp != null) {
|
||||
breakParts.add(nsp);
|
||||
}
|
||||
}
|
||||
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);
|
||||
List<GraphPart> mcp = new ArrayList<>();
|
||||
mcp.addAll(caseBodyParts);
|
||||
if (defaultPart2 != null) {
|
||||
mcp.add(defaultPart2);
|
||||
}
|
||||
GraphPart breakPart = getMostCommonPart(localData, mcp, loops);
|
||||
if ((defaultPart2 != breakPart) && (defaultCommands.isEmpty())) {
|
||||
defaultPart = defaultPart2;
|
||||
}
|
||||
|
||||
List<GraphTargetItem> caseValues = new ArrayList<>();
|
||||
for (int i = 0; i < caseBodyParts.size(); i++) {
|
||||
if (caseValuesMap.containsKey(i)) {
|
||||
caseValues.add(caseValuesMap.get(i));
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
List<List<GraphTargetItem>> caseCommands = new ArrayList<>();
|
||||
GraphPart next = null;
|
||||
|
||||
next = breakPart;
|
||||
|
||||
GraphTargetItem ti = checkLoop(next, stopPart, loops);
|
||||
currentLoop = new Loop(loops.size(), null, next);
|
||||
currentLoop.phase = 1;
|
||||
loops.add(currentLoop);
|
||||
//switchLoc.getNextPartPath(new ArrayList<GraphPart>());
|
||||
List<Integer> valuesMapping = new ArrayList<>();
|
||||
List<GraphPart> caseBodies = new ArrayList<>();
|
||||
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())) {
|
||||
List<GraphPart> stopPart2x = new ArrayList<>(stopPart);
|
||||
stopPart2x.add(next);
|
||||
defaultCommands = printGraph(localData, stack, allParts, null, defaultPart, stopPart2x, loops, staticOperation, path);
|
||||
}
|
||||
|
||||
if (!defaultCommands.isEmpty()) {
|
||||
if (defaultCommands.get(defaultCommands.size() - 1) instanceof BreakItem) {
|
||||
BreakItem bi = (BreakItem) defaultCommands.get(defaultCommands.size() - 1);
|
||||
if (bi.loopId == currentLoop.id) {
|
||||
defaultCommands.remove(defaultCommands.size() - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<GraphPart> ignored = new ArrayList<>();
|
||||
for (Loop l : loops) {
|
||||
ignored.add(l.loopContinue);
|
||||
}
|
||||
|
||||
for (int i = 0; i < caseBodies.size(); i++) {
|
||||
List<GraphTargetItem> cc = new ArrayList<>();
|
||||
GraphPart nextCase = null;
|
||||
nextCase = next;
|
||||
if (next != null) {
|
||||
if (i < caseBodies.size() - 1) {
|
||||
if (!caseBodies.get(i).leadsTo(localData, this, code, caseBodies.get(i + 1), loops)) {
|
||||
cc.add(new BreakItem(null, currentLoop.id));
|
||||
} else {
|
||||
nextCase = caseBodies.get(i + 1);
|
||||
}
|
||||
} else if (!defaultCommands.isEmpty()) {
|
||||
if (!caseBodies.get(i).leadsTo(localData, this, code, defaultPart, loops)) {
|
||||
cc.add(new BreakItem(null, currentLoop.id));
|
||||
} else {
|
||||
nextCase = defaultPart;
|
||||
}
|
||||
}
|
||||
}
|
||||
List<GraphPart> stopPart2x = new ArrayList<>(stopPart);
|
||||
//stopPart2.add(nextCase);
|
||||
for (GraphPart b : caseBodies) {
|
||||
if (b != caseBodies.get(i)) {
|
||||
stopPart2x.add(b);
|
||||
}
|
||||
}
|
||||
if (defaultPart != null) {
|
||||
stopPart2x.add(defaultPart);
|
||||
}
|
||||
if (breakPart != null) {
|
||||
stopPart2x.add(breakPart);
|
||||
}
|
||||
cc.addAll(0, printGraph(localData, stack, allParts, null, caseBodies.get(i), stopPart2x, loops, staticOperation, path));
|
||||
if (cc.size() >= 2) {
|
||||
if (cc.get(cc.size() - 1) instanceof BreakItem) {
|
||||
if ((cc.get(cc.size() - 2) instanceof ContinueItem) || (cc.get(cc.size() - 2) instanceof BreakItem)) {
|
||||
cc.remove(cc.size() - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
caseCommands.add(cc);
|
||||
}
|
||||
ret = new ArrayList<>();
|
||||
ret.addAll(output);
|
||||
SwitchItem sti = new SwitchItem(null, currentLoop, switchedObject, caseValues, caseCommands, defaultCommands, valuesMapping);
|
||||
ret.add(sti);
|
||||
currentLoop.phase = 2;
|
||||
if (next != null) {
|
||||
if (ti != null) {
|
||||
ret.add(ti);
|
||||
} else {
|
||||
ret.addAll(printGraph(localData, stack, allParts, null, next, stopPart, loops, staticOperation, path));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int checkIp(int ip) {
|
||||
int oldIp = ip;
|
||||
//return in for..in
|
||||
GraphSourceItem action = code.get(ip);
|
||||
if ((action instanceof ActionPush) && (((ActionPush) action).values.size() == 1) && (((ActionPush) action).values.get(0) instanceof Null)) {
|
||||
if (ip + 3 < code.size()) {
|
||||
if ((code.get(ip + 1) instanceof ActionEquals) || (code.get(ip + 1) instanceof ActionEquals2)) {
|
||||
if (code.get(ip + 2) instanceof ActionNot) {
|
||||
if (code.get(ip + 3) instanceof ActionIf) {
|
||||
ActionIf aif = (ActionIf) code.get(ip + 3);
|
||||
if (code.adr2pos(code.pos2adr(ip + 4) + aif.getJumpOffset()) == ip) {
|
||||
ip += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (oldIp != ip) {
|
||||
return checkIp(ip);
|
||||
}
|
||||
return ip;
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+339
-339
@@ -1,339 +1,339 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.model;
|
||||
|
||||
import com.jpexs.decompiler.flash.IdentifiersDeobfuscation;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
|
||||
import com.jpexs.decompiler.flash.action.Action;
|
||||
import com.jpexs.decompiler.flash.action.parser.script.ActionSourceGenerator;
|
||||
import com.jpexs.decompiler.flash.action.parser.script.VariableActionItem;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionPush;
|
||||
import com.jpexs.decompiler.flash.action.swf4.RegisterNumber;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionDefineFunction;
|
||||
import com.jpexs.decompiler.flash.action.swf7.ActionDefineFunction2;
|
||||
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.graph.CompilationException;
|
||||
import com.jpexs.decompiler.graph.Graph;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItemPos;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.SourceGenerator;
|
||||
import com.jpexs.decompiler.graph.model.LocalData;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class FunctionActionItem extends ActionItem {
|
||||
|
||||
public List<GraphTargetItem> actions;
|
||||
|
||||
public List<String> constants;
|
||||
|
||||
public String functionName;
|
||||
|
||||
public List<String> paramNames;
|
||||
|
||||
public GraphTargetItem calculatedFunctionName;
|
||||
|
||||
private int regStart;
|
||||
|
||||
private List<VariableActionItem> variables;
|
||||
|
||||
public static final int REGISTER_THIS = 1;
|
||||
|
||||
public static final int REGISTER_ARGUMENTS = 2;
|
||||
|
||||
public static final int REGISTER_SUPER = 3;
|
||||
|
||||
public static final int REGISTER_ROOT = 4;
|
||||
|
||||
public static final int REGISTER_PARENT = 5;
|
||||
|
||||
public static final int REGISTER_GLOBAL = 6;
|
||||
|
||||
@Override
|
||||
public List<GraphTargetItem> getAllSubItems() {
|
||||
List<GraphTargetItem> ret = new ArrayList<>();
|
||||
ret.addAll(actions);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public FunctionActionItem() {
|
||||
super(null, PRECEDENCE_PRIMARY);
|
||||
}
|
||||
|
||||
public FunctionActionItem(GraphSourceItem instruction, String functionName, List<String> paramNames, List<GraphTargetItem> actions, List<String> constants, int regStart, List<VariableActionItem> variables) {
|
||||
super(instruction, PRECEDENCE_PRIMARY);
|
||||
this.actions = actions;
|
||||
this.constants = constants;
|
||||
this.functionName = functionName;
|
||||
this.paramNames = paramNames;
|
||||
this.regStart = regStart;
|
||||
this.variables = variables;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException {
|
||||
writer.append("function");
|
||||
if (calculatedFunctionName != null) {
|
||||
writer.append(" ");
|
||||
String fname = calculatedFunctionName.toStringNoQuotes(localData);
|
||||
if (!IdentifiersDeobfuscation.isValidName(false, fname)) {
|
||||
writer.append(IdentifiersDeobfuscation.makeObfuscatedIdentifier(fname));
|
||||
} else {
|
||||
calculatedFunctionName.appendToNoQuotes(writer, localData);
|
||||
}
|
||||
} else if (!functionName.isEmpty()) {
|
||||
writer.append(" ");
|
||||
if (!IdentifiersDeobfuscation.isValidName(false, functionName)) {
|
||||
writer.append(IdentifiersDeobfuscation.makeObfuscatedIdentifier(functionName));
|
||||
} else {
|
||||
writer.append(functionName);
|
||||
}
|
||||
}
|
||||
writer.spaceBeforeCallParenthesies(paramNames.size());
|
||||
writer.append("(");
|
||||
|
||||
for (int p = 0; p < paramNames.size(); p++) {
|
||||
if (p > 0) {
|
||||
writer.append(", ");
|
||||
}
|
||||
String pname = paramNames.get(p);
|
||||
if (pname == null || pname.isEmpty()) {
|
||||
pname = new RegisterNumber(regStart + p).translate();
|
||||
}
|
||||
if (!IdentifiersDeobfuscation.isValidName(false, pname)) {
|
||||
writer.append(IdentifiersDeobfuscation.makeObfuscatedIdentifier(pname));
|
||||
}
|
||||
writer.append(pname);
|
||||
}
|
||||
writer.append(")").startBlock();
|
||||
|
||||
Graph.graphToString(actions, writer, localData);
|
||||
|
||||
return writer.endBlock();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GraphSourceItemPos> getNeededSources() {
|
||||
List<GraphSourceItemPos> ret = super.getNeededSources();
|
||||
for (GraphTargetItem ti : actions) {
|
||||
ret.addAll(ti.getNeededSources());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean needsSemicolon() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCompileTime(Set<GraphTargetItem> dependencies) {
|
||||
for (GraphTargetItem a : actions) {
|
||||
if (dependencies.contains(a)) {
|
||||
return false;
|
||||
}
|
||||
dependencies.add(a);
|
||||
if (!a.isCompileTime(dependencies)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getResult() {
|
||||
if (!actions.isEmpty()) {
|
||||
if (actions.get(actions.size() - 1) instanceof ReturnActionItem) {
|
||||
ReturnActionItem r = (ReturnActionItem) actions.get(actions.size() - 1);
|
||||
return r.value.getResult();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean needsNewLine() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GraphSourceItem> toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException {
|
||||
|
||||
Set<String> usedNames = new HashSet<>();
|
||||
for (VariableActionItem v : variables) {
|
||||
usedNames.add(v.getVariableName());
|
||||
}
|
||||
|
||||
List<GraphSourceItem> ret = new ArrayList<>();
|
||||
ActionSourceGenerator asGenerator = (ActionSourceGenerator) generator;
|
||||
List<Integer> paramRegs = new ArrayList<>();
|
||||
SourceGeneratorLocalData localDataCopy = Helper.deepCopy(localData);
|
||||
localDataCopy.inFunction++;
|
||||
boolean preloadParentFlag = false;
|
||||
boolean preloadRootFlag = false;
|
||||
boolean preloadSuperFlag = false;
|
||||
boolean preloadArgumentsFlag = false;
|
||||
boolean preloadThisFlag = false;
|
||||
boolean preloadGlobalFlag = false;
|
||||
|
||||
boolean suppressParentFlag = false;
|
||||
boolean suppressArgumentsFlag = false;
|
||||
boolean suppressThisFlag = false;
|
||||
|
||||
boolean needsFun2 = false;
|
||||
|
||||
List<String> registerNames = new ArrayList<>();
|
||||
registerNames.add("***** ZERO *****");
|
||||
if (usedNames.contains("this")) {
|
||||
needsFun2 = true;
|
||||
preloadThisFlag = true;
|
||||
registerNames.add("this");
|
||||
} else {
|
||||
suppressThisFlag = true;
|
||||
}
|
||||
if (usedNames.contains("arguments")) {
|
||||
preloadArgumentsFlag = true;
|
||||
needsFun2 = true;
|
||||
registerNames.add("arguments");
|
||||
} else {
|
||||
suppressArgumentsFlag = true;
|
||||
}
|
||||
if (usedNames.contains("super")) {
|
||||
preloadSuperFlag = true;
|
||||
needsFun2 = true;
|
||||
registerNames.add("super");
|
||||
}
|
||||
if (usedNames.contains("_root")) {
|
||||
preloadRootFlag = true;
|
||||
needsFun2 = true;
|
||||
registerNames.add("_root");
|
||||
}
|
||||
if (usedNames.contains("_parent")) {
|
||||
preloadParentFlag = true;
|
||||
needsFun2 = true;
|
||||
registerNames.add("_parent");
|
||||
} else {
|
||||
suppressParentFlag = true;
|
||||
}
|
||||
if (usedNames.contains("_global")) {
|
||||
needsFun2 = true;
|
||||
preloadGlobalFlag = true;
|
||||
registerNames.add("_global");
|
||||
}
|
||||
|
||||
int preloadedNumber = registerNames.size();
|
||||
if (!paramNames.isEmpty()) {
|
||||
needsFun2 = true;
|
||||
}
|
||||
if (localData.inMethod) {
|
||||
needsFun2 = true;
|
||||
}
|
||||
if (localData.inFunction > 1) {
|
||||
needsFun2 = true;
|
||||
}
|
||||
if (needsFun2) {
|
||||
for (int i = 0; i < paramNames.size(); i++) {
|
||||
paramRegs.add(registerNames.size());
|
||||
registerNames.add(paramNames.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
int regCount = 0;
|
||||
if (actions != null && !actions.isEmpty()) {
|
||||
localDataCopy.inFunction++;
|
||||
|
||||
for (VariableActionItem v : variables) {
|
||||
String varName = v.getVariableName();
|
||||
GraphTargetItem stored = v.getStoreValue();
|
||||
if (needsFun2) {
|
||||
if (v.isDefinition() && !registerNames.contains(varName)) {
|
||||
registerNames.add(varName);
|
||||
}
|
||||
}
|
||||
|
||||
if (registerNames.contains(varName)) {
|
||||
if (stored != null) {
|
||||
v.setBoxedValue(new StoreRegisterActionItem(null, new RegisterNumber(registerNames.indexOf(varName), varName), stored, false));
|
||||
} else {
|
||||
v.setBoxedValue(new DirectValueActionItem(new RegisterNumber(registerNames.indexOf(varName), varName)));
|
||||
}
|
||||
} else {
|
||||
if (v.isDefinition()) {
|
||||
v.setBoxedValue(new DefineLocalActionItem(null, ((ActionSourceGenerator) generator).pushConstTargetItem(varName), stored));
|
||||
} else {
|
||||
if (stored != null) {
|
||||
v.setBoxedValue(new SetVariableActionItem(null, ((ActionSourceGenerator) generator).pushConstTargetItem(varName), stored));
|
||||
} else {
|
||||
v.setBoxedValue(new GetVariableActionItem(null, ((ActionSourceGenerator) generator).pushConstTargetItem(varName)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
for (int i = 1 /* zero is not preloaded*/; i < registerNames.size(); i++) {
|
||||
localDataCopy.registerVars.put(registerNames.get(i), i);
|
||||
}
|
||||
|
||||
ret.addAll(asGenerator.toActionList(asGenerator.generate(localDataCopy, actions)));
|
||||
|
||||
regCount = registerNames.size();
|
||||
|
||||
//some temporary registers can exceed variable+param count
|
||||
for (GraphSourceItem a : ret) {
|
||||
if (a instanceof ActionPush) {
|
||||
ActionPush apu = (ActionPush) a;
|
||||
for (Object o : apu.values) {
|
||||
if (o instanceof RegisterNumber) {
|
||||
RegisterNumber rn = (RegisterNumber) o;
|
||||
if (rn.number >= regCount) {
|
||||
regCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
int len = Action.actionsToBytes(asGenerator.toActionList(ret), false, SWF.DEFAULT_VERSION).length;
|
||||
if (!needsFun2 && paramNames.isEmpty()) {
|
||||
ret.add(0, new ActionDefineFunction(functionName, paramNames, len, SWF.DEFAULT_VERSION));
|
||||
} else {
|
||||
ret.add(0, new ActionDefineFunction2(functionName,
|
||||
preloadParentFlag,
|
||||
preloadRootFlag,
|
||||
suppressParentFlag,
|
||||
preloadSuperFlag,
|
||||
suppressArgumentsFlag,
|
||||
preloadArgumentsFlag,
|
||||
suppressThisFlag,
|
||||
preloadThisFlag,
|
||||
preloadGlobalFlag,
|
||||
regCount, len, SWF.DEFAULT_VERSION, paramNames, paramRegs));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasReturnValue() {
|
||||
return false; //function actually returns itself, but here is false for generator to not add Pop
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.model;
|
||||
|
||||
import com.jpexs.decompiler.flash.IdentifiersDeobfuscation;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
|
||||
import com.jpexs.decompiler.flash.action.Action;
|
||||
import com.jpexs.decompiler.flash.action.parser.script.ActionSourceGenerator;
|
||||
import com.jpexs.decompiler.flash.action.parser.script.VariableActionItem;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionPush;
|
||||
import com.jpexs.decompiler.flash.action.swf4.RegisterNumber;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionDefineFunction;
|
||||
import com.jpexs.decompiler.flash.action.swf7.ActionDefineFunction2;
|
||||
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.graph.CompilationException;
|
||||
import com.jpexs.decompiler.graph.Graph;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItemPos;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.SourceGenerator;
|
||||
import com.jpexs.decompiler.graph.model.LocalData;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class FunctionActionItem extends ActionItem {
|
||||
|
||||
public List<GraphTargetItem> actions;
|
||||
|
||||
public List<String> constants;
|
||||
|
||||
public String functionName;
|
||||
|
||||
public List<String> paramNames;
|
||||
|
||||
public GraphTargetItem calculatedFunctionName;
|
||||
|
||||
private int regStart;
|
||||
|
||||
private List<VariableActionItem> variables;
|
||||
|
||||
public static final int REGISTER_THIS = 1;
|
||||
|
||||
public static final int REGISTER_ARGUMENTS = 2;
|
||||
|
||||
public static final int REGISTER_SUPER = 3;
|
||||
|
||||
public static final int REGISTER_ROOT = 4;
|
||||
|
||||
public static final int REGISTER_PARENT = 5;
|
||||
|
||||
public static final int REGISTER_GLOBAL = 6;
|
||||
|
||||
@Override
|
||||
public List<GraphTargetItem> getAllSubItems() {
|
||||
List<GraphTargetItem> ret = new ArrayList<>();
|
||||
ret.addAll(actions);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public FunctionActionItem() {
|
||||
super(null, PRECEDENCE_PRIMARY);
|
||||
}
|
||||
|
||||
public FunctionActionItem(GraphSourceItem instruction, String functionName, List<String> paramNames, List<GraphTargetItem> actions, List<String> constants, int regStart, List<VariableActionItem> variables) {
|
||||
super(instruction, PRECEDENCE_PRIMARY);
|
||||
this.actions = actions;
|
||||
this.constants = constants;
|
||||
this.functionName = functionName;
|
||||
this.paramNames = paramNames;
|
||||
this.regStart = regStart;
|
||||
this.variables = variables;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException {
|
||||
writer.append("function");
|
||||
if (calculatedFunctionName != null) {
|
||||
writer.append(" ");
|
||||
String fname = calculatedFunctionName.toStringNoQuotes(localData);
|
||||
if (!IdentifiersDeobfuscation.isValidName(false, fname)) {
|
||||
writer.append(IdentifiersDeobfuscation.makeObfuscatedIdentifier(fname));
|
||||
} else {
|
||||
calculatedFunctionName.appendToNoQuotes(writer, localData);
|
||||
}
|
||||
} else if (!functionName.isEmpty()) {
|
||||
writer.append(" ");
|
||||
if (!IdentifiersDeobfuscation.isValidName(false, functionName)) {
|
||||
writer.append(IdentifiersDeobfuscation.makeObfuscatedIdentifier(functionName));
|
||||
} else {
|
||||
writer.append(functionName);
|
||||
}
|
||||
}
|
||||
writer.spaceBeforeCallParenthesies(paramNames.size());
|
||||
writer.append("(");
|
||||
|
||||
for (int p = 0; p < paramNames.size(); p++) {
|
||||
if (p > 0) {
|
||||
writer.append(", ");
|
||||
}
|
||||
String pname = paramNames.get(p);
|
||||
if (pname == null || pname.isEmpty()) {
|
||||
pname = new RegisterNumber(regStart + p).translate();
|
||||
}
|
||||
if (!IdentifiersDeobfuscation.isValidName(false, pname)) {
|
||||
writer.append(IdentifiersDeobfuscation.makeObfuscatedIdentifier(pname));
|
||||
}
|
||||
writer.append(pname);
|
||||
}
|
||||
writer.append(")").startBlock();
|
||||
|
||||
Graph.graphToString(actions, writer, localData);
|
||||
|
||||
return writer.endBlock();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GraphSourceItemPos> getNeededSources() {
|
||||
List<GraphSourceItemPos> ret = super.getNeededSources();
|
||||
for (GraphTargetItem ti : actions) {
|
||||
ret.addAll(ti.getNeededSources());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean needsSemicolon() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCompileTime(Set<GraphTargetItem> dependencies) {
|
||||
for (GraphTargetItem a : actions) {
|
||||
if (dependencies.contains(a)) {
|
||||
return false;
|
||||
}
|
||||
dependencies.add(a);
|
||||
if (!a.isCompileTime(dependencies)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getResult() {
|
||||
if (!actions.isEmpty()) {
|
||||
if (actions.get(actions.size() - 1) instanceof ReturnActionItem) {
|
||||
ReturnActionItem r = (ReturnActionItem) actions.get(actions.size() - 1);
|
||||
return r.value.getResult();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean needsNewLine() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GraphSourceItem> toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException {
|
||||
|
||||
Set<String> usedNames = new HashSet<>();
|
||||
for (VariableActionItem v : variables) {
|
||||
usedNames.add(v.getVariableName());
|
||||
}
|
||||
|
||||
List<GraphSourceItem> ret = new ArrayList<>();
|
||||
ActionSourceGenerator asGenerator = (ActionSourceGenerator) generator;
|
||||
List<Integer> paramRegs = new ArrayList<>();
|
||||
SourceGeneratorLocalData localDataCopy = Helper.deepCopy(localData);
|
||||
localDataCopy.inFunction++;
|
||||
boolean preloadParentFlag = false;
|
||||
boolean preloadRootFlag = false;
|
||||
boolean preloadSuperFlag = false;
|
||||
boolean preloadArgumentsFlag = false;
|
||||
boolean preloadThisFlag = false;
|
||||
boolean preloadGlobalFlag = false;
|
||||
|
||||
boolean suppressParentFlag = false;
|
||||
boolean suppressArgumentsFlag = false;
|
||||
boolean suppressThisFlag = false;
|
||||
|
||||
boolean needsFun2 = false;
|
||||
|
||||
List<String> registerNames = new ArrayList<>();
|
||||
registerNames.add("***** ZERO *****");
|
||||
if (usedNames.contains("this")) {
|
||||
needsFun2 = true;
|
||||
preloadThisFlag = true;
|
||||
registerNames.add("this");
|
||||
} else {
|
||||
suppressThisFlag = true;
|
||||
}
|
||||
if (usedNames.contains("arguments")) {
|
||||
preloadArgumentsFlag = true;
|
||||
needsFun2 = true;
|
||||
registerNames.add("arguments");
|
||||
} else {
|
||||
suppressArgumentsFlag = true;
|
||||
}
|
||||
if (usedNames.contains("super")) {
|
||||
preloadSuperFlag = true;
|
||||
needsFun2 = true;
|
||||
registerNames.add("super");
|
||||
}
|
||||
if (usedNames.contains("_root")) {
|
||||
preloadRootFlag = true;
|
||||
needsFun2 = true;
|
||||
registerNames.add("_root");
|
||||
}
|
||||
if (usedNames.contains("_parent")) {
|
||||
preloadParentFlag = true;
|
||||
needsFun2 = true;
|
||||
registerNames.add("_parent");
|
||||
} else {
|
||||
suppressParentFlag = true;
|
||||
}
|
||||
if (usedNames.contains("_global")) {
|
||||
needsFun2 = true;
|
||||
preloadGlobalFlag = true;
|
||||
registerNames.add("_global");
|
||||
}
|
||||
|
||||
int preloadedNumber = registerNames.size();
|
||||
if (!paramNames.isEmpty()) {
|
||||
needsFun2 = true;
|
||||
}
|
||||
if (localData.inMethod) {
|
||||
needsFun2 = true;
|
||||
}
|
||||
if (localData.inFunction > 1) {
|
||||
needsFun2 = true;
|
||||
}
|
||||
if (needsFun2) {
|
||||
for (int i = 0; i < paramNames.size(); i++) {
|
||||
paramRegs.add(registerNames.size());
|
||||
registerNames.add(paramNames.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
int regCount = 0;
|
||||
if (actions != null && !actions.isEmpty()) {
|
||||
localDataCopy.inFunction++;
|
||||
|
||||
for (VariableActionItem v : variables) {
|
||||
String varName = v.getVariableName();
|
||||
GraphTargetItem stored = v.getStoreValue();
|
||||
if (needsFun2) {
|
||||
if (v.isDefinition() && !registerNames.contains(varName)) {
|
||||
registerNames.add(varName);
|
||||
}
|
||||
}
|
||||
|
||||
if (registerNames.contains(varName)) {
|
||||
if (stored != null) {
|
||||
v.setBoxedValue(new StoreRegisterActionItem(null, new RegisterNumber(registerNames.indexOf(varName), varName), stored, false));
|
||||
} else {
|
||||
v.setBoxedValue(new DirectValueActionItem(new RegisterNumber(registerNames.indexOf(varName), varName)));
|
||||
}
|
||||
} else {
|
||||
if (v.isDefinition()) {
|
||||
v.setBoxedValue(new DefineLocalActionItem(null, ((ActionSourceGenerator) generator).pushConstTargetItem(varName), stored));
|
||||
} else {
|
||||
if (stored != null) {
|
||||
v.setBoxedValue(new SetVariableActionItem(null, ((ActionSourceGenerator) generator).pushConstTargetItem(varName), stored));
|
||||
} else {
|
||||
v.setBoxedValue(new GetVariableActionItem(null, ((ActionSourceGenerator) generator).pushConstTargetItem(varName)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
for (int i = 1 /* zero is not preloaded*/; i < registerNames.size(); i++) {
|
||||
localDataCopy.registerVars.put(registerNames.get(i), i);
|
||||
}
|
||||
|
||||
ret.addAll(asGenerator.toActionList(asGenerator.generate(localDataCopy, actions)));
|
||||
|
||||
regCount = registerNames.size();
|
||||
|
||||
//some temporary registers can exceed variable+param count
|
||||
for (GraphSourceItem a : ret) {
|
||||
if (a instanceof ActionPush) {
|
||||
ActionPush apu = (ActionPush) a;
|
||||
for (Object o : apu.values) {
|
||||
if (o instanceof RegisterNumber) {
|
||||
RegisterNumber rn = (RegisterNumber) o;
|
||||
if (rn.number >= regCount) {
|
||||
regCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
int len = Action.actionsToBytes(asGenerator.toActionList(ret), false, SWF.DEFAULT_VERSION).length;
|
||||
if (!needsFun2 && paramNames.isEmpty()) {
|
||||
ret.add(0, new ActionDefineFunction(functionName, paramNames, len, SWF.DEFAULT_VERSION));
|
||||
} else {
|
||||
ret.add(0, new ActionDefineFunction2(functionName,
|
||||
preloadParentFlag,
|
||||
preloadRootFlag,
|
||||
suppressParentFlag,
|
||||
preloadSuperFlag,
|
||||
suppressArgumentsFlag,
|
||||
preloadArgumentsFlag,
|
||||
suppressThisFlag,
|
||||
preloadThisFlag,
|
||||
preloadGlobalFlag,
|
||||
regCount, len, SWF.DEFAULT_VERSION, paramNames, paramRegs));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasReturnValue() {
|
||||
return false; //function actually returns itself, but here is false for generator to not add Pop
|
||||
}
|
||||
}
|
||||
|
||||
+142
-142
@@ -1,142 +1,142 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.model;
|
||||
|
||||
import com.jpexs.decompiler.flash.IdentifiersDeobfuscation;
|
||||
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
|
||||
import com.jpexs.decompiler.flash.action.parser.script.ActionSourceGenerator;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionPush;
|
||||
import com.jpexs.decompiler.flash.action.swf4.RegisterNumber;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionSetMember;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionStoreRegister;
|
||||
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.graph.CompilationException;
|
||||
import com.jpexs.decompiler.graph.GraphPart;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItemPos;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.SourceGenerator;
|
||||
import com.jpexs.decompiler.graph.model.LocalData;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class SetMemberActionItem extends ActionItem implements SetTypeActionItem {
|
||||
|
||||
public GraphTargetItem object;
|
||||
|
||||
public GraphTargetItem objectName;
|
||||
|
||||
//public GraphTargetItem value;
|
||||
private int tempRegister = -1;
|
||||
|
||||
@Override
|
||||
public List<GraphTargetItem> getAllSubItems() {
|
||||
List<GraphTargetItem> ret = new ArrayList<>();
|
||||
ret.add(object);
|
||||
ret.add(value);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphPart getFirstPart() {
|
||||
return value.getFirstPart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(GraphTargetItem value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTempRegister() {
|
||||
return tempRegister;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTempRegister(int tempRegister) {
|
||||
this.tempRegister = tempRegister;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTargetItem getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public SetMemberActionItem(GraphSourceItem instruction, GraphTargetItem object, GraphTargetItem objectName, GraphTargetItem value) {
|
||||
super(instruction, PRECEDENCE_ASSIGMENT);
|
||||
this.object = object;
|
||||
this.objectName = objectName;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException {
|
||||
object.toString(writer, localData);
|
||||
|
||||
if ((!(objectName instanceof DirectValueActionItem)) || (!((DirectValueActionItem) objectName).isString()) || (!IdentifiersDeobfuscation.isValidName(false, ((DirectValueActionItem) objectName).toStringNoQuotes(localData)))) {
|
||||
writer.append("[");
|
||||
objectName.toString(writer, localData);
|
||||
writer.append("]");
|
||||
} else {
|
||||
writer.append(".");
|
||||
stripQuotes(objectName, localData, writer);
|
||||
}
|
||||
writer.append(" = ");
|
||||
return value.toString(writer, localData);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTargetItem getObject() {
|
||||
return new GetMemberActionItem(src, object, objectName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GraphSourceItemPos> getNeededSources() {
|
||||
List<GraphSourceItemPos> ret = super.getNeededSources();
|
||||
ret.addAll(object.getNeededSources());
|
||||
ret.addAll(objectName.getNeededSources());
|
||||
ret.addAll(value.getNeededSources());
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasSideEffect() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GraphSourceItem> toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException {
|
||||
ActionSourceGenerator asGenerator = (ActionSourceGenerator) generator;
|
||||
int tmpReg = asGenerator.getTempRegister(localData);
|
||||
try {
|
||||
return toSourceMerge(localData, generator, object, objectName, value, new ActionStoreRegister(tmpReg), new ActionSetMember(), new ActionPush(new RegisterNumber(tmpReg)));
|
||||
} finally {
|
||||
asGenerator.releaseTempRegister(localData, tmpReg);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GraphSourceItem> toSourceIgnoreReturnValue(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException {
|
||||
return toSourceMerge(localData, generator, object, objectName, value, new ActionSetMember());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasReturnValue() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.model;
|
||||
|
||||
import com.jpexs.decompiler.flash.IdentifiersDeobfuscation;
|
||||
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
|
||||
import com.jpexs.decompiler.flash.action.parser.script.ActionSourceGenerator;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionPush;
|
||||
import com.jpexs.decompiler.flash.action.swf4.RegisterNumber;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionSetMember;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionStoreRegister;
|
||||
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.graph.CompilationException;
|
||||
import com.jpexs.decompiler.graph.GraphPart;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItemPos;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.SourceGenerator;
|
||||
import com.jpexs.decompiler.graph.model.LocalData;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class SetMemberActionItem extends ActionItem implements SetTypeActionItem {
|
||||
|
||||
public GraphTargetItem object;
|
||||
|
||||
public GraphTargetItem objectName;
|
||||
|
||||
//public GraphTargetItem value;
|
||||
private int tempRegister = -1;
|
||||
|
||||
@Override
|
||||
public List<GraphTargetItem> getAllSubItems() {
|
||||
List<GraphTargetItem> ret = new ArrayList<>();
|
||||
ret.add(object);
|
||||
ret.add(value);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphPart getFirstPart() {
|
||||
return value.getFirstPart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(GraphTargetItem value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTempRegister() {
|
||||
return tempRegister;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTempRegister(int tempRegister) {
|
||||
this.tempRegister = tempRegister;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTargetItem getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public SetMemberActionItem(GraphSourceItem instruction, GraphTargetItem object, GraphTargetItem objectName, GraphTargetItem value) {
|
||||
super(instruction, PRECEDENCE_ASSIGMENT);
|
||||
this.object = object;
|
||||
this.objectName = objectName;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException {
|
||||
object.toString(writer, localData);
|
||||
|
||||
if ((!(objectName instanceof DirectValueActionItem)) || (!((DirectValueActionItem) objectName).isString()) || (!IdentifiersDeobfuscation.isValidName(false, ((DirectValueActionItem) objectName).toStringNoQuotes(localData)))) {
|
||||
writer.append("[");
|
||||
objectName.toString(writer, localData);
|
||||
writer.append("]");
|
||||
} else {
|
||||
writer.append(".");
|
||||
stripQuotes(objectName, localData, writer);
|
||||
}
|
||||
writer.append(" = ");
|
||||
return value.toString(writer, localData);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTargetItem getObject() {
|
||||
return new GetMemberActionItem(src, object, objectName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GraphSourceItemPos> getNeededSources() {
|
||||
List<GraphSourceItemPos> ret = super.getNeededSources();
|
||||
ret.addAll(object.getNeededSources());
|
||||
ret.addAll(objectName.getNeededSources());
|
||||
ret.addAll(value.getNeededSources());
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasSideEffect() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GraphSourceItem> toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException {
|
||||
ActionSourceGenerator asGenerator = (ActionSourceGenerator) generator;
|
||||
int tmpReg = asGenerator.getTempRegister(localData);
|
||||
try {
|
||||
return toSourceMerge(localData, generator, object, objectName, value, new ActionStoreRegister(tmpReg), new ActionSetMember(), new ActionPush(new RegisterNumber(tmpReg)));
|
||||
} finally {
|
||||
asGenerator.releaseTempRegister(localData, tmpReg);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GraphSourceItem> toSourceIgnoreReturnValue(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException {
|
||||
return toSourceMerge(localData, generator, object, objectName, value, new ActionSetMember());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasReturnValue() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+126
-126
@@ -1,126 +1,126 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.model;
|
||||
|
||||
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
|
||||
import com.jpexs.decompiler.flash.action.Action;
|
||||
import com.jpexs.decompiler.flash.action.parser.script.ActionSourceGenerator;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionPush;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionSetProperty;
|
||||
import com.jpexs.decompiler.flash.action.swf4.RegisterNumber;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionStoreRegister;
|
||||
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.graph.CompilationException;
|
||||
import com.jpexs.decompiler.graph.GraphPart;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItemPos;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.SourceGenerator;
|
||||
import com.jpexs.decompiler.graph.model.LocalData;
|
||||
import java.util.List;
|
||||
|
||||
public class SetPropertyActionItem extends ActionItem implements SetTypeActionItem {
|
||||
|
||||
public GraphTargetItem target;
|
||||
|
||||
public int propertyIndex;
|
||||
//public GraphTargetItem value;
|
||||
|
||||
@Override
|
||||
public GraphPart getFirstPart() {
|
||||
return value.getFirstPart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(GraphTargetItem value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
private int tempRegister = -1;
|
||||
|
||||
@Override
|
||||
public int getTempRegister() {
|
||||
return tempRegister;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTempRegister(int tempRegister) {
|
||||
this.tempRegister = tempRegister;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTargetItem getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public SetPropertyActionItem(GraphSourceItem instruction, GraphTargetItem target, int propertyIndex, GraphTargetItem value) {
|
||||
super(instruction, PRECEDENCE_ASSIGMENT);
|
||||
this.target = target;
|
||||
this.propertyIndex = propertyIndex;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException {
|
||||
if (isEmptyString(target)) {
|
||||
writer.append(Action.propertyNames[propertyIndex] + " = ");
|
||||
return value.toString(writer, localData);
|
||||
}
|
||||
target.toString(writer, localData);
|
||||
writer.append("." + Action.propertyNames[propertyIndex] + " = ");
|
||||
return value.toString(writer, localData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTargetItem getObject() {
|
||||
return new GetPropertyActionItem(src, target, propertyIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GraphSourceItemPos> getNeededSources() {
|
||||
List<GraphSourceItemPos> ret = super.getNeededSources();
|
||||
ret.addAll(target.getNeededSources());
|
||||
ret.addAll(value.getNeededSources());
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasSideEffect() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GraphSourceItem> toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException {
|
||||
ActionSourceGenerator asGenerator = (ActionSourceGenerator) generator;
|
||||
int tmpReg = asGenerator.getTempRegister(localData);
|
||||
try {
|
||||
return toSourceMerge(localData, generator, target, new ActionPush((Long) (long) propertyIndex), value, new ActionStoreRegister(tmpReg), new ActionSetProperty(), new ActionPush(new RegisterNumber(tmpReg)));
|
||||
} finally {
|
||||
asGenerator.releaseTempRegister(localData, tmpReg);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GraphSourceItem> toSourceIgnoreReturnValue(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException {
|
||||
return toSourceMerge(localData, generator, target, new ActionPush((Long) (long) propertyIndex), value, new ActionSetProperty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasReturnValue() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.model;
|
||||
|
||||
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
|
||||
import com.jpexs.decompiler.flash.action.Action;
|
||||
import com.jpexs.decompiler.flash.action.parser.script.ActionSourceGenerator;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionPush;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionSetProperty;
|
||||
import com.jpexs.decompiler.flash.action.swf4.RegisterNumber;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionStoreRegister;
|
||||
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.graph.CompilationException;
|
||||
import com.jpexs.decompiler.graph.GraphPart;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItemPos;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.SourceGenerator;
|
||||
import com.jpexs.decompiler.graph.model.LocalData;
|
||||
import java.util.List;
|
||||
|
||||
public class SetPropertyActionItem extends ActionItem implements SetTypeActionItem {
|
||||
|
||||
public GraphTargetItem target;
|
||||
|
||||
public int propertyIndex;
|
||||
//public GraphTargetItem value;
|
||||
|
||||
@Override
|
||||
public GraphPart getFirstPart() {
|
||||
return value.getFirstPart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(GraphTargetItem value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
private int tempRegister = -1;
|
||||
|
||||
@Override
|
||||
public int getTempRegister() {
|
||||
return tempRegister;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTempRegister(int tempRegister) {
|
||||
this.tempRegister = tempRegister;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTargetItem getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public SetPropertyActionItem(GraphSourceItem instruction, GraphTargetItem target, int propertyIndex, GraphTargetItem value) {
|
||||
super(instruction, PRECEDENCE_ASSIGMENT);
|
||||
this.target = target;
|
||||
this.propertyIndex = propertyIndex;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException {
|
||||
if (isEmptyString(target)) {
|
||||
writer.append(Action.propertyNames[propertyIndex] + " = ");
|
||||
return value.toString(writer, localData);
|
||||
}
|
||||
target.toString(writer, localData);
|
||||
writer.append("." + Action.propertyNames[propertyIndex] + " = ");
|
||||
return value.toString(writer, localData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTargetItem getObject() {
|
||||
return new GetPropertyActionItem(src, target, propertyIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GraphSourceItemPos> getNeededSources() {
|
||||
List<GraphSourceItemPos> ret = super.getNeededSources();
|
||||
ret.addAll(target.getNeededSources());
|
||||
ret.addAll(value.getNeededSources());
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasSideEffect() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GraphSourceItem> toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException {
|
||||
ActionSourceGenerator asGenerator = (ActionSourceGenerator) generator;
|
||||
int tmpReg = asGenerator.getTempRegister(localData);
|
||||
try {
|
||||
return toSourceMerge(localData, generator, target, new ActionPush((Long) (long) propertyIndex), value, new ActionStoreRegister(tmpReg), new ActionSetProperty(), new ActionPush(new RegisterNumber(tmpReg)));
|
||||
} finally {
|
||||
asGenerator.releaseTempRegister(localData, tmpReg);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GraphSourceItem> toSourceIgnoreReturnValue(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException {
|
||||
return toSourceMerge(localData, generator, target, new ActionPush((Long) (long) propertyIndex), value, new ActionSetProperty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasReturnValue() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+142
-142
@@ -1,142 +1,142 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.model;
|
||||
|
||||
import com.jpexs.decompiler.flash.IdentifiersDeobfuscation;
|
||||
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
|
||||
import com.jpexs.decompiler.flash.action.parser.script.ActionSourceGenerator;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionPush;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionSetVariable;
|
||||
import com.jpexs.decompiler.flash.action.swf4.RegisterNumber;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionStoreRegister;
|
||||
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.graph.CompilationException;
|
||||
import com.jpexs.decompiler.graph.GraphPart;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItemPos;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.SourceGenerator;
|
||||
import com.jpexs.decompiler.graph.model.LocalData;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class SetVariableActionItem extends ActionItem implements SetTypeActionItem {
|
||||
|
||||
public GraphTargetItem name;
|
||||
|
||||
//public GraphTargetItem value;
|
||||
private int tempRegister = -1;
|
||||
|
||||
@Override
|
||||
public GraphPart getFirstPart() {
|
||||
return value.getFirstPart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(GraphTargetItem value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTempRegister() {
|
||||
return tempRegister;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTempRegister(int tempRegister) {
|
||||
this.tempRegister = tempRegister;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTargetItem getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public SetVariableActionItem(GraphSourceItem instruction, GraphTargetItem name, GraphTargetItem value) {
|
||||
super(instruction, PRECEDENCE_ASSIGMENT);
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException {
|
||||
if (((name instanceof DirectValueActionItem)) && (((DirectValueActionItem) name).isString()) && (!IdentifiersDeobfuscation.isValidName(false, ((DirectValueActionItem) name).toStringNoQuotes(localData), "this", "super"))) {
|
||||
writer.append(IdentifiersDeobfuscation.makeObfuscatedIdentifier(((DirectValueActionItem) name).toStringNoQuotes(localData)));
|
||||
writer.append(" = ");
|
||||
return value.toString(writer, localData);
|
||||
} else if ((!(name instanceof DirectValueActionItem)) || (!((DirectValueActionItem) name).isString())) {
|
||||
writer.append("set");
|
||||
writer.spaceBeforeCallParenthesies(2);
|
||||
writer.append("(");
|
||||
name.toString(writer, localData);
|
||||
writer.append(",");
|
||||
value.toString(writer, localData);
|
||||
return writer.append(")");
|
||||
}
|
||||
stripQuotes(name, localData, writer);
|
||||
writer.append(" = ");
|
||||
return value.toString(writer, localData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTargetItem getObject() {
|
||||
return new GetVariableActionItem(src, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GraphSourceItemPos> getNeededSources() {
|
||||
List<GraphSourceItemPos> ret = super.getNeededSources();
|
||||
ret.addAll(name.getNeededSources());
|
||||
ret.addAll(value.getNeededSources());
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCompileTime(Set<GraphTargetItem> dependencies) {
|
||||
if (dependencies.contains(value)) {
|
||||
return false;
|
||||
}
|
||||
dependencies.add(value);
|
||||
return value.isCompileTime(dependencies);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasSideEffect() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GraphSourceItem> toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException {
|
||||
ActionSourceGenerator asGenerator = (ActionSourceGenerator) generator;
|
||||
int tmpReg = asGenerator.getTempRegister(localData);
|
||||
try {
|
||||
return toSourceMerge(localData, generator, name, value, new ActionStoreRegister(tmpReg), new ActionSetVariable(), new ActionPush(new RegisterNumber(tmpReg)));
|
||||
} finally {
|
||||
asGenerator.releaseTempRegister(localData, tmpReg);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GraphSourceItem> toSourceIgnoreReturnValue(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException {
|
||||
return toSourceMerge(localData, generator, name, value, new ActionSetVariable());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasReturnValue() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.model;
|
||||
|
||||
import com.jpexs.decompiler.flash.IdentifiersDeobfuscation;
|
||||
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
|
||||
import com.jpexs.decompiler.flash.action.parser.script.ActionSourceGenerator;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionPush;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionSetVariable;
|
||||
import com.jpexs.decompiler.flash.action.swf4.RegisterNumber;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionStoreRegister;
|
||||
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.graph.CompilationException;
|
||||
import com.jpexs.decompiler.graph.GraphPart;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItemPos;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.SourceGenerator;
|
||||
import com.jpexs.decompiler.graph.model.LocalData;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class SetVariableActionItem extends ActionItem implements SetTypeActionItem {
|
||||
|
||||
public GraphTargetItem name;
|
||||
|
||||
//public GraphTargetItem value;
|
||||
private int tempRegister = -1;
|
||||
|
||||
@Override
|
||||
public GraphPart getFirstPart() {
|
||||
return value.getFirstPart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(GraphTargetItem value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTempRegister() {
|
||||
return tempRegister;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTempRegister(int tempRegister) {
|
||||
this.tempRegister = tempRegister;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTargetItem getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public SetVariableActionItem(GraphSourceItem instruction, GraphTargetItem name, GraphTargetItem value) {
|
||||
super(instruction, PRECEDENCE_ASSIGMENT);
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException {
|
||||
if (((name instanceof DirectValueActionItem)) && (((DirectValueActionItem) name).isString()) && (!IdentifiersDeobfuscation.isValidName(false, ((DirectValueActionItem) name).toStringNoQuotes(localData), "this", "super"))) {
|
||||
writer.append(IdentifiersDeobfuscation.makeObfuscatedIdentifier(((DirectValueActionItem) name).toStringNoQuotes(localData)));
|
||||
writer.append(" = ");
|
||||
return value.toString(writer, localData);
|
||||
} else if ((!(name instanceof DirectValueActionItem)) || (!((DirectValueActionItem) name).isString())) {
|
||||
writer.append("set");
|
||||
writer.spaceBeforeCallParenthesies(2);
|
||||
writer.append("(");
|
||||
name.toString(writer, localData);
|
||||
writer.append(",");
|
||||
value.toString(writer, localData);
|
||||
return writer.append(")");
|
||||
}
|
||||
stripQuotes(name, localData, writer);
|
||||
writer.append(" = ");
|
||||
return value.toString(writer, localData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTargetItem getObject() {
|
||||
return new GetVariableActionItem(src, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GraphSourceItemPos> getNeededSources() {
|
||||
List<GraphSourceItemPos> ret = super.getNeededSources();
|
||||
ret.addAll(name.getNeededSources());
|
||||
ret.addAll(value.getNeededSources());
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCompileTime(Set<GraphTargetItem> dependencies) {
|
||||
if (dependencies.contains(value)) {
|
||||
return false;
|
||||
}
|
||||
dependencies.add(value);
|
||||
return value.isCompileTime(dependencies);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasSideEffect() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GraphSourceItem> toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException {
|
||||
ActionSourceGenerator asGenerator = (ActionSourceGenerator) generator;
|
||||
int tmpReg = asGenerator.getTempRegister(localData);
|
||||
try {
|
||||
return toSourceMerge(localData, generator, name, value, new ActionStoreRegister(tmpReg), new ActionSetVariable(), new ActionPush(new RegisterNumber(tmpReg)));
|
||||
} finally {
|
||||
asGenerator.releaseTempRegister(localData, tmpReg);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GraphSourceItem> toSourceIgnoreReturnValue(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException {
|
||||
return toSourceMerge(localData, generator, name, value, new ActionSetVariable());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasReturnValue() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+162
-162
@@ -1,162 +1,162 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.model.clauses;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
|
||||
import com.jpexs.decompiler.flash.action.Action;
|
||||
import com.jpexs.decompiler.flash.action.model.DirectValueActionItem;
|
||||
import com.jpexs.decompiler.flash.action.parser.script.ActionSourceGenerator;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionIf;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionJump;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionPush;
|
||||
import com.jpexs.decompiler.flash.action.swf4.RegisterNumber;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionEquals2;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionStoreRegister;
|
||||
import com.jpexs.decompiler.flash.action.swf6.ActionEnumerate2;
|
||||
import com.jpexs.decompiler.flash.ecma.Null;
|
||||
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.flash.helpers.LoopWithType;
|
||||
import com.jpexs.decompiler.flash.helpers.NulWriter;
|
||||
import com.jpexs.decompiler.graph.Block;
|
||||
import com.jpexs.decompiler.graph.CompilationException;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.Loop;
|
||||
import com.jpexs.decompiler.graph.SourceGenerator;
|
||||
import com.jpexs.decompiler.graph.model.ContinueItem;
|
||||
import com.jpexs.decompiler.graph.model.LocalData;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
public class ForInActionItem extends LoopActionItem implements Block {
|
||||
|
||||
public GraphTargetItem variableName;
|
||||
|
||||
public GraphTargetItem enumVariable;
|
||||
|
||||
public List<GraphTargetItem> commands;
|
||||
|
||||
private boolean labelUsed;
|
||||
|
||||
@Override
|
||||
public List<List<GraphTargetItem>> getSubs() {
|
||||
List<List<GraphTargetItem>> ret = new ArrayList<>();
|
||||
if (commands != null) {
|
||||
ret.add(commands);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public ForInActionItem(Action instruction, Loop loop, GraphTargetItem variableName, GraphTargetItem enumVariable, List<GraphTargetItem> commands) {
|
||||
super(instruction, loop);
|
||||
this.variableName = variableName;
|
||||
this.enumVariable = enumVariable;
|
||||
this.commands = commands;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean needsSemicolon() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException {
|
||||
if (writer instanceof NulWriter) {
|
||||
((NulWriter) writer).startLoop(loop.id, LoopWithType.LOOP_TYPE_LOOP);
|
||||
}
|
||||
if (labelUsed) {
|
||||
writer.append("loop" + loop.id + ":").newLine();
|
||||
}
|
||||
writer.append("for");
|
||||
if (writer.getFormatting().spaceBeforeParenthesesForParentheses) {
|
||||
writer.append(" ");
|
||||
}
|
||||
writer.append("(");
|
||||
if ((variableName instanceof DirectValueActionItem) && (((DirectValueActionItem) variableName).value instanceof RegisterNumber)) {
|
||||
writer.append("var ");
|
||||
}
|
||||
stripQuotes(variableName, localData, writer);
|
||||
writer.append(" in ");
|
||||
enumVariable.toString(writer, localData);
|
||||
writer.append(")").startBlock();
|
||||
for (GraphTargetItem ti : commands) {
|
||||
ti.toStringSemicoloned(writer, localData).newLine();
|
||||
}
|
||||
writer.endBlock();
|
||||
if (writer instanceof NulWriter) {
|
||||
LoopWithType loopOjb = ((NulWriter) writer).endLoop(loop.id);
|
||||
labelUsed = loopOjb.used;
|
||||
}
|
||||
return writer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ContinueItem> getContinues() {
|
||||
List<ContinueItem> ret = new ArrayList<>();
|
||||
for (GraphTargetItem ti : commands) {
|
||||
if (ti instanceof ContinueItem) {
|
||||
ret.add((ContinueItem) ti);
|
||||
}
|
||||
if (ti instanceof Block) {
|
||||
ret.addAll(((Block) ti).getContinues());
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GraphSourceItem> toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException {
|
||||
List<GraphSourceItem> ret = new ArrayList<>();
|
||||
ActionSourceGenerator asGenerator = (ActionSourceGenerator) generator;
|
||||
HashMap<String, Integer> registerVars = asGenerator.getRegisterVars(localData);
|
||||
ret.addAll(enumVariable.toSource(localData, generator));
|
||||
ret.add(new ActionEnumerate2());
|
||||
|
||||
List<Action> loopExpr = new ArrayList<>();
|
||||
int exprReg = asGenerator.getTempRegister(localData);
|
||||
|
||||
loopExpr.add(new ActionStoreRegister(exprReg));
|
||||
loopExpr.add(new ActionPush(new Null()));
|
||||
loopExpr.add(new ActionEquals2());
|
||||
ActionIf forInEndIf = new ActionIf(0);
|
||||
loopExpr.add(forInEndIf);
|
||||
List<Action> loopBody = new ArrayList<>();
|
||||
loopBody.add(new ActionPush(new RegisterNumber(exprReg)));
|
||||
loopBody.addAll(asGenerator.toActionList(variableName.toSourceIgnoreReturnValue(localData, generator)));
|
||||
int oldForIn = asGenerator.getForInLevel(localData);
|
||||
asGenerator.setForInLevel(localData, oldForIn + 1);
|
||||
loopBody.addAll(asGenerator.toActionList(asGenerator.generate(localData, commands)));
|
||||
asGenerator.setForInLevel(localData, oldForIn);
|
||||
ActionJump forinJmpBack = new ActionJump(0);
|
||||
loopBody.add(forinJmpBack);
|
||||
int bodyLen = Action.actionsToBytes(loopBody, false, SWF.DEFAULT_VERSION).length;
|
||||
int exprLen = Action.actionsToBytes(loopExpr, false, SWF.DEFAULT_VERSION).length;
|
||||
forinJmpBack.setJumpOffset(-bodyLen - exprLen);
|
||||
forInEndIf.setJumpOffset(bodyLen);
|
||||
ret.addAll(loopExpr);
|
||||
ret.addAll(loopBody);
|
||||
asGenerator.releaseTempRegister(localData, exprReg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasReturnValue() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.model.clauses;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
|
||||
import com.jpexs.decompiler.flash.action.Action;
|
||||
import com.jpexs.decompiler.flash.action.model.DirectValueActionItem;
|
||||
import com.jpexs.decompiler.flash.action.parser.script.ActionSourceGenerator;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionIf;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionJump;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionPush;
|
||||
import com.jpexs.decompiler.flash.action.swf4.RegisterNumber;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionEquals2;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionStoreRegister;
|
||||
import com.jpexs.decompiler.flash.action.swf6.ActionEnumerate2;
|
||||
import com.jpexs.decompiler.flash.ecma.Null;
|
||||
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.flash.helpers.LoopWithType;
|
||||
import com.jpexs.decompiler.flash.helpers.NulWriter;
|
||||
import com.jpexs.decompiler.graph.Block;
|
||||
import com.jpexs.decompiler.graph.CompilationException;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.Loop;
|
||||
import com.jpexs.decompiler.graph.SourceGenerator;
|
||||
import com.jpexs.decompiler.graph.model.ContinueItem;
|
||||
import com.jpexs.decompiler.graph.model.LocalData;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
public class ForInActionItem extends LoopActionItem implements Block {
|
||||
|
||||
public GraphTargetItem variableName;
|
||||
|
||||
public GraphTargetItem enumVariable;
|
||||
|
||||
public List<GraphTargetItem> commands;
|
||||
|
||||
private boolean labelUsed;
|
||||
|
||||
@Override
|
||||
public List<List<GraphTargetItem>> getSubs() {
|
||||
List<List<GraphTargetItem>> ret = new ArrayList<>();
|
||||
if (commands != null) {
|
||||
ret.add(commands);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public ForInActionItem(Action instruction, Loop loop, GraphTargetItem variableName, GraphTargetItem enumVariable, List<GraphTargetItem> commands) {
|
||||
super(instruction, loop);
|
||||
this.variableName = variableName;
|
||||
this.enumVariable = enumVariable;
|
||||
this.commands = commands;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean needsSemicolon() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException {
|
||||
if (writer instanceof NulWriter) {
|
||||
((NulWriter) writer).startLoop(loop.id, LoopWithType.LOOP_TYPE_LOOP);
|
||||
}
|
||||
if (labelUsed) {
|
||||
writer.append("loop" + loop.id + ":").newLine();
|
||||
}
|
||||
writer.append("for");
|
||||
if (writer.getFormatting().spaceBeforeParenthesesForParentheses) {
|
||||
writer.append(" ");
|
||||
}
|
||||
writer.append("(");
|
||||
if ((variableName instanceof DirectValueActionItem) && (((DirectValueActionItem) variableName).value instanceof RegisterNumber)) {
|
||||
writer.append("var ");
|
||||
}
|
||||
stripQuotes(variableName, localData, writer);
|
||||
writer.append(" in ");
|
||||
enumVariable.toString(writer, localData);
|
||||
writer.append(")").startBlock();
|
||||
for (GraphTargetItem ti : commands) {
|
||||
ti.toStringSemicoloned(writer, localData).newLine();
|
||||
}
|
||||
writer.endBlock();
|
||||
if (writer instanceof NulWriter) {
|
||||
LoopWithType loopOjb = ((NulWriter) writer).endLoop(loop.id);
|
||||
labelUsed = loopOjb.used;
|
||||
}
|
||||
return writer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ContinueItem> getContinues() {
|
||||
List<ContinueItem> ret = new ArrayList<>();
|
||||
for (GraphTargetItem ti : commands) {
|
||||
if (ti instanceof ContinueItem) {
|
||||
ret.add((ContinueItem) ti);
|
||||
}
|
||||
if (ti instanceof Block) {
|
||||
ret.addAll(((Block) ti).getContinues());
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GraphSourceItem> toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException {
|
||||
List<GraphSourceItem> ret = new ArrayList<>();
|
||||
ActionSourceGenerator asGenerator = (ActionSourceGenerator) generator;
|
||||
HashMap<String, Integer> registerVars = asGenerator.getRegisterVars(localData);
|
||||
ret.addAll(enumVariable.toSource(localData, generator));
|
||||
ret.add(new ActionEnumerate2());
|
||||
|
||||
List<Action> loopExpr = new ArrayList<>();
|
||||
int exprReg = asGenerator.getTempRegister(localData);
|
||||
|
||||
loopExpr.add(new ActionStoreRegister(exprReg));
|
||||
loopExpr.add(new ActionPush(new Null()));
|
||||
loopExpr.add(new ActionEquals2());
|
||||
ActionIf forInEndIf = new ActionIf(0);
|
||||
loopExpr.add(forInEndIf);
|
||||
List<Action> loopBody = new ArrayList<>();
|
||||
loopBody.add(new ActionPush(new RegisterNumber(exprReg)));
|
||||
loopBody.addAll(asGenerator.toActionList(variableName.toSourceIgnoreReturnValue(localData, generator)));
|
||||
int oldForIn = asGenerator.getForInLevel(localData);
|
||||
asGenerator.setForInLevel(localData, oldForIn + 1);
|
||||
loopBody.addAll(asGenerator.toActionList(asGenerator.generate(localData, commands)));
|
||||
asGenerator.setForInLevel(localData, oldForIn);
|
||||
ActionJump forinJmpBack = new ActionJump(0);
|
||||
loopBody.add(forinJmpBack);
|
||||
int bodyLen = Action.actionsToBytes(loopBody, false, SWF.DEFAULT_VERSION).length;
|
||||
int exprLen = Action.actionsToBytes(loopExpr, false, SWF.DEFAULT_VERSION).length;
|
||||
forinJmpBack.setJumpOffset(-bodyLen - exprLen);
|
||||
forInEndIf.setJumpOffset(bodyLen);
|
||||
ret.addAll(loopExpr);
|
||||
ret.addAll(loopBody);
|
||||
asGenerator.releaseTempRegister(localData, exprReg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasReturnValue() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+104
-104
@@ -1,104 +1,104 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.model.operations;
|
||||
|
||||
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
|
||||
import com.jpexs.decompiler.flash.action.model.DirectValueActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.GetMemberActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.GetPropertyActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.GetVariableActionItem;
|
||||
import com.jpexs.decompiler.flash.action.parser.script.ActionSourceGenerator;
|
||||
import com.jpexs.decompiler.flash.action.parser.script.VariableActionItem;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionPush;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionSetProperty;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionSetVariable;
|
||||
import com.jpexs.decompiler.flash.action.swf4.RegisterNumber;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionDecrement;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionSetMember;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionStoreRegister;
|
||||
import com.jpexs.decompiler.flash.ecma.EcmaScript;
|
||||
import com.jpexs.decompiler.graph.CompilationException;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.SourceGenerator;
|
||||
import com.jpexs.decompiler.graph.model.UnaryOpItem;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class PreDecrementActionItem extends UnaryOpItem {
|
||||
|
||||
public PreDecrementActionItem(GraphSourceItem instruction, GraphTargetItem object) {
|
||||
super(instruction, PRECEDENCE_UNARY, object, "--");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getResult() {
|
||||
return EcmaScript.toNumber(value.getResult()) - 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GraphSourceItem> toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException {
|
||||
ActionSourceGenerator asGenerator = (ActionSourceGenerator) generator;
|
||||
List<GraphSourceItem> ret = new ArrayList<>();
|
||||
GraphTargetItem val = value;
|
||||
if (val instanceof VariableActionItem) {
|
||||
val = ((VariableActionItem) val).getBoxedValue();
|
||||
}
|
||||
if (val instanceof GetVariableActionItem) {
|
||||
GetVariableActionItem gv = (GetVariableActionItem) val;
|
||||
ret.addAll(gv.toSource(localData, generator));
|
||||
ret.remove(ret.size() - 1); //ActionGetVariable
|
||||
ret.addAll(gv.toSource(localData, generator));
|
||||
ret.add(new ActionDecrement());
|
||||
int tmpReg = asGenerator.getTempRegister(localData);
|
||||
ret.add(new ActionStoreRegister(tmpReg));
|
||||
ret.add(new ActionSetVariable());
|
||||
ret.add(new ActionPush(new RegisterNumber(tmpReg)));
|
||||
asGenerator.releaseTempRegister(localData, tmpReg);
|
||||
} else if (val instanceof GetMemberActionItem) {
|
||||
GetMemberActionItem mem = (GetMemberActionItem) val;
|
||||
ret.addAll(mem.toSource(localData, generator));
|
||||
ret.remove(ret.size() - 1); //ActionGetMember
|
||||
ret.addAll(mem.toSource(localData, generator));
|
||||
ret.add(new ActionDecrement());
|
||||
int tmpReg = asGenerator.getTempRegister(localData);
|
||||
ret.add(new ActionStoreRegister(tmpReg));
|
||||
ret.add(new ActionSetMember());
|
||||
ret.add(new ActionPush(new RegisterNumber(tmpReg)));
|
||||
asGenerator.releaseTempRegister(localData, tmpReg);
|
||||
} else if ((val instanceof DirectValueActionItem) && ((DirectValueActionItem) val).value instanceof RegisterNumber) {
|
||||
RegisterNumber rn = (RegisterNumber) ((DirectValueActionItem) val).value;
|
||||
ret.add(new ActionPush(new RegisterNumber(rn.number)));
|
||||
ret.add(new ActionDecrement());
|
||||
ret.add(new ActionStoreRegister(rn.number));
|
||||
} else if (val instanceof GetPropertyActionItem) {
|
||||
GetPropertyActionItem gp = (GetPropertyActionItem) val;
|
||||
ret.addAll(gp.toSource(localData, generator)); // old value
|
||||
ret.addAll(gp.toSource(localData, generator));
|
||||
ret.remove(ret.size() - 1);
|
||||
ret.addAll(gp.toSource(localData, generator));
|
||||
ret.add(new ActionDecrement());
|
||||
ret.add(new ActionSetProperty());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTargetItem returnType() {
|
||||
return value.returnType();
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.model.operations;
|
||||
|
||||
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
|
||||
import com.jpexs.decompiler.flash.action.model.DirectValueActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.GetMemberActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.GetPropertyActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.GetVariableActionItem;
|
||||
import com.jpexs.decompiler.flash.action.parser.script.ActionSourceGenerator;
|
||||
import com.jpexs.decompiler.flash.action.parser.script.VariableActionItem;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionPush;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionSetProperty;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionSetVariable;
|
||||
import com.jpexs.decompiler.flash.action.swf4.RegisterNumber;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionDecrement;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionSetMember;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionStoreRegister;
|
||||
import com.jpexs.decompiler.flash.ecma.EcmaScript;
|
||||
import com.jpexs.decompiler.graph.CompilationException;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.SourceGenerator;
|
||||
import com.jpexs.decompiler.graph.model.UnaryOpItem;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class PreDecrementActionItem extends UnaryOpItem {
|
||||
|
||||
public PreDecrementActionItem(GraphSourceItem instruction, GraphTargetItem object) {
|
||||
super(instruction, PRECEDENCE_UNARY, object, "--");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getResult() {
|
||||
return EcmaScript.toNumber(value.getResult()) - 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GraphSourceItem> toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException {
|
||||
ActionSourceGenerator asGenerator = (ActionSourceGenerator) generator;
|
||||
List<GraphSourceItem> ret = new ArrayList<>();
|
||||
GraphTargetItem val = value;
|
||||
if (val instanceof VariableActionItem) {
|
||||
val = ((VariableActionItem) val).getBoxedValue();
|
||||
}
|
||||
if (val instanceof GetVariableActionItem) {
|
||||
GetVariableActionItem gv = (GetVariableActionItem) val;
|
||||
ret.addAll(gv.toSource(localData, generator));
|
||||
ret.remove(ret.size() - 1); //ActionGetVariable
|
||||
ret.addAll(gv.toSource(localData, generator));
|
||||
ret.add(new ActionDecrement());
|
||||
int tmpReg = asGenerator.getTempRegister(localData);
|
||||
ret.add(new ActionStoreRegister(tmpReg));
|
||||
ret.add(new ActionSetVariable());
|
||||
ret.add(new ActionPush(new RegisterNumber(tmpReg)));
|
||||
asGenerator.releaseTempRegister(localData, tmpReg);
|
||||
} else if (val instanceof GetMemberActionItem) {
|
||||
GetMemberActionItem mem = (GetMemberActionItem) val;
|
||||
ret.addAll(mem.toSource(localData, generator));
|
||||
ret.remove(ret.size() - 1); //ActionGetMember
|
||||
ret.addAll(mem.toSource(localData, generator));
|
||||
ret.add(new ActionDecrement());
|
||||
int tmpReg = asGenerator.getTempRegister(localData);
|
||||
ret.add(new ActionStoreRegister(tmpReg));
|
||||
ret.add(new ActionSetMember());
|
||||
ret.add(new ActionPush(new RegisterNumber(tmpReg)));
|
||||
asGenerator.releaseTempRegister(localData, tmpReg);
|
||||
} else if ((val instanceof DirectValueActionItem) && ((DirectValueActionItem) val).value instanceof RegisterNumber) {
|
||||
RegisterNumber rn = (RegisterNumber) ((DirectValueActionItem) val).value;
|
||||
ret.add(new ActionPush(new RegisterNumber(rn.number)));
|
||||
ret.add(new ActionDecrement());
|
||||
ret.add(new ActionStoreRegister(rn.number));
|
||||
} else if (val instanceof GetPropertyActionItem) {
|
||||
GetPropertyActionItem gp = (GetPropertyActionItem) val;
|
||||
ret.addAll(gp.toSource(localData, generator)); // old value
|
||||
ret.addAll(gp.toSource(localData, generator));
|
||||
ret.remove(ret.size() - 1);
|
||||
ret.addAll(gp.toSource(localData, generator));
|
||||
ret.add(new ActionDecrement());
|
||||
ret.add(new ActionSetProperty());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTargetItem returnType() {
|
||||
return value.returnType();
|
||||
}
|
||||
}
|
||||
|
||||
+105
-105
@@ -1,105 +1,105 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.model.operations;
|
||||
|
||||
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
|
||||
import com.jpexs.decompiler.flash.action.model.DirectValueActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.GetMemberActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.GetPropertyActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.GetVariableActionItem;
|
||||
import com.jpexs.decompiler.flash.action.parser.script.ActionSourceGenerator;
|
||||
import com.jpexs.decompiler.flash.action.parser.script.VariableActionItem;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionPush;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionSetProperty;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionSetVariable;
|
||||
import com.jpexs.decompiler.flash.action.swf4.RegisterNumber;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionIncrement;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionSetMember;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionStoreRegister;
|
||||
import com.jpexs.decompiler.flash.ecma.EcmaScript;
|
||||
import com.jpexs.decompiler.graph.CompilationException;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.SourceGenerator;
|
||||
import com.jpexs.decompiler.graph.model.UnaryOpItem;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class PreIncrementActionItem extends UnaryOpItem {
|
||||
|
||||
public PreIncrementActionItem(GraphSourceItem instruction, GraphTargetItem object) {
|
||||
super(instruction, PRECEDENCE_UNARY, object, "++");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getResult() {
|
||||
return EcmaScript.toNumber(value.getResult()) + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GraphSourceItem> toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException {
|
||||
ActionSourceGenerator asGenerator = (ActionSourceGenerator) generator;
|
||||
List<GraphSourceItem> ret = new ArrayList<>();
|
||||
GraphTargetItem val = value;
|
||||
if (val instanceof VariableActionItem) {
|
||||
val = ((VariableActionItem) val).getBoxedValue();
|
||||
}
|
||||
if (val instanceof GetVariableActionItem) {
|
||||
GetVariableActionItem gv = (GetVariableActionItem) val;
|
||||
ret.addAll(gv.toSource(localData, generator));
|
||||
ret.remove(ret.size() - 1); //ActionGetVariable
|
||||
ret.addAll(gv.toSource(localData, generator));
|
||||
ret.add(new ActionIncrement());
|
||||
int tmpReg = asGenerator.getTempRegister(localData);
|
||||
|
||||
ret.add(new ActionStoreRegister(tmpReg));
|
||||
ret.add(new ActionSetVariable());
|
||||
ret.add(new ActionPush(new RegisterNumber(tmpReg)));
|
||||
asGenerator.releaseTempRegister(localData, tmpReg);
|
||||
} else if (val instanceof GetMemberActionItem) {
|
||||
GetMemberActionItem mem = (GetMemberActionItem) val;
|
||||
ret.addAll(mem.toSource(localData, generator));
|
||||
ret.remove(ret.size() - 1); //ActionGetMember
|
||||
ret.addAll(mem.toSource(localData, generator));
|
||||
ret.add(new ActionIncrement());
|
||||
int tmpReg = asGenerator.getTempRegister(localData);
|
||||
ret.add(new ActionStoreRegister(tmpReg));
|
||||
ret.add(new ActionSetMember());
|
||||
ret.add(new ActionPush(new RegisterNumber(tmpReg)));
|
||||
asGenerator.releaseTempRegister(localData, tmpReg);
|
||||
} else if ((val instanceof DirectValueActionItem) && ((DirectValueActionItem) val).value instanceof RegisterNumber) {
|
||||
RegisterNumber rn = (RegisterNumber) ((DirectValueActionItem) val).value;
|
||||
ret.add(new ActionPush(new RegisterNumber(rn.number)));
|
||||
ret.add(new ActionIncrement());
|
||||
ret.add(new ActionStoreRegister(rn.number));
|
||||
} else if (val instanceof GetPropertyActionItem) {
|
||||
GetPropertyActionItem gp = (GetPropertyActionItem) val;
|
||||
ret.addAll(gp.toSource(localData, generator)); // old value
|
||||
ret.addAll(gp.toSource(localData, generator));
|
||||
ret.remove(ret.size() - 1);
|
||||
ret.addAll(gp.toSource(localData, generator));
|
||||
ret.add(new ActionIncrement());
|
||||
ret.add(new ActionSetProperty());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTargetItem returnType() {
|
||||
return value.returnType();
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.model.operations;
|
||||
|
||||
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
|
||||
import com.jpexs.decompiler.flash.action.model.DirectValueActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.GetMemberActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.GetPropertyActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.GetVariableActionItem;
|
||||
import com.jpexs.decompiler.flash.action.parser.script.ActionSourceGenerator;
|
||||
import com.jpexs.decompiler.flash.action.parser.script.VariableActionItem;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionPush;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionSetProperty;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionSetVariable;
|
||||
import com.jpexs.decompiler.flash.action.swf4.RegisterNumber;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionIncrement;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionSetMember;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionStoreRegister;
|
||||
import com.jpexs.decompiler.flash.ecma.EcmaScript;
|
||||
import com.jpexs.decompiler.graph.CompilationException;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.SourceGenerator;
|
||||
import com.jpexs.decompiler.graph.model.UnaryOpItem;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class PreIncrementActionItem extends UnaryOpItem {
|
||||
|
||||
public PreIncrementActionItem(GraphSourceItem instruction, GraphTargetItem object) {
|
||||
super(instruction, PRECEDENCE_UNARY, object, "++");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getResult() {
|
||||
return EcmaScript.toNumber(value.getResult()) + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GraphSourceItem> toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException {
|
||||
ActionSourceGenerator asGenerator = (ActionSourceGenerator) generator;
|
||||
List<GraphSourceItem> ret = new ArrayList<>();
|
||||
GraphTargetItem val = value;
|
||||
if (val instanceof VariableActionItem) {
|
||||
val = ((VariableActionItem) val).getBoxedValue();
|
||||
}
|
||||
if (val instanceof GetVariableActionItem) {
|
||||
GetVariableActionItem gv = (GetVariableActionItem) val;
|
||||
ret.addAll(gv.toSource(localData, generator));
|
||||
ret.remove(ret.size() - 1); //ActionGetVariable
|
||||
ret.addAll(gv.toSource(localData, generator));
|
||||
ret.add(new ActionIncrement());
|
||||
int tmpReg = asGenerator.getTempRegister(localData);
|
||||
|
||||
ret.add(new ActionStoreRegister(tmpReg));
|
||||
ret.add(new ActionSetVariable());
|
||||
ret.add(new ActionPush(new RegisterNumber(tmpReg)));
|
||||
asGenerator.releaseTempRegister(localData, tmpReg);
|
||||
} else if (val instanceof GetMemberActionItem) {
|
||||
GetMemberActionItem mem = (GetMemberActionItem) val;
|
||||
ret.addAll(mem.toSource(localData, generator));
|
||||
ret.remove(ret.size() - 1); //ActionGetMember
|
||||
ret.addAll(mem.toSource(localData, generator));
|
||||
ret.add(new ActionIncrement());
|
||||
int tmpReg = asGenerator.getTempRegister(localData);
|
||||
ret.add(new ActionStoreRegister(tmpReg));
|
||||
ret.add(new ActionSetMember());
|
||||
ret.add(new ActionPush(new RegisterNumber(tmpReg)));
|
||||
asGenerator.releaseTempRegister(localData, tmpReg);
|
||||
} else if ((val instanceof DirectValueActionItem) && ((DirectValueActionItem) val).value instanceof RegisterNumber) {
|
||||
RegisterNumber rn = (RegisterNumber) ((DirectValueActionItem) val).value;
|
||||
ret.add(new ActionPush(new RegisterNumber(rn.number)));
|
||||
ret.add(new ActionIncrement());
|
||||
ret.add(new ActionStoreRegister(rn.number));
|
||||
} else if (val instanceof GetPropertyActionItem) {
|
||||
GetPropertyActionItem gp = (GetPropertyActionItem) val;
|
||||
ret.addAll(gp.toSource(localData, generator)); // old value
|
||||
ret.addAll(gp.toSource(localData, generator));
|
||||
ret.remove(ret.size() - 1);
|
||||
ret.addAll(gp.toSource(localData, generator));
|
||||
ret.add(new ActionIncrement());
|
||||
ret.add(new ActionSetProperty());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTargetItem returnType() {
|
||||
return value.returnType();
|
||||
}
|
||||
}
|
||||
|
||||
+555
-555
File diff suppressed because it is too large
Load Diff
+1164
-1164
File diff suppressed because it is too large
Load Diff
+794
-794
File diff suppressed because it is too large
Load Diff
+222
-222
@@ -1,222 +1,222 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.parser.script;
|
||||
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public enum SymbolType {
|
||||
//Keywords
|
||||
|
||||
BREAK,
|
||||
CASE,
|
||||
CONTINUE,
|
||||
DEFAULT,
|
||||
DO,
|
||||
WHILE,
|
||||
ELSE,
|
||||
FOR,
|
||||
EACH,
|
||||
IN(GraphTargetItem.PRECEDENCE_RELATIONAL, true),
|
||||
IF,
|
||||
RETURN,
|
||||
SUPER(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
SWITCH,
|
||||
THROW,
|
||||
TRY,
|
||||
CATCH,
|
||||
FINALLY,
|
||||
WITH,
|
||||
DYNAMIC,
|
||||
INTERNAL,
|
||||
OVERRIDE,
|
||||
PRIVATE,
|
||||
PROTECTED,
|
||||
PUBLIC,
|
||||
STATIC,
|
||||
CLASS,
|
||||
CONST,
|
||||
EXTENDS,
|
||||
FUNCTION(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
GET,
|
||||
IMPLEMENTS,
|
||||
INTERFACE,
|
||||
NAMESPACE,
|
||||
PACKAGE,
|
||||
SET,
|
||||
VAR,
|
||||
IMPORT,
|
||||
USE,
|
||||
FALSE(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
NULL(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
THIS(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
TRUE(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
//Operators
|
||||
PARENT_OPEN(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
PARENT_CLOSE(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
CURLY_OPEN(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
CURLY_CLOSE(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
BRACKET_OPEN(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
BRACKET_CLOSE(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
SEMICOLON,
|
||||
COMMA(GraphTargetItem.PRECEDENCE_COMMA, false),
|
||||
REST,
|
||||
DOT(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
ASSIGN(GraphTargetItem.PRECEDENCE_ASSIGMENT, true, true),
|
||||
GREATER_THAN(GraphTargetItem.PRECEDENCE_RELATIONAL, true),
|
||||
LOWER_THAN(GraphTargetItem.PRECEDENCE_RELATIONAL, true),
|
||||
NOT(GraphTargetItem.PRECEDENCE_UNARY, false),
|
||||
NEGATE(GraphTargetItem.PRECEDENCE_UNARY, false),
|
||||
TERNAR(GraphTargetItem.PRECEDENCE_CONDITIONAL, true, true), /*!! ternar !!!*/
|
||||
COLON(GraphTargetItem.PRECEDENCE_CONDITIONAL, false),/*!! ternar !!!*/
|
||||
EQUALS(GraphTargetItem.PRECEDENCE_EQUALITY, true),
|
||||
STRICT_EQUALS(GraphTargetItem.PRECEDENCE_EQUALITY, true),
|
||||
LOWER_EQUAL(GraphTargetItem.PRECEDENCE_RELATIONAL, true),
|
||||
GREATER_EQUAL(GraphTargetItem.PRECEDENCE_RELATIONAL, true),
|
||||
NOT_EQUAL(GraphTargetItem.PRECEDENCE_EQUALITY, true),
|
||||
STRICT_NOT_EQUAL(GraphTargetItem.PRECEDENCE_EQUALITY, true),
|
||||
AND(GraphTargetItem.PRECEDENCE_LOGICALAND, true),
|
||||
OR(GraphTargetItem.PRECEDENCE_LOGICALOR, true),
|
||||
FULLAND(GraphTargetItem.PRECEDENCE_LOGICALAND, true),
|
||||
FULLOR(GraphTargetItem.PRECEDENCE_LOGICALOR, true),
|
||||
INCREMENT(GraphTargetItem.PRECEDENCE_POSTFIX, false),//OR Unary
|
||||
DECREMENT(GraphTargetItem.PRECEDENCE_POSTFIX, false), //OR Unary
|
||||
PLUS(GraphTargetItem.PRECEDENCE_ADDITIVE, true),
|
||||
MINUS(GraphTargetItem.PRECEDENCE_ADDITIVE, true), //OR Unary
|
||||
MULTIPLY(GraphTargetItem.PRECEDENCE_MULTIPLICATIVE, true),
|
||||
DIVIDE(GraphTargetItem.PRECEDENCE_MULTIPLICATIVE, true),
|
||||
BITAND(GraphTargetItem.PRECEDENCE_BITWISEAND, true),
|
||||
BITOR(GraphTargetItem.PRECEDENCE_BITWISEOR, true),
|
||||
XOR(GraphTargetItem.PRECEDENCE_BITWISEXOR, true),
|
||||
MODULO(GraphTargetItem.PRECEDENCE_BITWISESHIFT, true),
|
||||
SHIFT_LEFT(GraphTargetItem.PRECEDENCE_BITWISESHIFT, true),
|
||||
SHIFT_RIGHT(GraphTargetItem.PRECEDENCE_BITWISESHIFT, true),
|
||||
USHIFT_RIGHT(GraphTargetItem.PRECEDENCE_BITWISESHIFT, true),
|
||||
ASSIGN_PLUS(GraphTargetItem.PRECEDENCE_ASSIGMENT, true, true),
|
||||
ASSIGN_MINUS(GraphTargetItem.PRECEDENCE_ASSIGMENT, true, true),
|
||||
ASSIGN_MULTIPLY(GraphTargetItem.PRECEDENCE_ASSIGMENT, true, true),
|
||||
ASSIGN_DIVIDE(GraphTargetItem.PRECEDENCE_ASSIGMENT, true, true),
|
||||
ASSIGN_BITAND(GraphTargetItem.PRECEDENCE_ASSIGMENT, true, true),
|
||||
ASSIGN_BITOR(GraphTargetItem.PRECEDENCE_ASSIGMENT, true, true),
|
||||
ASSIGN_XOR(GraphTargetItem.PRECEDENCE_ASSIGMENT, true, true),
|
||||
ASSIGN_MODULO(GraphTargetItem.PRECEDENCE_ASSIGMENT, true, true),
|
||||
ASSIGN_SHIFT_LEFT(GraphTargetItem.PRECEDENCE_ASSIGMENT, true, true),
|
||||
ASSIGN_SHIFT_RIGHT(GraphTargetItem.PRECEDENCE_ASSIGMENT, true, true),
|
||||
ASSIGN_USHIFT_RIGHT(GraphTargetItem.PRECEDENCE_ASSIGMENT, true, true),
|
||||
AS(GraphTargetItem.PRECEDENCE_RELATIONAL, true),
|
||||
DELETE(GraphTargetItem.PRECEDENCE_UNARY, false),
|
||||
INSTANCEOF(GraphTargetItem.PRECEDENCE_RELATIONAL, true),
|
||||
IS(GraphTargetItem.PRECEDENCE_RELATIONAL, true),
|
||||
NAMESPACE_OP(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
NEW(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
TYPEOF(GraphTargetItem.PRECEDENCE_UNARY, false),
|
||||
VOID,
|
||||
ATTRIBUTE,
|
||||
//Other
|
||||
STRING(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
COMMENT,
|
||||
XML,
|
||||
IDENTIFIER(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
INTEGER(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
DOUBLE(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
TYPENAME(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
EOF,
|
||||
TRACE(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
GETURL(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
GOTOANDSTOP(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
NEXTFRAME(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
PLAY(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
PREVFRAME(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
TELLTARGET(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
STOP(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
STOPALLSOUNDS(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
TOGGLEHIGHQUALITY(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
ORD(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
CHR(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
DUPLICATEMOVIECLIP(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
STOPDRAG(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
GETTIMER(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
LOADVARIABLES(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
LOADMOVIE(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
GOTOANDPLAY(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
MBORD(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
MBCHR(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
MBLENGTH(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
MBSUBSTRING(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
RANDOM(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
REMOVEMOVIECLIP(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
STARTDRAG(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
SUBSTR(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
LENGTH(GraphTargetItem.PRECEDENCE_PRIMARY, false), //string.length
|
||||
INT(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
TARGETPATH(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
NUMBER_OP(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
STRING_OP(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
IFFRAMELOADED,
|
||||
INFINITY(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
EVAL(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
UNDEFINED(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
NEWLINE(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
NAN(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
GETVERSION(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
CALL(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
LOADMOVIENUM(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
LOADVARIABLESNUM(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
PRINT(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
PRINTNUM(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
PRINTASBITMAP(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
PRINTASBITMAPNUM(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
UNLOADMOVIE(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
UNLOADMOVIENUM(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
FSCOMMAND(GraphTargetItem.PRECEDENCE_PRIMARY, false);
|
||||
|
||||
private int precedence = GraphTargetItem.NOPRECEDENCE;
|
||||
|
||||
private boolean binary = false;
|
||||
|
||||
private boolean rightAssociative = false;
|
||||
|
||||
public boolean isBinary() {
|
||||
return binary;
|
||||
}
|
||||
|
||||
public boolean isRightAssociative() {
|
||||
return rightAssociative;
|
||||
}
|
||||
|
||||
public int getPrecedence() {
|
||||
return precedence;
|
||||
}
|
||||
|
||||
private SymbolType(int precedence, boolean binary) {
|
||||
this.precedence = precedence;
|
||||
this.binary = binary;
|
||||
}
|
||||
|
||||
private SymbolType(int precedence, boolean binary, boolean rightAssociative) {
|
||||
this.precedence = precedence;
|
||||
this.binary = binary;
|
||||
this.rightAssociative = rightAssociative;
|
||||
}
|
||||
|
||||
private SymbolType() {
|
||||
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.parser.script;
|
||||
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public enum SymbolType {
|
||||
//Keywords
|
||||
|
||||
BREAK,
|
||||
CASE,
|
||||
CONTINUE,
|
||||
DEFAULT,
|
||||
DO,
|
||||
WHILE,
|
||||
ELSE,
|
||||
FOR,
|
||||
EACH,
|
||||
IN(GraphTargetItem.PRECEDENCE_RELATIONAL, true),
|
||||
IF,
|
||||
RETURN,
|
||||
SUPER(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
SWITCH,
|
||||
THROW,
|
||||
TRY,
|
||||
CATCH,
|
||||
FINALLY,
|
||||
WITH,
|
||||
DYNAMIC,
|
||||
INTERNAL,
|
||||
OVERRIDE,
|
||||
PRIVATE,
|
||||
PROTECTED,
|
||||
PUBLIC,
|
||||
STATIC,
|
||||
CLASS,
|
||||
CONST,
|
||||
EXTENDS,
|
||||
FUNCTION(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
GET,
|
||||
IMPLEMENTS,
|
||||
INTERFACE,
|
||||
NAMESPACE,
|
||||
PACKAGE,
|
||||
SET,
|
||||
VAR,
|
||||
IMPORT,
|
||||
USE,
|
||||
FALSE(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
NULL(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
THIS(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
TRUE(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
//Operators
|
||||
PARENT_OPEN(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
PARENT_CLOSE(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
CURLY_OPEN(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
CURLY_CLOSE(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
BRACKET_OPEN(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
BRACKET_CLOSE(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
SEMICOLON,
|
||||
COMMA(GraphTargetItem.PRECEDENCE_COMMA, false),
|
||||
REST,
|
||||
DOT(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
ASSIGN(GraphTargetItem.PRECEDENCE_ASSIGMENT, true, true),
|
||||
GREATER_THAN(GraphTargetItem.PRECEDENCE_RELATIONAL, true),
|
||||
LOWER_THAN(GraphTargetItem.PRECEDENCE_RELATIONAL, true),
|
||||
NOT(GraphTargetItem.PRECEDENCE_UNARY, false),
|
||||
NEGATE(GraphTargetItem.PRECEDENCE_UNARY, false),
|
||||
TERNAR(GraphTargetItem.PRECEDENCE_CONDITIONAL, true, true), /*!! ternar !!!*/
|
||||
COLON(GraphTargetItem.PRECEDENCE_CONDITIONAL, false),/*!! ternar !!!*/
|
||||
EQUALS(GraphTargetItem.PRECEDENCE_EQUALITY, true),
|
||||
STRICT_EQUALS(GraphTargetItem.PRECEDENCE_EQUALITY, true),
|
||||
LOWER_EQUAL(GraphTargetItem.PRECEDENCE_RELATIONAL, true),
|
||||
GREATER_EQUAL(GraphTargetItem.PRECEDENCE_RELATIONAL, true),
|
||||
NOT_EQUAL(GraphTargetItem.PRECEDENCE_EQUALITY, true),
|
||||
STRICT_NOT_EQUAL(GraphTargetItem.PRECEDENCE_EQUALITY, true),
|
||||
AND(GraphTargetItem.PRECEDENCE_LOGICALAND, true),
|
||||
OR(GraphTargetItem.PRECEDENCE_LOGICALOR, true),
|
||||
FULLAND(GraphTargetItem.PRECEDENCE_LOGICALAND, true),
|
||||
FULLOR(GraphTargetItem.PRECEDENCE_LOGICALOR, true),
|
||||
INCREMENT(GraphTargetItem.PRECEDENCE_POSTFIX, false),//OR Unary
|
||||
DECREMENT(GraphTargetItem.PRECEDENCE_POSTFIX, false), //OR Unary
|
||||
PLUS(GraphTargetItem.PRECEDENCE_ADDITIVE, true),
|
||||
MINUS(GraphTargetItem.PRECEDENCE_ADDITIVE, true), //OR Unary
|
||||
MULTIPLY(GraphTargetItem.PRECEDENCE_MULTIPLICATIVE, true),
|
||||
DIVIDE(GraphTargetItem.PRECEDENCE_MULTIPLICATIVE, true),
|
||||
BITAND(GraphTargetItem.PRECEDENCE_BITWISEAND, true),
|
||||
BITOR(GraphTargetItem.PRECEDENCE_BITWISEOR, true),
|
||||
XOR(GraphTargetItem.PRECEDENCE_BITWISEXOR, true),
|
||||
MODULO(GraphTargetItem.PRECEDENCE_BITWISESHIFT, true),
|
||||
SHIFT_LEFT(GraphTargetItem.PRECEDENCE_BITWISESHIFT, true),
|
||||
SHIFT_RIGHT(GraphTargetItem.PRECEDENCE_BITWISESHIFT, true),
|
||||
USHIFT_RIGHT(GraphTargetItem.PRECEDENCE_BITWISESHIFT, true),
|
||||
ASSIGN_PLUS(GraphTargetItem.PRECEDENCE_ASSIGMENT, true, true),
|
||||
ASSIGN_MINUS(GraphTargetItem.PRECEDENCE_ASSIGMENT, true, true),
|
||||
ASSIGN_MULTIPLY(GraphTargetItem.PRECEDENCE_ASSIGMENT, true, true),
|
||||
ASSIGN_DIVIDE(GraphTargetItem.PRECEDENCE_ASSIGMENT, true, true),
|
||||
ASSIGN_BITAND(GraphTargetItem.PRECEDENCE_ASSIGMENT, true, true),
|
||||
ASSIGN_BITOR(GraphTargetItem.PRECEDENCE_ASSIGMENT, true, true),
|
||||
ASSIGN_XOR(GraphTargetItem.PRECEDENCE_ASSIGMENT, true, true),
|
||||
ASSIGN_MODULO(GraphTargetItem.PRECEDENCE_ASSIGMENT, true, true),
|
||||
ASSIGN_SHIFT_LEFT(GraphTargetItem.PRECEDENCE_ASSIGMENT, true, true),
|
||||
ASSIGN_SHIFT_RIGHT(GraphTargetItem.PRECEDENCE_ASSIGMENT, true, true),
|
||||
ASSIGN_USHIFT_RIGHT(GraphTargetItem.PRECEDENCE_ASSIGMENT, true, true),
|
||||
AS(GraphTargetItem.PRECEDENCE_RELATIONAL, true),
|
||||
DELETE(GraphTargetItem.PRECEDENCE_UNARY, false),
|
||||
INSTANCEOF(GraphTargetItem.PRECEDENCE_RELATIONAL, true),
|
||||
IS(GraphTargetItem.PRECEDENCE_RELATIONAL, true),
|
||||
NAMESPACE_OP(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
NEW(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
TYPEOF(GraphTargetItem.PRECEDENCE_UNARY, false),
|
||||
VOID,
|
||||
ATTRIBUTE,
|
||||
//Other
|
||||
STRING(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
COMMENT,
|
||||
XML,
|
||||
IDENTIFIER(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
INTEGER(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
DOUBLE(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
TYPENAME(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
EOF,
|
||||
TRACE(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
GETURL(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
GOTOANDSTOP(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
NEXTFRAME(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
PLAY(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
PREVFRAME(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
TELLTARGET(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
STOP(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
STOPALLSOUNDS(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
TOGGLEHIGHQUALITY(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
ORD(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
CHR(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
DUPLICATEMOVIECLIP(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
STOPDRAG(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
GETTIMER(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
LOADVARIABLES(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
LOADMOVIE(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
GOTOANDPLAY(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
MBORD(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
MBCHR(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
MBLENGTH(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
MBSUBSTRING(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
RANDOM(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
REMOVEMOVIECLIP(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
STARTDRAG(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
SUBSTR(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
LENGTH(GraphTargetItem.PRECEDENCE_PRIMARY, false), //string.length
|
||||
INT(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
TARGETPATH(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
NUMBER_OP(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
STRING_OP(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
IFFRAMELOADED,
|
||||
INFINITY(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
EVAL(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
UNDEFINED(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
NEWLINE(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
NAN(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
GETVERSION(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
CALL(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
LOADMOVIENUM(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
LOADVARIABLESNUM(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
PRINT(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
PRINTNUM(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
PRINTASBITMAP(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
PRINTASBITMAPNUM(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
UNLOADMOVIE(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
UNLOADMOVIENUM(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
FSCOMMAND(GraphTargetItem.PRECEDENCE_PRIMARY, false);
|
||||
|
||||
private int precedence = GraphTargetItem.NOPRECEDENCE;
|
||||
|
||||
private boolean binary = false;
|
||||
|
||||
private boolean rightAssociative = false;
|
||||
|
||||
public boolean isBinary() {
|
||||
return binary;
|
||||
}
|
||||
|
||||
public boolean isRightAssociative() {
|
||||
return rightAssociative;
|
||||
}
|
||||
|
||||
public int getPrecedence() {
|
||||
return precedence;
|
||||
}
|
||||
|
||||
private SymbolType(int precedence, boolean binary) {
|
||||
this.precedence = precedence;
|
||||
this.binary = binary;
|
||||
}
|
||||
|
||||
private SymbolType(int precedence, boolean binary, boolean rightAssociative) {
|
||||
this.precedence = precedence;
|
||||
this.binary = binary;
|
||||
this.rightAssociative = rightAssociative;
|
||||
}
|
||||
|
||||
private SymbolType() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+104
-104
@@ -1,104 +1,104 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.swf3;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.action.Action;
|
||||
import com.jpexs.decompiler.flash.action.ActionGraph;
|
||||
import com.jpexs.decompiler.flash.action.ActionList;
|
||||
import com.jpexs.decompiler.flash.action.model.DirectValueActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.clauses.IfFrameLoadedActionItem;
|
||||
import com.jpexs.decompiler.flash.action.parser.ActionParseException;
|
||||
import com.jpexs.decompiler.flash.action.parser.pcode.FlasmLexer;
|
||||
import com.jpexs.decompiler.flash.action.special.ActionStore;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.TranslateStack;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class ActionWaitForFrame extends Action implements ActionStore {
|
||||
|
||||
public int frame;
|
||||
|
||||
public int skipCount;
|
||||
|
||||
public List<Action> skipped;
|
||||
|
||||
public ActionWaitForFrame(int actionLength, SWFInputStream sis) throws IOException {
|
||||
super(0x8A, actionLength);
|
||||
frame = sis.readUI16("frame");
|
||||
skipCount = sis.readUI8("skipCount");
|
||||
skipped = new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "WaitForFrame";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getASMSource(ActionList container, Set<Long> knownAddreses, ScriptExportMode exportMode) {
|
||||
String ret = "WaitForFrame " + frame + " " + skipCount;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getBytes(int version) {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
SWFOutputStream sos = new SWFOutputStream(baos, version);
|
||||
try {
|
||||
sos.writeUI16(frame);
|
||||
sos.writeUI8(skipCount);
|
||||
sos.close();
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return surroundWithAction(baos.toByteArray(), version);
|
||||
}
|
||||
|
||||
public ActionWaitForFrame(FlasmLexer lexer) throws IOException, ActionParseException {
|
||||
super(0x8A, -1);
|
||||
frame = (int) lexLong(lexer);
|
||||
skipCount = (int) lexLong(lexer);
|
||||
skipped = new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) throws InterruptedException {
|
||||
GraphTargetItem frameTi = new DirectValueActionItem(null, 0, new Long(frame), new ArrayList<>());
|
||||
List<GraphTargetItem> body = ActionGraph.translateViaGraph(regNames, variables, functions, skipped, SWF.DEFAULT_VERSION, staticOperation, path);
|
||||
output.add(new IfFrameLoadedActionItem(frameTi, body, this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStoreSize() {
|
||||
return skipCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStore(List<Action> store) {
|
||||
skipped = store;
|
||||
skipCount = store.size();
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.swf3;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.action.Action;
|
||||
import com.jpexs.decompiler.flash.action.ActionGraph;
|
||||
import com.jpexs.decompiler.flash.action.ActionList;
|
||||
import com.jpexs.decompiler.flash.action.model.DirectValueActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.clauses.IfFrameLoadedActionItem;
|
||||
import com.jpexs.decompiler.flash.action.parser.ActionParseException;
|
||||
import com.jpexs.decompiler.flash.action.parser.pcode.FlasmLexer;
|
||||
import com.jpexs.decompiler.flash.action.special.ActionStore;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.TranslateStack;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class ActionWaitForFrame extends Action implements ActionStore {
|
||||
|
||||
public int frame;
|
||||
|
||||
public int skipCount;
|
||||
|
||||
public List<Action> skipped;
|
||||
|
||||
public ActionWaitForFrame(int actionLength, SWFInputStream sis) throws IOException {
|
||||
super(0x8A, actionLength);
|
||||
frame = sis.readUI16("frame");
|
||||
skipCount = sis.readUI8("skipCount");
|
||||
skipped = new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "WaitForFrame";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getASMSource(ActionList container, Set<Long> knownAddreses, ScriptExportMode exportMode) {
|
||||
String ret = "WaitForFrame " + frame + " " + skipCount;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getBytes(int version) {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
SWFOutputStream sos = new SWFOutputStream(baos, version);
|
||||
try {
|
||||
sos.writeUI16(frame);
|
||||
sos.writeUI8(skipCount);
|
||||
sos.close();
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return surroundWithAction(baos.toByteArray(), version);
|
||||
}
|
||||
|
||||
public ActionWaitForFrame(FlasmLexer lexer) throws IOException, ActionParseException {
|
||||
super(0x8A, -1);
|
||||
frame = (int) lexLong(lexer);
|
||||
skipCount = (int) lexLong(lexer);
|
||||
skipped = new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) throws InterruptedException {
|
||||
GraphTargetItem frameTi = new DirectValueActionItem(null, 0, new Long(frame), new ArrayList<>());
|
||||
List<GraphTargetItem> body = ActionGraph.translateViaGraph(regNames, variables, functions, skipped, SWF.DEFAULT_VERSION, staticOperation, path);
|
||||
output.add(new IfFrameLoadedActionItem(frameTi, body, this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStoreSize() {
|
||||
return skipCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStore(List<Action> store) {
|
||||
skipped = store;
|
||||
skipCount = store.size();
|
||||
}
|
||||
}
|
||||
|
||||
+138
-138
@@ -1,138 +1,138 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.swf4;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.action.Action;
|
||||
import com.jpexs.decompiler.flash.action.ActionGraph;
|
||||
import com.jpexs.decompiler.flash.action.ActionList;
|
||||
import com.jpexs.decompiler.flash.action.model.clauses.IfFrameLoadedActionItem;
|
||||
import com.jpexs.decompiler.flash.action.parser.ActionParseException;
|
||||
import com.jpexs.decompiler.flash.action.parser.pcode.FlasmLexer;
|
||||
import com.jpexs.decompiler.flash.action.special.ActionStore;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.TranslateStack;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class ActionWaitForFrame2 extends Action implements ActionStore {
|
||||
|
||||
public int skipCount;
|
||||
|
||||
List<Action> skipped;
|
||||
|
||||
public ActionWaitForFrame2(int skipCount) {
|
||||
super(0x8D, 1);
|
||||
this.skipCount = skipCount;
|
||||
skipped = new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStoreSize() {
|
||||
return skipCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStore(List<Action> store) {
|
||||
skipped = store;
|
||||
skipCount = store.size();
|
||||
}
|
||||
|
||||
public ActionWaitForFrame2(int actionLength, SWFInputStream sis) throws IOException {
|
||||
super(0x8D, actionLength);
|
||||
skipCount = sis.readUI8("skipCount");
|
||||
skipped = new ArrayList<>();
|
||||
/*for (int i = 0; i < skipCount; i++) {
|
||||
Action a = sis.readAction(cpool);
|
||||
if (a instanceof ActionEnd) {
|
||||
skipCount = i;
|
||||
break;
|
||||
}
|
||||
if (a == null) {
|
||||
skipCount = i;
|
||||
break;
|
||||
}
|
||||
skipped.add(a);
|
||||
}
|
||||
boolean deobfuscate = Configuration.getConfig("autoDeobfuscate", true);
|
||||
if (deobfuscate) {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
for (int i = 0; i < skipCount; i++) {
|
||||
baos.write(skipped.get(i).getBytes(sis.getVersion()));
|
||||
}
|
||||
baos.write(new ActionEnd().getBytes(sis.getVersion()));
|
||||
SWFInputStream sis2 = new SWFInputStream(new ByteArrayInputStream(baos.toByteArray()), sis.getVersion());
|
||||
skipped = sis2.readActionList(new ArrayList<DisassemblyListener>(), 0, "");
|
||||
if (!skipped.isEmpty()) {
|
||||
if (skipped.get(skipped.size() - 1) instanceof ActionEnd) {
|
||||
skipped.remove(skipped.size() - 1);
|
||||
}
|
||||
}
|
||||
skipCount = skipped.size();
|
||||
}*/
|
||||
}
|
||||
|
||||
public ActionWaitForFrame2(FlasmLexer lexer) throws IOException, ActionParseException {
|
||||
super(0x8D, -1);
|
||||
skipCount = (int) lexLong(lexer);
|
||||
skipped = new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getBytes(int version) {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
SWFOutputStream sos = new SWFOutputStream(baos, version);
|
||||
try {
|
||||
sos.writeUI8(skipCount);
|
||||
sos.close();
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return surroundWithAction(baos.toByteArray(), version);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "WaitForFrame2";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getASMSource(ActionList container, Set<Long> knownAddreses, ScriptExportMode exportMode) {
|
||||
String ret = "WaitForFrame2 " + skipCount;
|
||||
/*for (int i = 0; i < skipped.size(); i++) {
|
||||
if (skipped.get(i) instanceof ActionEnd) {
|
||||
break;
|
||||
}
|
||||
ret += "\r\n" + skipped.get(i).getASMSource(container, knownAddreses, version, exportMode);
|
||||
}*/
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) throws InterruptedException {
|
||||
GraphTargetItem frame = stack.pop();
|
||||
List<GraphTargetItem> body = ActionGraph.translateViaGraph(regNames, variables, functions, skipped, SWF.DEFAULT_VERSION, staticOperation, path);
|
||||
output.add(new IfFrameLoadedActionItem(frame, body, this));
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.swf4;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.action.Action;
|
||||
import com.jpexs.decompiler.flash.action.ActionGraph;
|
||||
import com.jpexs.decompiler.flash.action.ActionList;
|
||||
import com.jpexs.decompiler.flash.action.model.clauses.IfFrameLoadedActionItem;
|
||||
import com.jpexs.decompiler.flash.action.parser.ActionParseException;
|
||||
import com.jpexs.decompiler.flash.action.parser.pcode.FlasmLexer;
|
||||
import com.jpexs.decompiler.flash.action.special.ActionStore;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.TranslateStack;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class ActionWaitForFrame2 extends Action implements ActionStore {
|
||||
|
||||
public int skipCount;
|
||||
|
||||
List<Action> skipped;
|
||||
|
||||
public ActionWaitForFrame2(int skipCount) {
|
||||
super(0x8D, 1);
|
||||
this.skipCount = skipCount;
|
||||
skipped = new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStoreSize() {
|
||||
return skipCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStore(List<Action> store) {
|
||||
skipped = store;
|
||||
skipCount = store.size();
|
||||
}
|
||||
|
||||
public ActionWaitForFrame2(int actionLength, SWFInputStream sis) throws IOException {
|
||||
super(0x8D, actionLength);
|
||||
skipCount = sis.readUI8("skipCount");
|
||||
skipped = new ArrayList<>();
|
||||
/*for (int i = 0; i < skipCount; i++) {
|
||||
Action a = sis.readAction(cpool);
|
||||
if (a instanceof ActionEnd) {
|
||||
skipCount = i;
|
||||
break;
|
||||
}
|
||||
if (a == null) {
|
||||
skipCount = i;
|
||||
break;
|
||||
}
|
||||
skipped.add(a);
|
||||
}
|
||||
boolean deobfuscate = Configuration.getConfig("autoDeobfuscate", true);
|
||||
if (deobfuscate) {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
for (int i = 0; i < skipCount; i++) {
|
||||
baos.write(skipped.get(i).getBytes(sis.getVersion()));
|
||||
}
|
||||
baos.write(new ActionEnd().getBytes(sis.getVersion()));
|
||||
SWFInputStream sis2 = new SWFInputStream(new ByteArrayInputStream(baos.toByteArray()), sis.getVersion());
|
||||
skipped = sis2.readActionList(new ArrayList<DisassemblyListener>(), 0, "");
|
||||
if (!skipped.isEmpty()) {
|
||||
if (skipped.get(skipped.size() - 1) instanceof ActionEnd) {
|
||||
skipped.remove(skipped.size() - 1);
|
||||
}
|
||||
}
|
||||
skipCount = skipped.size();
|
||||
}*/
|
||||
}
|
||||
|
||||
public ActionWaitForFrame2(FlasmLexer lexer) throws IOException, ActionParseException {
|
||||
super(0x8D, -1);
|
||||
skipCount = (int) lexLong(lexer);
|
||||
skipped = new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getBytes(int version) {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
SWFOutputStream sos = new SWFOutputStream(baos, version);
|
||||
try {
|
||||
sos.writeUI8(skipCount);
|
||||
sos.close();
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
return surroundWithAction(baos.toByteArray(), version);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "WaitForFrame2";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getASMSource(ActionList container, Set<Long> knownAddreses, ScriptExportMode exportMode) {
|
||||
String ret = "WaitForFrame2 " + skipCount;
|
||||
/*for (int i = 0; i < skipped.size(); i++) {
|
||||
if (skipped.get(i) instanceof ActionEnd) {
|
||||
break;
|
||||
}
|
||||
ret += "\r\n" + skipped.get(i).getASMSource(container, knownAddreses, version, exportMode);
|
||||
}*/
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) throws InterruptedException {
|
||||
GraphTargetItem frame = stack.pop();
|
||||
List<GraphTargetItem> body = ActionGraph.translateViaGraph(regNames, variables, functions, skipped, SWF.DEFAULT_VERSION, staticOperation, path);
|
||||
output.add(new IfFrameLoadedActionItem(frame, body, this));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,65 +1,65 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.swf4;
|
||||
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ConstantIndex implements Serializable {
|
||||
|
||||
public int index;
|
||||
|
||||
public List<String> constantPool;
|
||||
|
||||
public ConstantIndex(int index) {
|
||||
this.index = index;
|
||||
this.constantPool = new ArrayList<>();
|
||||
}
|
||||
|
||||
public ConstantIndex(int index, List<String> constantPool) {
|
||||
this.index = index;
|
||||
this.constantPool = constantPool;
|
||||
}
|
||||
|
||||
public String toStringNoQ() {
|
||||
if (Configuration.resolveConstants.get()) {
|
||||
if (constantPool != null) {
|
||||
if (index < constantPool.size()) {
|
||||
return constantPool.get(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return "constant" + index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (Configuration.resolveConstants.get()) {
|
||||
if (constantPool != null) {
|
||||
if (index < constantPool.size()) {
|
||||
return "\"" + Helper.escapeActionScriptString(constantPool.get(index)) + "\"";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return "constant" + index;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.swf4;
|
||||
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ConstantIndex implements Serializable {
|
||||
|
||||
public int index;
|
||||
|
||||
public List<String> constantPool;
|
||||
|
||||
public ConstantIndex(int index) {
|
||||
this.index = index;
|
||||
this.constantPool = new ArrayList<>();
|
||||
}
|
||||
|
||||
public ConstantIndex(int index, List<String> constantPool) {
|
||||
this.index = index;
|
||||
this.constantPool = constantPool;
|
||||
}
|
||||
|
||||
public String toStringNoQ() {
|
||||
if (Configuration.resolveConstants.get()) {
|
||||
if (constantPool != null) {
|
||||
if (index < constantPool.size()) {
|
||||
return constantPool.get(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return "constant" + index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (Configuration.resolveConstants.get()) {
|
||||
if (constantPool != null) {
|
||||
if (index < constantPool.size()) {
|
||||
return "\"" + Helper.escapeActionScriptString(constantPool.get(index)) + "\"";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return "constant" + index;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,42 +1,42 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.swf6;
|
||||
|
||||
import com.jpexs.decompiler.flash.action.Action;
|
||||
import com.jpexs.decompiler.flash.action.model.EnumerateActionItem;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.TranslateStack;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
public class ActionEnumerate2 extends Action {
|
||||
|
||||
public ActionEnumerate2() {
|
||||
super(0x55, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Enumerate2";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
GraphTargetItem object = stack.pop();
|
||||
stack.push(new EnumerateActionItem(this, object));
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.swf6;
|
||||
|
||||
import com.jpexs.decompiler.flash.action.Action;
|
||||
import com.jpexs.decompiler.flash.action.model.EnumerateActionItem;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.TranslateStack;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
public class ActionEnumerate2 extends Action {
|
||||
|
||||
public ActionEnumerate2() {
|
||||
super(0x55, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Enumerate2";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
GraphTargetItem object = stack.pop();
|
||||
stack.push(new EnumerateActionItem(this, object));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user