mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-10-01 13:50:45 +00:00
@@ -1,6 +1,30 @@
|
||||
# Change Log
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## [Unreleased]
|
||||
### Added
|
||||
- [#1449] Turkish translation by Osman ÖZ
|
||||
- AS2 classes: maintain order of variables, and methods (place variables before methods)
|
||||
- AS1/2: displaying script path in the error log when jump to invalid address
|
||||
- AS1/2: Try..catch with Error types - decompilation and direct editation
|
||||
- AS1/2: Properly handling of Flash7 scripts exported to Flash5/6 - ActionDefineFunction local registers
|
||||
|
||||
### Changed
|
||||
- AS1/2 direct editation - generated constantpool is sorted according to ActionPush position
|
||||
|
||||
### Fixed
|
||||
- Accessing font list on demand - prevents loading X11 on systems without UI
|
||||
- Better AS2 class detection
|
||||
- AS1/2 break statement decompilation in for..in loops
|
||||
- AS2 direct editation - not generating Pop in class header ifs
|
||||
- AS1/2 deobfuscation - ActionRandom fixed for nonpositive numbers
|
||||
- AS1/2 switch statement detection - fixes of default section position
|
||||
- AS1/2: break on the end of for..in loop
|
||||
- AS1/2: Export selection dialog did not allow to select script export formats and/or export script at all
|
||||
- AS3 P-code - HAS_OPTIONAL flag in AVM2 code displayed twice
|
||||
- Turkish locale toLowerCase I problem fix - causing not loading main window at all
|
||||
- [#1456] jsyntaxpane (code display/editor) fixed for Java 9/10
|
||||
|
||||
## [11.0.0] - 2018-01-17
|
||||
### Added
|
||||
- [#1240] AS search using multiple threads when parallel speedup is enabled
|
||||
@@ -2341,3 +2365,4 @@ All notable changes to this project will be documented in this file.
|
||||
[#1320]: https://www.free-decompiler.com/flash/issues/1320
|
||||
[#1323]: https://www.free-decompiler.com/flash/issues/1323
|
||||
[#27]: https://www.free-decompiler.com/flash/issues/27
|
||||
[#1449]: https://www.free-decompiler.com/flash/issues/1449
|
||||
|
||||
@@ -123,6 +123,7 @@ The application was made in Czech republic.
|
||||
* **Laurent LOUVET** - french translation
|
||||
* **MaGiC** - portugese translation
|
||||
* **martinkoza** - polish translation
|
||||
* **Osman ÖZ** - turkish translation
|
||||
* **pepka** - ukrainian and dutch translation
|
||||
* **poxyran** - spanish translation
|
||||
* **realmaster42** - portugese-brasil translation
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
- Russian
|
||||
- Spanish
|
||||
- Swedish
|
||||
- Turkish
|
||||
- Ukrainian
|
||||
|
||||
## New translation
|
||||
|
||||
@@ -368,6 +368,7 @@ var SMDir
|
||||
!insertmacro LANG_LOAD "Russian"
|
||||
!insertmacro LANG_LOAD "Spanish"
|
||||
!insertmacro LANG_LOAD "Swedish"
|
||||
!insertmacro LANG_LOAD "Turkish"
|
||||
!insertmacro LANG_LOAD "Ukrainian"
|
||||
!insertmacro LANG_LOAD "Italian"
|
||||
|
||||
|
||||
Binary file not shown.
@@ -12,10 +12,13 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
*/
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash;
|
||||
|
||||
import com.jpexs.decompiler.graph.Loop;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -24,8 +27,10 @@ import java.util.HashSet;
|
||||
public class FinalProcessLocalData {
|
||||
|
||||
public final HashSet<Integer> temporaryRegisters;
|
||||
public final List<Loop> loops;
|
||||
|
||||
public FinalProcessLocalData() {
|
||||
public FinalProcessLocalData(List<Loop> loops) {
|
||||
temporaryRegisters = new HashSet<>();
|
||||
this.loops = loops;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
*/
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash;
|
||||
|
||||
import SevenZip.Compression.LZMA.Decoder;
|
||||
@@ -348,6 +349,8 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
|
||||
private static final DecompilerPool decompilerPool = new DecompilerPool();
|
||||
|
||||
public static final String AS2_PKG_PREFIX = "__Packages.";
|
||||
|
||||
public static List<String> swfSignatures = Arrays.asList(
|
||||
"FWS", // Uncompressed Flash
|
||||
"CWS", // ZLib compressed Flash
|
||||
@@ -1708,8 +1711,9 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
}
|
||||
|
||||
private void getASMs(boolean exportFileNames, TreeItem treeItem, List<TreeItem> nodesToExport, boolean exportAll, Map<String, ASMSource> asmsToExport, String path) {
|
||||
boolean exportNode = nodesToExport.contains(treeItem);
|
||||
TreeItem realItem = treeItem instanceof TagScript ? ((TagScript) treeItem).getTag() : treeItem;
|
||||
boolean exportNode = nodesToExport.contains(treeItem) || nodesToExport.contains(realItem);
|
||||
|
||||
if (realItem instanceof ASMSource && (exportAll || exportNode)) {
|
||||
String npath = path;
|
||||
String exPath = path;
|
||||
@@ -1965,6 +1969,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
}
|
||||
|
||||
private static void getVariables(ConstantPool constantPool, BaseLocalData localData, TranslateStack stack, List<GraphTargetItem> output, ActionGraphSource code, int ip, List<MyEntry<DirectValueActionItem, ConstantPool>> variables, List<GraphSourceItem> functions, HashMap<DirectValueActionItem, ConstantPool> strings, List<Integer> visited, HashMap<DirectValueActionItem, String> usageTypes, String path) throws InterruptedException {
|
||||
ActionLocalData aLocalData = (ActionLocalData) localData;
|
||||
boolean debugMode = false;
|
||||
while ((ip > -1) && ip < code.size()) {
|
||||
if (visited.contains(ip)) {
|
||||
@@ -2031,7 +2036,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
ip = code.adr2pos(addr);
|
||||
addr += size;
|
||||
int nextip = code.adr2pos(addr);
|
||||
getVariables(variables, functions, strings, usageTypes, new ActionGraphSource(code.getActions().subList(ip, nextip), code.version, new HashMap<>(), new HashMap<>(), new HashMap<>()), 0, path + (cntName == null ? "" : "/" + cntName));
|
||||
getVariables(aLocalData.insideDoInitAction, variables, functions, strings, usageTypes, new ActionGraphSource(path, aLocalData.insideDoInitAction, code.getActions().subList(ip, nextip), code.version, new HashMap<>(), new HashMap<>(), new HashMap<>()), 0, path + (cntName == null ? "" : "/" + cntName));
|
||||
ip = nextip;
|
||||
}
|
||||
List<List<GraphTargetItem>> r = new ArrayList<>();
|
||||
@@ -2122,39 +2127,40 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
}
|
||||
}
|
||||
|
||||
private static void getVariables(List<MyEntry<DirectValueActionItem, ConstantPool>> variables, List<GraphSourceItem> functions, HashMap<DirectValueActionItem, ConstantPool> strings, HashMap<DirectValueActionItem, String> usageTypes, ActionGraphSource code, int addr, String path) throws InterruptedException {
|
||||
ActionLocalData localData = new ActionLocalData();
|
||||
private static void getVariables(boolean insideDoInitAction, List<MyEntry<DirectValueActionItem, ConstantPool>> variables, List<GraphSourceItem> functions, HashMap<DirectValueActionItem, ConstantPool> strings, HashMap<DirectValueActionItem, String> usageTypes, ActionGraphSource code, int addr, String path) throws InterruptedException {
|
||||
ActionLocalData localData = new ActionLocalData(insideDoInitAction);
|
||||
getVariables(null, localData, new TranslateStack(path), new ArrayList<>(), code, code.adr2pos(addr), variables, functions, strings, new ArrayList<>(), usageTypes, path);
|
||||
}
|
||||
|
||||
private List<MyEntry<DirectValueActionItem, ConstantPool>> getVariables(List<MyEntry<DirectValueActionItem, ConstantPool>> variables, HashMap<ASMSource, ActionList> actionsMap, List<GraphSourceItem> functions, HashMap<DirectValueActionItem, ConstantPool> strings, HashMap<DirectValueActionItem, String> usageTypes, ASMSource src, String path) throws InterruptedException {
|
||||
private List<MyEntry<DirectValueActionItem, ConstantPool>> getVariables(boolean insideDefineFunction1, List<MyEntry<DirectValueActionItem, ConstantPool>> variables, HashMap<ASMSource, ActionList> actionsMap, List<GraphSourceItem> functions, HashMap<DirectValueActionItem, ConstantPool> strings, HashMap<DirectValueActionItem, String> usageTypes, ASMSource src, String path) throws InterruptedException {
|
||||
List<MyEntry<DirectValueActionItem, ConstantPool>> ret = new ArrayList<>();
|
||||
ActionList actions = src.getActions();
|
||||
actionsMap.put(src, actions);
|
||||
getVariables(variables, functions, strings, usageTypes, new ActionGraphSource(actions, version, new HashMap<>(), new HashMap<>(), new HashMap<>()), 0, path);
|
||||
boolean insideDoInitAction = src instanceof DoInitActionTag;
|
||||
getVariables(insideDoInitAction, variables, functions, strings, usageTypes, new ActionGraphSource(path, insideDoInitAction, actions, version, new HashMap<>(), new HashMap<>(), new HashMap<>()), 0, path);
|
||||
return ret;
|
||||
}
|
||||
|
||||
private void getVariables(Iterable<Tag> tags, String path, List<MyEntry<DirectValueActionItem, ConstantPool>> variables, HashMap<ASMSource, ActionList> actionsMap, List<GraphSourceItem> functions, HashMap<DirectValueActionItem, ConstantPool> strings, HashMap<DirectValueActionItem, String> usageTypes) throws InterruptedException {
|
||||
private void getVariables(boolean insideDefineFunction1, Iterable<Tag> tags, String path, List<MyEntry<DirectValueActionItem, ConstantPool>> variables, HashMap<ASMSource, ActionList> actionsMap, List<GraphSourceItem> functions, HashMap<DirectValueActionItem, ConstantPool> strings, HashMap<DirectValueActionItem, String> usageTypes) throws InterruptedException {
|
||||
List<String> processed = new ArrayList<>();
|
||||
for (Tag t : tags) {
|
||||
String subPath = path + "/" + t.toString();
|
||||
if (t instanceof ASMSource) {
|
||||
addVariable((ASMSource) t, subPath, processed, variables, actionsMap, functions, strings, usageTypes);
|
||||
addVariable(insideDefineFunction1, (ASMSource) t, subPath, processed, variables, actionsMap, functions, strings, usageTypes);
|
||||
}
|
||||
if (t instanceof ASMSourceContainer) {
|
||||
List<String> processed2 = new ArrayList<>();
|
||||
for (ASMSource asm : ((ASMSourceContainer) t).getSubItems()) {
|
||||
addVariable(asm, subPath + "/" + asm.toString(), processed2, variables, actionsMap, functions, strings, usageTypes);
|
||||
addVariable(insideDefineFunction1, asm, subPath + "/" + asm.toString(), processed2, variables, actionsMap, functions, strings, usageTypes);
|
||||
}
|
||||
}
|
||||
if (t instanceof DefineSpriteTag) {
|
||||
getVariables(((DefineSpriteTag) t).getTags(), path + "/" + t.toString(), variables, actionsMap, functions, strings, usageTypes);
|
||||
getVariables(insideDefineFunction1, ((DefineSpriteTag) t).getTags(), path + "/" + t.toString(), variables, actionsMap, functions, strings, usageTypes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addVariable(ASMSource asm, String path, List<String> processed, List<MyEntry<DirectValueActionItem, ConstantPool>> variables, HashMap<ASMSource, ActionList> actionsMap, List<GraphSourceItem> functions, HashMap<DirectValueActionItem, ConstantPool> strings, HashMap<DirectValueActionItem, String> usageTypes) throws InterruptedException {
|
||||
private void addVariable(boolean insideDefineFunction1, ASMSource asm, String path, List<String> processed, List<MyEntry<DirectValueActionItem, ConstantPool>> variables, HashMap<ASMSource, ActionList> actionsMap, List<GraphSourceItem> functions, HashMap<DirectValueActionItem, ConstantPool> strings, HashMap<DirectValueActionItem, String> usageTypes) throws InterruptedException {
|
||||
int pos = 1;
|
||||
String infPath2 = path;
|
||||
while (processed.contains(infPath2)) {
|
||||
@@ -2163,7 +2169,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
}
|
||||
processed.add(infPath2);
|
||||
informListeners("getVariables", infPath2);
|
||||
getVariables(variables, actionsMap, functions, strings, usageTypes, asm, path);
|
||||
getVariables(insideDefineFunction1, variables, actionsMap, functions, strings, usageTypes, asm, path);
|
||||
}
|
||||
|
||||
public boolean as3StringConstantExists(String str) {
|
||||
@@ -2252,7 +2258,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
HashMap<DirectValueActionItem, String> usageTypes = new HashMap<>();
|
||||
|
||||
int ret = 0;
|
||||
getVariables(getTags(), "", allVariableNames, actionsMap, allFunctions, allStrings, usageTypes);
|
||||
getVariables(false, getTags(), "", allVariableNames, actionsMap, allFunctions, allStrings, usageTypes);
|
||||
informListeners("rename", "");
|
||||
int fc = 0;
|
||||
for (MyEntry<DirectValueActionItem, ConstantPool> it : allVariableNames) {
|
||||
@@ -2275,10 +2281,9 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
DoInitActionTag dia = (DoInitActionTag) t;
|
||||
String exportName = getExportName(dia.spriteId);
|
||||
exportName = exportName != null ? exportName : "_unk_";
|
||||
final String pkgPrefix = "__Packages.";
|
||||
String[] classNameParts = null;
|
||||
if (exportName.startsWith(pkgPrefix)) {
|
||||
String className = exportName.substring(pkgPrefix.length());
|
||||
if (exportName.startsWith(AS2_PKG_PREFIX)) {
|
||||
String className = exportName.substring(AS2_PKG_PREFIX.length());
|
||||
if (className.contains(".")) {
|
||||
classNameParts = className.split("\\.");
|
||||
} else {
|
||||
@@ -2288,7 +2293,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
int staticOperation = Graph.SOP_USE_STATIC; //(Boolean) Configuration.getConfig("autoDeobfuscate", true) ? Graph.SOP_SKIP_STATIC : Graph.SOP_USE_STATIC;
|
||||
List<GraphTargetItem> dec;
|
||||
try {
|
||||
dec = Action.actionsToTree(dia.getActions(), version, staticOperation, ""/*FIXME*/);
|
||||
dec = Action.actionsToTree(true /*Yes, inside doInitAction*/, dia.getActions(), version, staticOperation, ""/*FIXME*/);
|
||||
} catch (EmptyStackException ex) {
|
||||
continue;
|
||||
}
|
||||
@@ -2297,9 +2302,15 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
if (it instanceof ClassActionItem) {
|
||||
ClassActionItem cti = (ClassActionItem) it;
|
||||
List<GraphTargetItem> methods = new ArrayList<>();
|
||||
methods.addAll(cti.functions);
|
||||
methods.addAll(cti.staticFunctions);
|
||||
List<GraphTargetItem> vars = new ArrayList<>();
|
||||
|
||||
for (MyEntry<GraphTargetItem, GraphTargetItem> trait : cti.traits) {
|
||||
if (trait.getValue() instanceof FunctionActionItem) {
|
||||
methods.add(trait.getValue());
|
||||
} else {
|
||||
vars.add(trait.getValue());
|
||||
}
|
||||
}
|
||||
for (GraphTargetItem gti : methods) {
|
||||
if (gti instanceof FunctionActionItem) {
|
||||
FunctionActionItem fun = (FunctionActionItem) gti;
|
||||
@@ -2314,13 +2325,6 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
}
|
||||
}
|
||||
|
||||
List<GraphTargetItem> vars = new ArrayList<>();
|
||||
for (MyEntry<GraphTargetItem, GraphTargetItem> item : cti.vars) {
|
||||
vars.add(item.getKey());
|
||||
}
|
||||
for (MyEntry<GraphTargetItem, GraphTargetItem> item : cti.staticVars) {
|
||||
vars.add(item.getKey());
|
||||
}
|
||||
for (GraphTargetItem gti : vars) {
|
||||
if (gti instanceof DirectValueActionItem) {
|
||||
DirectValueActionItem dvf = (DirectValueActionItem) gti;
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
*/
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2;
|
||||
|
||||
import com.jpexs.decompiler.flash.EndOfStreamException;
|
||||
@@ -264,7 +265,7 @@ import com.jpexs.decompiler.flash.abc.avm2.model.clauses.DeclarationAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.clauses.ForEachInAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.clauses.ForInAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.parser.script.PropertyAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.parser.script.Reference;
|
||||
import com.jpexs.helpers.Reference;
|
||||
import com.jpexs.decompiler.flash.abc.types.ABCException;
|
||||
import com.jpexs.decompiler.flash.abc.types.AssignedValue;
|
||||
import com.jpexs.decompiler.flash.abc.types.ConvertData;
|
||||
@@ -1175,7 +1176,6 @@ public class AVM2Code implements Cloneable {
|
||||
writer.appendNoHilight("flag ");
|
||||
writer.hilightSpecial("HAS_OPTIONAL", HighlightSpecialType.FLAG_HAS_OPTIONAL);
|
||||
writer.newLine();
|
||||
writer.appendNoHilight("flag HAS_OPTIONAL").newLine();
|
||||
}
|
||||
if (info.flagHas_paramnames()) {
|
||||
writer.appendNoHilight("flag ");
|
||||
@@ -2172,8 +2172,7 @@ public class AVM2Code implements Cloneable {
|
||||
ins.operands[j] = updater.updateOperandOffset(target, ins.operands[j]);
|
||||
}
|
||||
}*/ //Faster, but not so universal
|
||||
{
|
||||
if (ins.definition instanceof IfTypeIns) {
|
||||
if (ins.definition instanceof IfTypeIns) {
|
||||
long target = ins.getTargetAddress();
|
||||
try {
|
||||
ins.operands[0] = updater.updateOperandOffset(ins.getAddress(), target, ins.operands[0]);
|
||||
@@ -2181,7 +2180,6 @@ public class AVM2Code implements Cloneable {
|
||||
throw new ConvertException("Invalid offset (" + ins + ")", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
ins.setAddress(updater.updateInstructionOffset(ins.getAddress()));
|
||||
//Note: changing operands here does not change instruction byte length as offsets are always S24 (not variable length)
|
||||
}
|
||||
|
||||
+3
-2
@@ -12,7 +12,8 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
*/
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.deobfuscation;
|
||||
|
||||
import com.jpexs.decompiler.flash.BaseLocalData;
|
||||
@@ -32,7 +33,7 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.SetLocalTypeIn
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.ReturnValueIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.ReturnVoidIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.ThrowIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.parser.script.Reference;
|
||||
import com.jpexs.helpers.Reference;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodBody;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.Trait;
|
||||
|
||||
+3
-2
@@ -12,7 +12,8 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
*/
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.deobfuscation;
|
||||
|
||||
import com.jpexs.decompiler.flash.BaseLocalData;
|
||||
@@ -30,7 +31,7 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.other.ReturnValueIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.ReturnVoidIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.ThrowIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.NullAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.parser.script.Reference;
|
||||
import com.jpexs.helpers.Reference;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodBody;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.Trait;
|
||||
import com.jpexs.decompiler.graph.Graph;
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
*/
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.graph;
|
||||
|
||||
import com.jpexs.decompiler.flash.BaseLocalData;
|
||||
@@ -571,8 +572,8 @@ public class AVM2Graph extends Graph {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalProcessAfter(List<GraphTargetItem> list, int level, FinalProcessLocalData localData) {
|
||||
super.finalProcessAfter(list, level, localData);
|
||||
protected void finalProcessAfter(List<GraphTargetItem> list, int level, FinalProcessLocalData localData, String path) {
|
||||
super.finalProcessAfter(list, level, localData, path);
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
if (list.get(i) instanceof SetLocalAVM2Item) {
|
||||
SetLocalAVM2Item ri = (SetLocalAVM2Item) list.get(i);
|
||||
@@ -585,7 +586,7 @@ public class AVM2Graph extends Graph {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalProcess(List<GraphTargetItem> list, int level, FinalProcessLocalData localData) throws InterruptedException {
|
||||
protected void finalProcess(List<GraphTargetItem> list, int level, FinalProcessLocalData localData, String path) throws InterruptedException {
|
||||
|
||||
if (level == 0) {
|
||||
if (!list.isEmpty()) {
|
||||
@@ -702,7 +703,7 @@ public class AVM2Graph extends Graph {
|
||||
}
|
||||
}
|
||||
//Handle for loops at the end:
|
||||
super.finalProcess(list, level, localData);
|
||||
super.finalProcess(list, level, localData, path);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
*/
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.graph;
|
||||
|
||||
import com.jpexs.decompiler.flash.BaseLocalData;
|
||||
@@ -21,7 +22,7 @@ import com.jpexs.decompiler.flash.abc.AVM2LocalData;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConvertOutput;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.parser.script.Reference;
|
||||
import com.jpexs.helpers.Reference;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodBody;
|
||||
import com.jpexs.decompiler.graph.DottedChain;
|
||||
import com.jpexs.decompiler.graph.GraphPart;
|
||||
|
||||
+3
-2
@@ -12,7 +12,8 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
*/
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
@@ -29,7 +30,7 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.IncLocalIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.SetLocalTypeIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.AVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.parser.script.Reference;
|
||||
import com.jpexs.helpers.Reference;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodBody;
|
||||
import com.jpexs.decompiler.flash.abc.types.Multiname;
|
||||
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
|
||||
+3
-1
@@ -12,9 +12,11 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
*/
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.parser.script;
|
||||
|
||||
import com.jpexs.helpers.Reference;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
|
||||
+3
-1
@@ -12,9 +12,11 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
*/
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.parser.script;
|
||||
|
||||
import com.jpexs.helpers.Reference;
|
||||
import com.jpexs.decompiler.flash.SWC;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
|
||||
|
||||
+3
-1
@@ -12,9 +12,11 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
*/
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.parser.script;
|
||||
|
||||
import com.jpexs.helpers.Reference;
|
||||
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instructions;
|
||||
|
||||
+3
-1
@@ -12,9 +12,11 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
*/
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.parser.script;
|
||||
|
||||
import com.jpexs.helpers.Reference;
|
||||
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
|
||||
+3
-1
@@ -12,9 +12,11 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
*/
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.parser.script;
|
||||
|
||||
import com.jpexs.helpers.Reference;
|
||||
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instructions;
|
||||
import com.jpexs.decompiler.flash.abc.types.Multiname;
|
||||
|
||||
+3
-1
@@ -12,9 +12,11 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
*/
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.parser.script;
|
||||
|
||||
import com.jpexs.helpers.Reference;
|
||||
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instructions;
|
||||
|
||||
+3
-1
@@ -12,9 +12,11 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
*/
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.parser.script;
|
||||
|
||||
import com.jpexs.helpers.Reference;
|
||||
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.types.Namespace;
|
||||
|
||||
+3
-1
@@ -12,9 +12,11 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
*/
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.parser.script;
|
||||
|
||||
import com.jpexs.helpers.Reference;
|
||||
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool;
|
||||
|
||||
+3
-1
@@ -12,9 +12,11 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
*/
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.parser.script;
|
||||
|
||||
import com.jpexs.helpers.Reference;
|
||||
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool;
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
*/
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action;
|
||||
|
||||
import com.jpexs.decompiler.flash.AppResources;
|
||||
@@ -20,9 +21,10 @@ import com.jpexs.decompiler.flash.BaseLocalData;
|
||||
import com.jpexs.decompiler.flash.DisassemblyListener;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.parser.script.Reference;
|
||||
import com.jpexs.helpers.Reference;
|
||||
import com.jpexs.decompiler.flash.action.deobfuscation.ActionDeobfuscator;
|
||||
import com.jpexs.decompiler.flash.action.model.ActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.CallMethodActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.ConstantPool;
|
||||
import com.jpexs.decompiler.flash.action.model.DirectValueActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.ExtendsActionItem;
|
||||
@@ -65,6 +67,7 @@ import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.flash.helpers.NulWriter;
|
||||
import com.jpexs.decompiler.flash.helpers.SWFDecompilerPlugin;
|
||||
import com.jpexs.decompiler.flash.helpers.collections.MyEntry;
|
||||
import com.jpexs.decompiler.flash.tags.DoInitActionTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ASMSource;
|
||||
import com.jpexs.decompiler.graph.Graph;
|
||||
import com.jpexs.decompiler.graph.GraphSource;
|
||||
@@ -78,6 +81,7 @@ import com.jpexs.decompiler.graph.model.IfItem;
|
||||
import com.jpexs.decompiler.graph.model.LocalData;
|
||||
import com.jpexs.decompiler.graph.model.NotItem;
|
||||
import com.jpexs.decompiler.graph.model.PopItem;
|
||||
import com.jpexs.decompiler.graph.model.PushItem;
|
||||
import com.jpexs.decompiler.graph.model.ScriptEndItem;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import com.jpexs.helpers.CancellableWorker;
|
||||
@@ -756,7 +760,7 @@ public abstract class Action implements GraphSourceItem {
|
||||
* @param path the value of path
|
||||
* @throws java.lang.InterruptedException
|
||||
*/
|
||||
public void translate(GraphSourceItem lineStartIns, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) throws InterruptedException {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartIns, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) throws InterruptedException {
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -832,8 +836,8 @@ public abstract class Action implements GraphSourceItem {
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static List<GraphTargetItem> actionsToTree(List<Action> actions, int version, int staticOperation, String path) throws InterruptedException {
|
||||
return actionsToTree(new HashMap<>(), new HashMap<>(), new HashMap<>(), actions, version, staticOperation, path);
|
||||
public static List<GraphTargetItem> actionsToTree(boolean insideDoInitAction, List<Action> actions, int version, int staticOperation, String path) throws InterruptedException {
|
||||
return actionsToTree(insideDoInitAction, new HashMap<>(), new HashMap<>(), new HashMap<>(), actions, version, staticOperation, path);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -858,7 +862,8 @@ public abstract class Action implements GraphSourceItem {
|
||||
@Override
|
||||
public List<GraphTargetItem> call() throws Exception {
|
||||
int staticOperation = Graph.SOP_USE_STATIC; //(Boolean) Configuration.getConfig("autoDeobfuscate", true) ? Graph.SOP_SKIP_STATIC : Graph.SOP_USE_STATIC;
|
||||
List<GraphTargetItem> tree = actionsToTree(new HashMap<>(), new HashMap<>(), new HashMap<>(), actions, version, staticOperation, path);
|
||||
boolean insideDoInitAction = (asm instanceof DoInitActionTag);
|
||||
List<GraphTargetItem> tree = actionsToTree(insideDoInitAction, new HashMap<>(), new HashMap<>(), new HashMap<>(), actions, version, staticOperation, path);
|
||||
SWFDecompilerPlugin.fireActionTreeCreated(tree, swf);
|
||||
if (Configuration.autoDeobfuscate.get()) {
|
||||
new ActionDeobfuscator().actionTreeCreated(tree, swf);
|
||||
@@ -916,8 +921,8 @@ public abstract class Action implements GraphSourceItem {
|
||||
* @return List of treeItems
|
||||
* @throws java.lang.InterruptedException
|
||||
*/
|
||||
public static List<GraphTargetItem> actionsToTree(HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, List<Action> actions, int version, int staticOperation, String path) throws InterruptedException {
|
||||
return ActionGraph.translateViaGraph(regNames, variables, functions, actions, version, staticOperation, path);
|
||||
public static List<GraphTargetItem> actionsToTree(boolean insideDoInitAction, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, List<Action> actions, int version, int staticOperation, String path) throws InterruptedException {
|
||||
return ActionGraph.translateViaGraph(insideDoInitAction, regNames, variables, functions, actions, version, staticOperation, path);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -929,7 +934,7 @@ public abstract class Action implements GraphSourceItem {
|
||||
}
|
||||
expectedSize += getStackPushCount(localData, stack);*/
|
||||
|
||||
translate(aLocalData.lineStartAction, stack, output, aLocalData.regNames, aLocalData.variables, aLocalData.functions, staticOperation, path);
|
||||
translate(aLocalData.insideDoInitAction, aLocalData.lineStartAction, stack, output, aLocalData.regNames, aLocalData.variables, aLocalData.functions, staticOperation, path);
|
||||
/*if (stack.size() != expectedSize && !(this instanceof ActionPushDuplicate)) {
|
||||
throw new Error("HONFIKA stack size mismatch");
|
||||
}*/
|
||||
@@ -965,11 +970,11 @@ public abstract class Action implements GraphSourceItem {
|
||||
this.ignored = ignored;
|
||||
}
|
||||
|
||||
public static List<GraphTargetItem> actionsPartToTree(Reference<GraphSourceItem> fi, HashMap<Integer, String> registerNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, TranslateStack stack, List<Action> actions, int start, int end, int version, int staticOperation, String path) throws InterruptedException {
|
||||
public static List<GraphTargetItem> actionsPartToTree(boolean insideDoInitAction, Reference<GraphSourceItem> fi, HashMap<Integer, String> registerNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, TranslateStack stack, List<Action> actions, int start, int end, int version, int staticOperation, String path) throws InterruptedException {
|
||||
if (start < actions.size() && (end > 0) && (start > 0)) {
|
||||
logger.log(Level.FINE, "Entering {0}-{1}{2}", new Object[]{start, end, actions.size() > 0 ? (" (" + actions.get(start).toString() + " - " + actions.get(end == actions.size() ? end - 1 : end) + ")") : ""});
|
||||
}
|
||||
ActionLocalData localData = new ActionLocalData(registerNames, variables, functions);
|
||||
ActionLocalData localData = new ActionLocalData(insideDoInitAction, registerNames, variables, functions);
|
||||
localData.lineStartAction = fi.getVal();
|
||||
List<GraphTargetItem> output = new ArrayList<>();
|
||||
int ip = start;
|
||||
@@ -1039,7 +1044,7 @@ public abstract class Action implements GraphSourceItem {
|
||||
}
|
||||
}
|
||||
}
|
||||
out = ActionGraph.translateViaGraph(regNames, variables2, functions, actions.subList(adr2ip(actions, endAddr), adr2ip(actions, endAddr + size)), version, staticOperation, path + (cntName == null ? "" : "/" + cntName));
|
||||
out = ActionGraph.translateViaGraph(insideDoInitAction, regNames, variables2, functions, actions.subList(adr2ip(actions, endAddr), adr2ip(actions, endAddr + size)), version, staticOperation, path + (cntName == null ? "" : "/" + cntName));
|
||||
} catch (OutOfMemoryError | TranslateException | StackOverflowError ex) {
|
||||
logger.log(Level.SEVERE, "Decompilation error in: " + path, ex);
|
||||
if (ex instanceof OutOfMemoryError) {
|
||||
@@ -1072,7 +1077,7 @@ public abstract class Action implements GraphSourceItem {
|
||||
if (actions.get(ip + 2) instanceof ActionNot) {
|
||||
if (actions.get(ip + 3) instanceof ActionIf) {
|
||||
ActionIf aif = (ActionIf) actions.get(ip + 3);
|
||||
if (adr2ip(actions, ip2adr(actions, ip + 4) + aif.getJumpOffset()) == ip) {
|
||||
if (adr2ip(actions, ip2adr(actions, ip + 3) + 5 + aif.getJumpOffset()) == ip) {
|
||||
ip += 4;
|
||||
continue;
|
||||
}
|
||||
@@ -1082,103 +1087,16 @@ public abstract class Action implements GraphSourceItem {
|
||||
}
|
||||
}
|
||||
|
||||
/*ActionJump && ActionIf removed*/
|
||||
/*if ((action instanceof ActionEnumerate2) || (action instanceof ActionEnumerate)) {
|
||||
loopStart = ip + 1;
|
||||
isForIn = true;
|
||||
ip += 4;
|
||||
action.translate(localData, stack, output);
|
||||
EnumerateActionItem en = (EnumerateActionItem) stack.peek();
|
||||
inItem = en.object;
|
||||
continue;
|
||||
} else*/ /*if (action instanceof ActionTry) {
|
||||
ActionTry atry = (ActionTry) action;
|
||||
List<GraphTargetItem> tryCommands = ActionGraph.translateViaGraph(registerNames, variables, functions, atry.tryBody, version);
|
||||
ActionItem catchName;
|
||||
if (atry.catchInRegisterFlag) {
|
||||
catchName = new DirectValueActionItem(atry, -1, new RegisterNumber(atry.catchRegister), new ArrayList<>());
|
||||
} else {
|
||||
catchName = new DirectValueActionItem(atry, -1, atry.catchName, new ArrayList<>());
|
||||
}
|
||||
List<GraphTargetItem> catchExceptions = new ArrayList<GraphTargetItem>();
|
||||
catchExceptions.add(catchName);
|
||||
List<List<GraphTargetItem>> catchCommands = new ArrayList<List<GraphTargetItem>>();
|
||||
catchCommands.add(ActionGraph.translateViaGraph(registerNames, variables, functions, atry.catchBody, version));
|
||||
List<GraphTargetItem> finallyCommands = ActionGraph.translateViaGraph(registerNames, variables, functions, atry.finallyBody, version);
|
||||
output.add(new TryActionItem(tryCommands, catchExceptions, catchCommands, finallyCommands));
|
||||
} else if (action instanceof ActionWith) {
|
||||
ActionWith awith = (ActionWith) action;
|
||||
List<GraphTargetItem> withCommands = ActionGraph.translateViaGraph(registerNames, variables, functions,new ArrayList<Action>() , version); //TODO:parse with actions
|
||||
output.add(new WithActionItem(action, stack.pop(), withCommands));
|
||||
} else */ if (false) {
|
||||
} /*if (action instanceof ActionStoreRegister) {
|
||||
if ((ip + 1 <= end) && (actions.get(ip + 1) instanceof ActionPop)) {
|
||||
action.translate(localData, stack, output);
|
||||
stack.pop();
|
||||
ip++;
|
||||
} else {
|
||||
try {
|
||||
action.translate(localData, stack, output);
|
||||
} catch (Exception ex) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
} */ /*else if (action instanceof ActionStrictEquals) {
|
||||
if ((ip + 1 < actions.size()) && (actions.get(ip + 1) instanceof ActionIf)) {
|
||||
List<ActionItem> caseValues = new ArrayList<ActionItem>();
|
||||
List<List<ActionItem>> caseCommands = new ArrayList<List<ActionItem>>();
|
||||
caseValues.add(stack.pop());
|
||||
ActionItem switchedObject = stack.pop();
|
||||
if (output.size() > 0) {
|
||||
if (output.get(output.size() - 1) instanceof StoreRegisterActionItem) {
|
||||
output.remove(output.size() - 1);
|
||||
}
|
||||
}
|
||||
int caseStart = ip + 2;
|
||||
List<Integer> caseBodyIps = new ArrayList<Integer>();
|
||||
long defaultAddr = 0;
|
||||
caseBodyIps.add(adr2ip(actions, ((ActionIf) actions.get(ip + 1)).getRef(version), version));
|
||||
ip++;
|
||||
do {
|
||||
ip++;
|
||||
if ((actions.get(ip - 1) instanceof ActionStrictEquals) && (actions.get(ip) instanceof ActionIf)) {
|
||||
caseValues.add(actionsToStackTree(registerNames, jumpsOrIfs, actions, constants, caseStart, ip - 2, version).pop());
|
||||
caseStart = ip + 1;
|
||||
caseBodyIps.add(adr2ip(actions, ((ActionIf) actions.get(ip)).getRef(version), version));
|
||||
if (actions.get(ip + 1) instanceof ActionJump) {
|
||||
defaultAddr = ((ActionJump) actions.get(ip + 1)).getRef(version);
|
||||
ip = adr2ip(actions, defaultAddr, version);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (ip < end);
|
||||
|
||||
for (int i = 0; i < caseBodyIps.size(); i++) {
|
||||
int caseEnd = ip - 1;
|
||||
if (i < caseBodyIps.size() - 1) {
|
||||
caseEnd = caseBodyIps.get(i + 1) - 1;
|
||||
}
|
||||
caseCommands.add(actionsToTree(registerNames, unknownJumps, loopList, jumpsOrIfs, stack, constants, actions, caseBodyIps.get(i), caseEnd, version));
|
||||
}
|
||||
output.add(new SwitchActionItem(action, defaultAddr, switchedObject, caseValues, caseCommands, null));
|
||||
continue;
|
||||
} else {
|
||||
action.translate(stack, constants, output, registerNames);
|
||||
}
|
||||
} */ else {
|
||||
|
||||
if (action instanceof ActionStore) {
|
||||
ActionStore store = (ActionStore) action;
|
||||
store.setStore(actions.subList(ip + 1, ip + 1 + store.getStoreSize()));
|
||||
ip = ip + 1 + store.getStoreSize() - 1/*ip++ will be next*/;
|
||||
}
|
||||
|
||||
action.translate(localData, stack, output, staticOperation, path);
|
||||
if (action instanceof ActionStore) {
|
||||
ActionStore store = (ActionStore) action;
|
||||
store.setStore(actions.subList(ip + 1, ip + 1 + store.getStoreSize()));
|
||||
ip = ip + 1 + store.getStoreSize() - 1/*ip++ will be next*/;
|
||||
}
|
||||
|
||||
action.translate(localData, stack, output, staticOperation, path);
|
||||
|
||||
ip++;
|
||||
}
|
||||
//output = checkClass(output);
|
||||
logger.log(Level.FINE, "Leaving {0}-{1}", new Object[]{start, end});
|
||||
return output;
|
||||
}
|
||||
@@ -1211,155 +1129,6 @@ public abstract class Action implements GraphSourceItem {
|
||||
return ti;
|
||||
}
|
||||
|
||||
public static List<GraphTargetItem> checkClass(List<GraphTargetItem> output) {
|
||||
if (true) {
|
||||
//return output;
|
||||
}
|
||||
List<GraphTargetItem> ret = new ArrayList<>();
|
||||
List<GraphTargetItem> functions = new ArrayList<>();
|
||||
List<GraphTargetItem> staticFunctions = new ArrayList<>();
|
||||
List<MyEntry<GraphTargetItem, GraphTargetItem>> vars = new ArrayList<>();
|
||||
List<MyEntry<GraphTargetItem, GraphTargetItem>> staticVars = new ArrayList<>();
|
||||
GraphTargetItem className;
|
||||
GraphTargetItem extendsOp = null;
|
||||
List<GraphTargetItem> implementsOp = new ArrayList<>();
|
||||
boolean ok = true;
|
||||
int prevCount = 0;
|
||||
for (GraphTargetItem t : output) {
|
||||
if (t instanceof IfItem) {
|
||||
IfItem it = (IfItem) t;
|
||||
if (it.expression instanceof NotItem) {
|
||||
NotItem nti = (NotItem) it.expression;
|
||||
if ((nti.value instanceof GetMemberActionItem) || (nti.value instanceof GetVariableActionItem)) {
|
||||
if (true) { //it.onFalse.isEmpty()){ //||(it.onFalse.get(0) instanceof UnsupportedActionItem)) {
|
||||
if ((it.onTrue.size() == 1) && (it.onTrue.get(0) instanceof SetMemberActionItem) && (((SetMemberActionItem) it.onTrue.get(0)).value instanceof NewObjectActionItem)) {
|
||||
// ignore
|
||||
} else {
|
||||
List<GraphTargetItem> parts = it.onTrue;
|
||||
className = getWithoutGlobal(nti.value);
|
||||
if (parts.size() >= 1) {
|
||||
int ipos = 0;
|
||||
|
||||
while ((parts.get(ipos) instanceof PopItem) || ((parts.get(ipos) instanceof IfItem) && ((((IfItem) parts.get(ipos)).onTrue.size() == 1) && (((IfItem) parts.get(ipos)).onTrue.get(0) instanceof SetMemberActionItem) && (((SetMemberActionItem) ((IfItem) parts.get(ipos)).onTrue.get(0)).value instanceof NewObjectActionItem)))) {
|
||||
ipos++;
|
||||
}
|
||||
if (parts.get(ipos) instanceof ExtendsActionItem) {
|
||||
ExtendsActionItem et = (ExtendsActionItem) parts.get(ipos);
|
||||
extendsOp = getWithoutGlobal(et.superclass);
|
||||
ipos++;
|
||||
}
|
||||
if (parts.get(ipos) instanceof StoreRegisterActionItem) {
|
||||
StoreRegisterActionItem sr = (StoreRegisterActionItem) parts.get(ipos);
|
||||
int instanceReg = sr.register.number;
|
||||
if (sr.value instanceof GetMemberActionItem) {
|
||||
GetMemberActionItem gm = (GetMemberActionItem) sr.value;
|
||||
//gm.memberName should be "prototype"
|
||||
if (gm.object instanceof TemporaryRegister) {
|
||||
TemporaryRegister tm = (TemporaryRegister) gm.object;
|
||||
int classReg = tm.getRegId();
|
||||
if (tm.value instanceof SetMemberActionItem) {
|
||||
SetMemberActionItem sm = (SetMemberActionItem) tm.value;
|
||||
if (sm.value instanceof StoreRegisterActionItem) {
|
||||
sr = (StoreRegisterActionItem) sm.value;
|
||||
if (sr.value instanceof FunctionActionItem) {
|
||||
((FunctionActionItem) (sr.value)).calculatedFunctionName = (className instanceof GetMemberActionItem) ? ((GetMemberActionItem) className).memberName : className;
|
||||
functions.add((FunctionActionItem) sr.value);
|
||||
|
||||
for (; ipos < parts.size(); ipos++) {
|
||||
if (parts.get(ipos) instanceof ImplementsOpActionItem) {
|
||||
ImplementsOpActionItem io = (ImplementsOpActionItem) parts.get(ipos);
|
||||
implementsOp = io.superclasses;
|
||||
continue;
|
||||
}
|
||||
if (parts.get(ipos) instanceof SetMemberActionItem) {
|
||||
sm = (SetMemberActionItem) parts.get(ipos);
|
||||
int rnum = -1;
|
||||
if (sm.object instanceof DirectValueActionItem) {
|
||||
DirectValueActionItem dv = (DirectValueActionItem) sm.object;
|
||||
if (dv.value instanceof RegisterNumber) {
|
||||
RegisterNumber rn = (RegisterNumber) dv.value;
|
||||
rnum = rn.number;
|
||||
}
|
||||
}
|
||||
if (sm.object instanceof TemporaryRegister) {
|
||||
rnum = ((TemporaryRegister) sm.object).getRegId();
|
||||
}
|
||||
if (rnum == instanceReg) {
|
||||
if (sm.value instanceof FunctionActionItem) {
|
||||
((FunctionActionItem) sm.value).calculatedFunctionName = sm.objectName;
|
||||
functions.add((FunctionActionItem) sm.value);
|
||||
} else {
|
||||
vars.add(new MyEntry<>(sm.objectName, sm.value));
|
||||
}
|
||||
} else if (rnum == classReg) {
|
||||
if (sm.value instanceof FunctionActionItem) {
|
||||
((FunctionActionItem) sm.value).calculatedFunctionName = sm.objectName;
|
||||
staticFunctions.add((FunctionActionItem) sm.value);
|
||||
} else {
|
||||
staticVars.add(new MyEntry<>(sm.objectName, sm.value));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
List<GraphTargetItem> output2 = new ArrayList<>();
|
||||
for (int i = 0; i < prevCount; i++) {
|
||||
output2.add(output.get(i));
|
||||
}
|
||||
output2.add(new ClassActionItem(className, extendsOp, implementsOp, null/*FIXME*/, functions, vars, staticFunctions, staticVars));
|
||||
return output2;
|
||||
}
|
||||
}
|
||||
} else if (parts.get(ipos) instanceof SetMemberActionItem) {
|
||||
SetMemberActionItem sm = (SetMemberActionItem) parts.get(0);
|
||||
if (sm.value instanceof FunctionActionItem) {
|
||||
FunctionActionItem f = (FunctionActionItem) sm.value;
|
||||
if (f.actions.isEmpty()) {
|
||||
if (parts.size() == 2) {
|
||||
if (parts.get(1) instanceof ImplementsOpActionItem) {
|
||||
ImplementsOpActionItem iot = (ImplementsOpActionItem) parts.get(1);
|
||||
implementsOp = iot.superclasses;
|
||||
} else {
|
||||
//ok = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
List<GraphTargetItem> output2 = new ArrayList<>();
|
||||
for (int i = 0; i < prevCount; i++) {
|
||||
output2.add(output.get(i));
|
||||
}
|
||||
output2.add(new InterfaceActionItem(sm.objectName, implementsOp));
|
||||
return output2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//ok = false;
|
||||
}
|
||||
} else {
|
||||
ok = false;
|
||||
}
|
||||
} else {
|
||||
ok = false;
|
||||
}
|
||||
} else if (!(t instanceof PopItem)) {
|
||||
prevCount++;
|
||||
//ok = false;
|
||||
}
|
||||
if (!ok) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean ignoredLoops() {
|
||||
return false;
|
||||
|
||||
+291
@@ -0,0 +1,291 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2018 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.SWF;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionJump;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionPop;
|
||||
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.swf5.ActionReturn;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionStoreRegister;
|
||||
import com.jpexs.decompiler.flash.ecma.Undefined;
|
||||
import com.jpexs.decompiler.flash.helpers.SWFDecompilerAdapter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
/**
|
||||
* Cleaner for ActionDefineFunction push registers. From Flash 7 onwards,
|
||||
* functions are stored as ActionDefineFunction2 with use up to 255 local
|
||||
* registers. When exporting SWF to lower formats Flash5-Flash6 in Flash IDE
|
||||
* (for example MX 2004), all ActionDefineFunction2 are replaced with
|
||||
* ActionDefineFunction, and it also use local registers (4 of them are
|
||||
* available). The code of ActionDefineFunction is also modified that it pushes
|
||||
* all previous values of registers on the code start and pops them back on code
|
||||
* exit or when return action shows up. All returns are replaced with jump to
|
||||
* popping part. This makes code flow tangled and the decompiler cannot properly
|
||||
* handle it. The cleaner will fix this mess.
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class ActionDefineFunctionPushRegistersCleaner extends SWFDecompilerAdapter {
|
||||
|
||||
@Override
|
||||
public void actionListParsed(ActionList actions, SWF swf) throws InterruptedException {
|
||||
cleanActionDefineFunctions(actions);
|
||||
}
|
||||
|
||||
private void cleanActionDefineFunctions(ActionList actions) {
|
||||
for (int i = actions.size() - 1; i >= 0; i--) {
|
||||
Action action = actions.get(i);
|
||||
if (action instanceof ActionDefineFunction) {
|
||||
ActionDefineFunction def = (ActionDefineFunction) action;
|
||||
|
||||
List<Long> sizes = def.getContainerSizes();
|
||||
long endAddress = action.getAddress() + def.getHeaderSize() + sizes.get(0);
|
||||
int lastIndex = actions.getIndexByAddress(endAddress);
|
||||
int startIndex = i + 1;
|
||||
int count = lastIndex - startIndex;
|
||||
cleanPushRegisters(actions, startIndex, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param code
|
||||
* @param startIndex Index of first Action in DefineFunction body
|
||||
* @param count Count of actions in DefineFunction
|
||||
* @return
|
||||
*/
|
||||
private boolean cleanPushRegisters(ActionList code, int startIndex, int count) {
|
||||
if (count == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
ON BEGINNING:
|
||||
Push register1 register2 normalval
|
||||
*/
|
||||
List<Integer> pushedRegisters = new ArrayList<>();
|
||||
int pos = startIndex;
|
||||
loopregs:
|
||||
while (code.get(pos) instanceof ActionPush) {
|
||||
ActionPush ap = (ActionPush) code.get(pos);
|
||||
for (int i = 0; i < ap.values.size(); i++) {
|
||||
if (ap.values.get(i) instanceof RegisterNumber) {
|
||||
RegisterNumber rn = (RegisterNumber) ap.values.get(i);
|
||||
pushedRegisters.add(rn.number);
|
||||
} else {
|
||||
break loopregs;
|
||||
}
|
||||
}
|
||||
pos++;
|
||||
if (pos >= code.size()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (pushedRegisters.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
ON FINISH:
|
||||
|
||||
when function returns something:
|
||||
StoreRegister 0 ;return value
|
||||
Pop
|
||||
StoreRegister 2
|
||||
Pop
|
||||
StoreRegister 1
|
||||
Pop
|
||||
Push register0
|
||||
Return
|
||||
|
||||
when function does not return anything:
|
||||
StoreRegister 2
|
||||
Pop
|
||||
StoreRegister 1
|
||||
Pop
|
||||
|
||||
when original function has some returns, but no return at the end of function:
|
||||
Push undefined
|
||||
locjump: StoreRegister 0
|
||||
Pop
|
||||
...
|
||||
|
||||
*/
|
||||
int returnReg = -1;
|
||||
pos = startIndex + count - 1;
|
||||
if (code.get(pos) instanceof ActionReturn) {
|
||||
pos--;
|
||||
if (pos < startIndex) {
|
||||
return false;
|
||||
}
|
||||
if (!(code.get(pos) instanceof ActionPush)) {
|
||||
return false;
|
||||
}
|
||||
ActionPush pu = (ActionPush) code.get(pos);
|
||||
if (pu.values.size() != 1) {
|
||||
return false;
|
||||
}
|
||||
if (!(pu.values.get(0) instanceof RegisterNumber)) {
|
||||
return false;
|
||||
}
|
||||
RegisterNumber rn = (RegisterNumber) pu.values.get(0);
|
||||
returnReg = rn.number;
|
||||
pos--;
|
||||
if (pos < startIndex) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
for (int i = 0; i < pushedRegisters.size(); i++) {
|
||||
if (!(code.get(pos) instanceof ActionPop)) {
|
||||
return false;
|
||||
}
|
||||
pos--;
|
||||
if (pos < startIndex) {
|
||||
return false;
|
||||
}
|
||||
if (!(code.get(pos) instanceof ActionStoreRegister)) {
|
||||
return false;
|
||||
}
|
||||
ActionStoreRegister asr = (ActionStoreRegister) code.get(pos);
|
||||
int expectedReg = pushedRegisters.get(i);
|
||||
if (asr.registerNumber != expectedReg) {
|
||||
return false;
|
||||
}
|
||||
pos--;
|
||||
if (pos < startIndex) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Set<Integer> jumpsToReturnPositions = new TreeSet<>(new Comparator<Integer>() {
|
||||
@Override
|
||||
public int compare(Integer o1, Integer o2) {
|
||||
return o2 - o1; //biggest first
|
||||
}
|
||||
});
|
||||
|
||||
int posBeforeFinishPart;
|
||||
Action actionBeforeFinishPart = null;
|
||||
if (returnReg > -1) {
|
||||
if (!(code.get(pos) instanceof ActionPop)) {
|
||||
return false;
|
||||
}
|
||||
pos--;
|
||||
if (pos < startIndex) {
|
||||
return false;
|
||||
}
|
||||
if (!(code.get(pos) instanceof ActionStoreRegister)) {
|
||||
return false;
|
||||
}
|
||||
ActionStoreRegister asr = (ActionStoreRegister) code.get(pos);
|
||||
int expectedReg = returnReg;
|
||||
if (asr.registerNumber != expectedReg) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Iterator<Action> ait = code.getReferencesFor(asr);
|
||||
while (ait.hasNext()) {
|
||||
Action a = ait.next();
|
||||
if (!(a instanceof ActionJump)) {
|
||||
return false;
|
||||
}
|
||||
jumpsToReturnPositions.add(code.indexOf(a));
|
||||
}
|
||||
pos--;
|
||||
if (!(code.get(pos) instanceof ActionJump)) {
|
||||
actionBeforeFinishPart = code.get(pos);
|
||||
}
|
||||
posBeforeFinishPart = pos;
|
||||
} else {
|
||||
posBeforeFinishPart = pos;
|
||||
}
|
||||
|
||||
//process code...
|
||||
//replace jumps to return with returns
|
||||
for (Integer jp : jumpsToReturnPositions) {
|
||||
int index = jp;
|
||||
code.removeAction(index);
|
||||
code.addAction(index, new ActionReturn());
|
||||
}
|
||||
|
||||
//previous action (not jump) also leads to finishpart, we might add return there aswell
|
||||
if (returnReg > -1 && actionBeforeFinishPart != null) {
|
||||
if ((actionBeforeFinishPart instanceof ActionPush) && ((ActionPush) actionBeforeFinishPart).values.size() == 1 && ((ActionPush) actionBeforeFinishPart).values.get(0) == Undefined.INSTANCE) {
|
||||
//its return undefined, which is same as no return
|
||||
code.removeAction(posBeforeFinishPart);
|
||||
posBeforeFinishPart--;
|
||||
count--;
|
||||
} else if (actionBeforeFinishPart instanceof ActionReturn) {
|
||||
//it was a jump that was replaced with Return
|
||||
} else if (actionBeforeFinishPart instanceof ActionJump) {
|
||||
//its jump to another location, we will not add return there
|
||||
} else { //might be another returned value
|
||||
posBeforeFinishPart++;
|
||||
code.addAction(posBeforeFinishPart, new ActionReturn());
|
||||
count++; //action added, but not removed, we increase total count
|
||||
}
|
||||
}
|
||||
|
||||
//remove finishPart
|
||||
int removeStartIndex = posBeforeFinishPart + 1;
|
||||
int removeCount = startIndex + count - removeStartIndex;
|
||||
code.removeAction(removeStartIndex, removeCount);
|
||||
|
||||
//remove pushes from beginning part
|
||||
pos = startIndex;
|
||||
int registersLeft = pushedRegisters.size();
|
||||
loopregs2:
|
||||
while (code.get(pos) instanceof ActionPush) {
|
||||
ActionPush currentPush = (ActionPush) code.get(pos);
|
||||
|
||||
List<Object> currentPushedValues = currentPush.values;
|
||||
List<Object> newPushedValues = new ArrayList<>();
|
||||
for (int i = 0; i < currentPushedValues.size(); i++) {
|
||||
if (registersLeft > 0 && currentPushedValues.get(i) instanceof RegisterNumber) {
|
||||
registersLeft--;
|
||||
} else {
|
||||
newPushedValues.add(currentPushedValues.get(i));
|
||||
}
|
||||
}
|
||||
if (newPushedValues.size() != currentPushedValues.size()) {
|
||||
code.removeAction(pos); //remove that push
|
||||
if (!newPushedValues.isEmpty()) {
|
||||
ActionPush newPush = new ActionPush(newPushedValues.toArray());
|
||||
newPush.constantPool = currentPush.constantPool;
|
||||
code.addAction(pos, newPush); //replace with different push
|
||||
} else {
|
||||
pos--; //action removed, but not added
|
||||
}
|
||||
}
|
||||
if (registersLeft == 0) { //we removed all unwanted registers
|
||||
break;
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,8 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
*/
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action;
|
||||
|
||||
import com.jpexs.decompiler.flash.BaseLocalData;
|
||||
@@ -48,6 +49,7 @@ 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.DefaultItem;
|
||||
import com.jpexs.decompiler.graph.model.IfItem;
|
||||
import com.jpexs.decompiler.graph.model.SwitchItem;
|
||||
import com.jpexs.decompiler.graph.model.WhileItem;
|
||||
import java.util.ArrayList;
|
||||
@@ -62,26 +64,31 @@ import java.util.Set;
|
||||
*/
|
||||
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<>());
|
||||
//this.version = version;
|
||||
/*heads = makeGraph(code, new ArrayList<GraphPart>());
|
||||
for (GraphPart head : heads) {
|
||||
fixGraph(head);
|
||||
makeMulti(head, new ArrayList<GraphPart>());
|
||||
}*/
|
||||
private boolean insideDoInitAction;
|
||||
|
||||
public ActionGraph(String path, boolean insideDoInitAction, List<Action> code, HashMap<Integer, String> registerNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int version) {
|
||||
super(new ActionGraphSource(path, insideDoInitAction, code, version, registerNames, variables, functions), new ArrayList<>());
|
||||
this.insideDoInitAction = insideDoInitAction;
|
||||
}
|
||||
|
||||
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 {
|
||||
public boolean isInsideDoInitAction() {
|
||||
return insideDoInitAction;
|
||||
}
|
||||
|
||||
ActionGraph g = new ActionGraph(code, registerNames, variables, functions, version);
|
||||
ActionLocalData localData = new ActionLocalData(registerNames);
|
||||
@Override
|
||||
protected void afterPopupateAllParts(Set<GraphPart> allParts) {
|
||||
|
||||
}
|
||||
|
||||
public static List<GraphTargetItem> translateViaGraph(boolean insideDoInitAction, 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(path, insideDoInitAction, code, registerNames, variables, functions, version);
|
||||
ActionLocalData localData = new ActionLocalData(insideDoInitAction, registerNames);
|
||||
g.init(localData);
|
||||
return g.translate(localData, staticOperation, path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finalProcessStack(TranslateStack stack, List<GraphTargetItem> output) {
|
||||
public void finalProcessStack(TranslateStack stack, List<GraphTargetItem> output, String path) {
|
||||
if (stack.size() > 0) {
|
||||
for (int i = stack.size() - 1; i >= 0; i--) {
|
||||
//System.err.println(stack.get(i));
|
||||
@@ -96,11 +103,11 @@ public class ActionGraph extends Graph {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalProcess(List<GraphTargetItem> list, int level, FinalProcessLocalData localData) throws InterruptedException {
|
||||
List<GraphTargetItem> ret = Action.checkClass(list);
|
||||
if (ret != list) {
|
||||
list.clear();
|
||||
list.addAll(ret);
|
||||
protected void finalProcess(List<GraphTargetItem> list, int level, FinalProcessLocalData localData, String path) throws InterruptedException {
|
||||
|
||||
if (insideDoInitAction) {
|
||||
ActionScript2ClassDetector detector = new ActionScript2ClassDetector();
|
||||
detector.checkClass(list, path);
|
||||
}
|
||||
int targetStart;
|
||||
int targetEnd;
|
||||
@@ -161,34 +168,51 @@ public class ActionGraph extends Graph {
|
||||
} while (again);
|
||||
for (int t = 1/*not first*/; t < list.size(); t++) {
|
||||
GraphTargetItem it = list.get(t);
|
||||
List<GraphTargetItem> checkedBody = null;
|
||||
GraphTargetItem checkedCondition = null;
|
||||
Loop checkedLoop = null;
|
||||
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 == Null.INSTANCE) {
|
||||
GraphTargetItem en = list.get(t - 1);
|
||||
if (en instanceof EnumerateActionItem) {
|
||||
EnumerateActionItem eti = (EnumerateActionItem) en;
|
||||
list.remove(t);
|
||||
wi.commands.remove(0);
|
||||
list.add(t, new ForInActionItem(null, null, wi.loop, sti.getObject(), eti.object, wi.commands));
|
||||
list.remove(t - 1);
|
||||
t--;
|
||||
checkedBody = wi.commands;
|
||||
checkedCondition = wi.expression.get(wi.expression.size() - 1);
|
||||
checkedLoop = wi.loop;
|
||||
} else if (it instanceof IfItem) {
|
||||
IfItem ifi = (IfItem) it;
|
||||
if (ifi.onFalse.isEmpty()) {
|
||||
checkedBody = ifi.onTrue;
|
||||
checkedCondition = ifi.expression;
|
||||
checkedLoop = null;
|
||||
}
|
||||
}
|
||||
if (checkedBody != null && (!checkedBody.isEmpty()) && (checkedBody.get(0) instanceof SetTypeActionItem)) {
|
||||
SetTypeActionItem sti = (SetTypeActionItem) checkedBody.get(0);
|
||||
if (checkedCondition instanceof NeqActionItem) {
|
||||
NeqActionItem ne = (NeqActionItem) checkedCondition;
|
||||
if (ne.rightSide instanceof DirectValueActionItem) {
|
||||
DirectValueActionItem dv = (DirectValueActionItem) ne.rightSide;
|
||||
if (dv.value == Null.INSTANCE) {
|
||||
GraphTargetItem en = list.get(t - 1);
|
||||
if (en instanceof EnumerateActionItem) {
|
||||
EnumerateActionItem eti = (EnumerateActionItem) en;
|
||||
list.remove(t);
|
||||
checkedBody.remove(0);
|
||||
if (checkedLoop == null) {
|
||||
checkedLoop = new Loop(localData.loops.size(), null, null);
|
||||
checkedBody.add(new BreakItem(null, null, checkedLoop.id));
|
||||
}
|
||||
list.add(t, new ForInActionItem(null, null, checkedLoop, sti.getObject(), eti.object, checkedBody));
|
||||
list.remove(t - 1);
|
||||
t--;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
//Handle for loops at the end:
|
||||
super.finalProcess(list, level, localData);
|
||||
super.finalProcess(list, level, localData, path);
|
||||
|
||||
}
|
||||
|
||||
@@ -300,59 +324,102 @@ public class ActionGraph extends Graph {
|
||||
stack.push(set);
|
||||
} else {
|
||||
part = part.nextParts.get(1);
|
||||
//caseBodyParts.add(part);
|
||||
GraphPart defaultPart = part;
|
||||
if (code.size() > defaultPart.start && code.get(defaultPart.start) instanceof ActionJump) {
|
||||
defaultPart = defaultPart.nextParts.get(0);
|
||||
}
|
||||
|
||||
GraphPart breakPart = getMostCommonPart(localData, caseBodyParts, loops);
|
||||
|
||||
List<GraphTargetItem> caseValues = new ArrayList<>();
|
||||
boolean hasDefault = false;
|
||||
for (int i = 0; i < caseBodyParts.size(); i++) {
|
||||
caseValues.add(caseValuesMap.get(i));
|
||||
/*
|
||||
case 4:
|
||||
case 5:
|
||||
default:
|
||||
trace("5 & def");
|
||||
...
|
||||
case 6:
|
||||
|
||||
*/
|
||||
//must go backwards to hit case 5, not case 4
|
||||
for (int i = caseBodyParts.size() - 1; i >= 0; i--) {
|
||||
if (caseBodyParts.get(i) == defaultPart) {
|
||||
i++;
|
||||
caseValuesMap.add(i, new DefaultItem());
|
||||
caseBodyParts.add(i, defaultPart);
|
||||
caseValues.add(caseValuesMap.get(i));
|
||||
DefaultItem di = new DefaultItem();
|
||||
caseValuesMap.add(i + 1, di);
|
||||
caseBodyParts.add(i + 1, defaultPart);
|
||||
hasDefault = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasDefault) {
|
||||
//List<GraphPart> stops = new ArrayList<>();
|
||||
//stops.addAll(caseBodyParts);
|
||||
for (int i = 0; i < caseBodyParts.size(); i++) {
|
||||
if (defaultPart.leadsTo(localData, this, code, caseBodyParts.get(i), loops)) {
|
||||
caseValuesMap.add(i, new DefaultItem());
|
||||
caseBodyParts.add(i, defaultPart);
|
||||
caseValues.add(i, caseValuesMap.get(i));
|
||||
/*
|
||||
case 1:
|
||||
trace("1");
|
||||
case 2:
|
||||
trace("2"); //no break
|
||||
default:
|
||||
trace("def");
|
||||
...
|
||||
case 3:
|
||||
*/
|
||||
//must go backwards to hit case 2, not case 1
|
||||
for (int i = caseBodyParts.size() - 1; i >= 0; i--) {
|
||||
if (caseBodyParts.get(i).leadsTo(localData, this, code, defaultPart, loops)) {
|
||||
DefaultItem di = new DefaultItem();
|
||||
caseValuesMap.add(i + 1, di);
|
||||
caseBodyParts.add(i + 1, defaultPart);
|
||||
hasDefault = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasDefault) {
|
||||
caseValuesMap.add(new DefaultItem());
|
||||
caseBodyParts.add(defaultPart);
|
||||
caseValues.add(caseValuesMap.get(caseValuesMap.size() - 1));
|
||||
/*
|
||||
case 1:
|
||||
trace("1");
|
||||
break;
|
||||
default:
|
||||
trace("def"); //no break
|
||||
case 2:
|
||||
trace("2");
|
||||
*/
|
||||
for (int i = 0; i < caseBodyParts.size(); i++) {
|
||||
if (defaultPart.leadsTo(localData, this, code, caseBodyParts.get(i), loops)) {
|
||||
DefaultItem di = new DefaultItem();
|
||||
caseValuesMap.add(i, di);
|
||||
caseBodyParts.add(i, defaultPart);
|
||||
hasDefault = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<List<GraphTargetItem>> caseCommands = new ArrayList<>();
|
||||
GraphPart next;
|
||||
if (!hasDefault) {
|
||||
/*
|
||||
case 1:
|
||||
...
|
||||
case 2:
|
||||
...
|
||||
default:
|
||||
trace("def");
|
||||
*/
|
||||
caseValuesMap.add(new DefaultItem());
|
||||
caseBodyParts.add(defaultPart);
|
||||
}
|
||||
|
||||
next = breakPart;
|
||||
GraphPart breakPart = getMostCommonPart(localData, caseBodyParts, loops);
|
||||
List<List<GraphTargetItem>> caseCommands = new ArrayList<>();
|
||||
GraphPart next = breakPart;
|
||||
|
||||
GraphTargetItem ti = checkLoop(next, stopPart, loops);
|
||||
|
||||
//create switch as new loop break command detection to work
|
||||
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++) {
|
||||
for (int i = 0; i < caseValuesMap.size(); i++) {
|
||||
GraphPart cur = caseBodyParts.get(i);
|
||||
if (!caseBodies.contains(cur)) {
|
||||
caseBodies.add(cur);
|
||||
@@ -360,45 +427,36 @@ public class ActionGraph extends Graph {
|
||||
valuesMapping.add(caseBodies.indexOf(cur));
|
||||
}
|
||||
|
||||
/*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;
|
||||
List<GraphTargetItem> currentCaseCommands = new ArrayList<>();
|
||||
GraphPart 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, localData.lineStartInstruction, currentLoop.id));
|
||||
currentCaseCommands.add(new BreakItem(null, localData.lineStartInstruction, currentLoop.id));
|
||||
} else {
|
||||
nextCase = caseBodies.get(i + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
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(partCodes, partCodePos, 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);
|
||||
currentCaseCommands.addAll(0, printGraph(partCodes, partCodePos, localData, stack, allParts, null, caseBodies.get(i), stopPart2x, loops, staticOperation, path));
|
||||
if (currentCaseCommands.size() >= 2) {
|
||||
if (currentCaseCommands.get(currentCaseCommands.size() - 1) instanceof BreakItem) {
|
||||
if ((currentCaseCommands.get(currentCaseCommands.size() - 2) instanceof ContinueItem) || (currentCaseCommands.get(currentCaseCommands.size() - 2) instanceof BreakItem)) {
|
||||
currentCaseCommands.remove(currentCaseCommands.size() - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
caseCommands.add(cc);
|
||||
caseCommands.add(currentCaseCommands);
|
||||
}
|
||||
|
||||
//If the lastone is default empty and alone, remove it
|
||||
@@ -410,15 +468,16 @@ public class ActionGraph extends Graph {
|
||||
}
|
||||
if (lastc.isEmpty()) {
|
||||
int cnt2 = 0;
|
||||
if (caseValues.get(caseValues.size() - 1) instanceof DefaultItem) {
|
||||
if (caseValuesMap.get(caseValuesMap.size() - 1) instanceof DefaultItem) {
|
||||
for (int i = valuesMapping.size() - 1; i >= 0; i--) {
|
||||
if (valuesMapping.get(i) == caseCommands.size() - 1) {
|
||||
cnt2++;
|
||||
}
|
||||
}
|
||||
|
||||
caseValuesMap.remove(caseValuesMap.size() - 1);
|
||||
valuesMapping.remove(valuesMapping.size() - 1);
|
||||
if (cnt2 == 1) {
|
||||
caseValues.remove(caseValues.size() - 1);
|
||||
valuesMapping.remove(valuesMapping.size() - 1);
|
||||
caseCommands.remove(lastc);
|
||||
}
|
||||
}
|
||||
@@ -430,13 +489,12 @@ public class ActionGraph extends Graph {
|
||||
if (!lastc.isEmpty() && (lastc.get(lastc.size() - 1) instanceof BreakItem)) {
|
||||
BreakItem bi = (BreakItem) lastc.get(lastc.size() - 1);
|
||||
lastc.remove(lastc.size() - 1);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
ret = new ArrayList<>();
|
||||
ret.addAll(output);
|
||||
SwitchItem sti = new SwitchItem(null, switchStartItem, currentLoop, switchedObject, caseValues, caseCommands, valuesMapping);
|
||||
SwitchItem sti = new SwitchItem(null, switchStartItem, currentLoop, switchedObject, caseValuesMap, caseCommands, valuesMapping);
|
||||
ret.add(sti);
|
||||
currentLoop.phase = 2;
|
||||
if (next != null) {
|
||||
@@ -454,15 +512,15 @@ public class ActionGraph extends Graph {
|
||||
@Override
|
||||
protected int checkIp(int ip) {
|
||||
int oldIp = ip;
|
||||
//return in for..in
|
||||
//return/break in for..in
|
||||
GraphSourceItem action = code.get(ip);
|
||||
if ((action instanceof ActionPush) && (((ActionPush) action).values.size() == 1) && (((ActionPush) action).values.get(0) == Null.INSTANCE)) {
|
||||
if (ip + 4 < code.size()) {
|
||||
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) {
|
||||
if (code.adr2pos(code.pos2adr(ip + 3) + 5 /*IF numbytes*/ + aif.getJumpOffset()) == ip) {
|
||||
ip += 4;
|
||||
}
|
||||
}
|
||||
@@ -471,6 +529,9 @@ public class ActionGraph extends Graph {
|
||||
}
|
||||
}
|
||||
if (oldIp != ip) {
|
||||
if (ip == code.size()) { //no next checkIp call since its after code size
|
||||
return ip;
|
||||
}
|
||||
return checkIp(ip);
|
||||
}
|
||||
return ip;
|
||||
|
||||
@@ -12,11 +12,12 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
*/
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action;
|
||||
|
||||
import com.jpexs.decompiler.flash.BaseLocalData;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.parser.script.Reference;
|
||||
import com.jpexs.helpers.Reference;
|
||||
import com.jpexs.decompiler.graph.GraphPart;
|
||||
import com.jpexs.decompiler.graph.GraphSource;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
@@ -45,16 +46,22 @@ public class ActionGraphSource extends GraphSource {
|
||||
|
||||
private final HashMap<String, GraphTargetItem> functions;
|
||||
|
||||
private final boolean insideDoInitAction;
|
||||
|
||||
private final String path;
|
||||
|
||||
public List<Action> getActions() {
|
||||
return actions;
|
||||
}
|
||||
|
||||
public ActionGraphSource(List<Action> actions, int version, HashMap<Integer, String> registerNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions) {
|
||||
public ActionGraphSource(String path, boolean insideDoInitAction, List<Action> actions, int version, HashMap<Integer, String> registerNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions) {
|
||||
this.actions = actions;
|
||||
this.version = version;
|
||||
this.registerNames = registerNames;
|
||||
this.variables = variables;
|
||||
this.functions = functions;
|
||||
this.insideDoInitAction = insideDoInitAction;
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -80,7 +87,7 @@ public class ActionGraphSource extends GraphSource {
|
||||
public List<GraphTargetItem> translatePart(GraphPart part, BaseLocalData localData, TranslateStack stack, int start, int end, int staticOperation, String path) throws InterruptedException {
|
||||
Reference<GraphSourceItem> fi = new Reference<>(localData.lineStartInstruction);
|
||||
|
||||
List<GraphTargetItem> r = Action.actionsPartToTree(fi, registerNames, variables, functions, stack, actions, start, end, version, staticOperation, path);
|
||||
List<GraphTargetItem> r = Action.actionsPartToTree(this.insideDoInitAction, fi, registerNames, variables, functions, stack, actions, start, end, version, staticOperation, path);
|
||||
localData.lineStartInstruction = fi.getVal();
|
||||
return r;
|
||||
}
|
||||
@@ -135,7 +142,7 @@ public class ActionGraphSource extends GraphSource {
|
||||
}
|
||||
//ret = adr2posInside(adr);
|
||||
if (ret == -1) {
|
||||
Logger.getLogger(ActionGraphSource.class.getName()).log(Level.SEVERE, "Address loc" + Helper.formatAddress(adr) + " not found");
|
||||
Logger.getLogger(ActionGraphSource.class.getName()).log(Level.SEVERE, "{0} - address loc{1} not found", new Object[]{path, Helper.formatAddress(adr)});
|
||||
/*System.err.println("Addr loc"+Helper.formatAddress(adr)+" not found");
|
||||
int pos=0;
|
||||
for(long l:posCache){
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
*/
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action;
|
||||
|
||||
import com.jpexs.decompiler.flash.DisassemblyListener;
|
||||
@@ -31,7 +32,11 @@ import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.helpers.SWFDecompilerPlugin;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItemContainer;
|
||||
import com.jpexs.helpers.CancellableWorker;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import com.jpexs.helpers.stat.Statistics;
|
||||
import com.jpexs.helpers.utf8.Utf8Helper;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
@@ -163,6 +168,15 @@ public class ActionListReader {
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: This cleaner needs to be executed only before actual decompilation, not when disassembly only
|
||||
try {
|
||||
new ActionDefineFunctionPushRegistersCleaner().actionListParsed(actions, sis.getSwf());
|
||||
} catch (ThreadDeath | InterruptedException ex) {
|
||||
throw ex;
|
||||
} catch (Throwable ex) {
|
||||
logger.log(Level.SEVERE, "Cleaning push registers in ActionDefineFunction failed: " + path, ex);
|
||||
}
|
||||
|
||||
return actions;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
*/
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action;
|
||||
|
||||
import com.jpexs.decompiler.flash.BaseLocalData;
|
||||
@@ -34,21 +35,26 @@ public class ActionLocalData extends BaseLocalData {
|
||||
|
||||
public GraphSourceItem lineStartAction;
|
||||
|
||||
public ActionLocalData() {
|
||||
public boolean insideDoInitAction;
|
||||
|
||||
public ActionLocalData(boolean insideDoInitAction) {
|
||||
regNames = new HashMap<>();
|
||||
variables = new HashMap<>();
|
||||
functions = new HashMap<>();
|
||||
this.insideDoInitAction = insideDoInitAction;
|
||||
}
|
||||
|
||||
public ActionLocalData(HashMap<Integer, String> regNames) {
|
||||
public ActionLocalData(boolean insideDoInitAction, HashMap<Integer, String> regNames) {
|
||||
this.regNames = regNames;
|
||||
variables = new HashMap<>();
|
||||
functions = new HashMap<>();
|
||||
this.insideDoInitAction = insideDoInitAction;
|
||||
}
|
||||
|
||||
public ActionLocalData(HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions) {
|
||||
public ActionLocalData(boolean insideDoInitAction, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions) {
|
||||
this.regNames = regNames;
|
||||
this.variables = variables;
|
||||
this.functions = functions;
|
||||
this.insideDoInitAction = insideDoInitAction;
|
||||
}
|
||||
}
|
||||
|
||||
+738
@@ -0,0 +1,738 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2018 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.action.model.CallFunctionActionItem;
|
||||
import com.jpexs.helpers.Reference;
|
||||
import com.jpexs.decompiler.flash.action.model.CallMethodActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.DirectValueActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.ExtendsActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.FunctionActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.GetMemberActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.GetVariableActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.ImplementsOpActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.NewMethodActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.NewObjectActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.SetMemberActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.SetVariableActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.StoreRegisterActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.TemporaryRegister;
|
||||
import com.jpexs.decompiler.flash.action.model.clauses.ClassActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.clauses.InterfaceActionItem;
|
||||
import com.jpexs.decompiler.flash.action.swf4.RegisterNumber;
|
||||
import com.jpexs.decompiler.flash.ecma.Null;
|
||||
import com.jpexs.decompiler.flash.helpers.collections.MyEntry;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.model.IfItem;
|
||||
import com.jpexs.decompiler.graph.model.NotItem;
|
||||
import com.jpexs.decompiler.graph.model.PopItem;
|
||||
import com.jpexs.decompiler.graph.model.PushItem;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class ActionScript2ClassDetector {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(ActionScript2ClassDetector.class.getName());
|
||||
|
||||
private class AssertException extends Exception {
|
||||
|
||||
private final String condition;
|
||||
|
||||
public AssertException(String condition) {
|
||||
super(condition);
|
||||
this.condition = condition;
|
||||
}
|
||||
|
||||
public String getCondition() {
|
||||
return condition;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether an item is direct submember of path. a.b.c.d is submember
|
||||
* of a.b.c, x.y.z is not submember of x,
|
||||
*
|
||||
* @param item
|
||||
* @param objectPath
|
||||
* @param newPathItem New submember name
|
||||
* @return
|
||||
*/
|
||||
private boolean isMemberOfPath(GraphTargetItem item, List<String> objectPath, Reference<String> newPathItem) {
|
||||
List<String> path = getMembersPath(item);
|
||||
if (path == null) {
|
||||
return false;
|
||||
}
|
||||
if (path.size() != objectPath.size() + 1) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < objectPath.size(); i++) {
|
||||
if (!path.get(i).equals(objectPath.get(i))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
newPathItem.setVal(path.get(path.size() - 1));
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets path of variable and its getMembers: a.b.c.d => [a,b,c,d]
|
||||
*
|
||||
* @param item
|
||||
* @return List of path or null if not members path
|
||||
*/
|
||||
private List<String> getMembersPath(GraphTargetItem item) {
|
||||
List<String> ret = new ArrayList<>();
|
||||
while (item instanceof GetMemberActionItem) {
|
||||
GetMemberActionItem mem = (GetMemberActionItem) item;
|
||||
if (!(mem.memberName instanceof DirectValueActionItem)) {
|
||||
return null;
|
||||
}
|
||||
DirectValueActionItem dv = ((DirectValueActionItem) mem.memberName);
|
||||
if (!dv.isString()) {
|
||||
return null;
|
||||
}
|
||||
ret.add(0, dv.getAsString());
|
||||
item = mem.object;
|
||||
}
|
||||
if (!(item instanceof GetVariableActionItem)) {
|
||||
return null;
|
||||
}
|
||||
GetVariableActionItem gv = (GetVariableActionItem) item;
|
||||
if (!(gv.name instanceof DirectValueActionItem)) {
|
||||
return null;
|
||||
}
|
||||
DirectValueActionItem dv = ((DirectValueActionItem) gv.name);
|
||||
if (!dv.isString()) {
|
||||
return null;
|
||||
}
|
||||
String varName = dv.getAsString();
|
||||
ret.add(0, varName);
|
||||
return ret;
|
||||
}
|
||||
|
||||
private GraphTargetItem setMemberToGetMember(GraphTargetItem item) {
|
||||
if (item instanceof SetMemberActionItem) {
|
||||
return new GetMemberActionItem(null, null, ((SetMemberActionItem) item).object, ((SetMemberActionItem) item).objectName);
|
||||
} else if (item instanceof SetVariableActionItem) {
|
||||
return new GetVariableActionItem(null, null, ((SetVariableActionItem) item).name);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private GraphTargetItem newToGetMember(GraphTargetItem nobj) throws AssertException {
|
||||
if (nobj instanceof NewMethodActionItem) {
|
||||
NewMethodActionItem nm = (NewMethodActionItem) nobj;
|
||||
return new GetMemberActionItem(nobj.getSrc(), nobj.getLineStartItem(), nm.scriptObject, nm.methodName);
|
||||
} else if (nobj instanceof NewObjectActionItem) {
|
||||
NewObjectActionItem no = (NewObjectActionItem) nobj;
|
||||
return new GetVariableActionItem(nobj.getSrc(), nobj.getLineStartItem(), no.objectName);
|
||||
}
|
||||
throw new AssertException("NewMethod or NewObject expected");
|
||||
}
|
||||
|
||||
private List<String> getSetMembersPath(GraphTargetItem item) {
|
||||
if (item instanceof SetVariableActionItem) {
|
||||
SetVariableActionItem sv = (SetVariableActionItem) item;
|
||||
if (!(sv.name instanceof DirectValueActionItem)) {
|
||||
return null;
|
||||
}
|
||||
DirectValueActionItem nDv = (DirectValueActionItem) sv.name;
|
||||
if (!nDv.isString()) {
|
||||
return null;
|
||||
}
|
||||
List<String> ret = new ArrayList<>();
|
||||
ret.add(nDv.getAsString());
|
||||
return ret;
|
||||
} else if (item instanceof SetMemberActionItem) {
|
||||
SetMemberActionItem sm = (SetMemberActionItem) item;
|
||||
if (!(sm.objectName instanceof DirectValueActionItem)) {
|
||||
return null;
|
||||
}
|
||||
DirectValueActionItem onDv = (DirectValueActionItem) sm.objectName;
|
||||
if (!onDv.isString()) {
|
||||
return null;
|
||||
}
|
||||
String currentMemberName = onDv.getAsString();
|
||||
List<String> path = getMembersPath(sm.object);
|
||||
if (path == null) {
|
||||
return null;
|
||||
}
|
||||
path.add(currentMemberName);
|
||||
return path;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get register id or -1 if not found
|
||||
*
|
||||
* @param item
|
||||
* @return
|
||||
*/
|
||||
private int getAsRegisterNum(GraphTargetItem item, String assertName) throws AssertException {
|
||||
if (item instanceof DirectValueActionItem) {
|
||||
DirectValueActionItem dv = (DirectValueActionItem) item;
|
||||
if (dv.value instanceof RegisterNumber) {
|
||||
RegisterNumber rn = (RegisterNumber) dv.value;
|
||||
return rn.number;
|
||||
}
|
||||
}
|
||||
if (item instanceof TemporaryRegister) {
|
||||
TemporaryRegister tr = (TemporaryRegister) item;
|
||||
return tr.getRegId();
|
||||
}
|
||||
throw new AssertException("not a register - " + assertName);
|
||||
}
|
||||
|
||||
/*private boolean isInstanceRegister(GraphTargetItem item, Reference<Integer> instanceReg, Reference<Integer> classReg,Reference<GraphTargetItem> extracted, String assertName) throws AssertException {
|
||||
if (item instanceof DirectValueActionItem) {
|
||||
DirectValueActionItem dv = (DirectValueActionItem) item;
|
||||
if (dv.value instanceof RegisterNumber) {
|
||||
RegisterNumber rn = (RegisterNumber) dv.value;
|
||||
if (rn.number == instanceReg.getVal()) {
|
||||
return true;
|
||||
} else if (rn.number == classReg.getVal()) {
|
||||
return false;
|
||||
}else{
|
||||
throw new AssertException(assertName + " - unknown register");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (item instanceof TemporaryRegister) {
|
||||
TemporaryRegister tr = (TemporaryRegister) item;
|
||||
if (!"prototype".equals(getAsString(gm.memberName, "memberName"))) {
|
||||
throw new AssertException("memberName not \"prototype\"");
|
||||
}
|
||||
return tr.getRegId();
|
||||
}
|
||||
}
|
||||
*/
|
||||
private static GraphTargetItem getWithoutGlobal(GraphTargetItem ti) {
|
||||
GraphTargetItem t = ti;
|
||||
if (!(t instanceof GetMemberActionItem)) {
|
||||
return ti;
|
||||
}
|
||||
GetMemberActionItem lastMember = null;
|
||||
while (((GetMemberActionItem) t).object instanceof GetMemberActionItem) {
|
||||
lastMember = (GetMemberActionItem) t;
|
||||
t = ((GetMemberActionItem) t).object;
|
||||
}
|
||||
if (((GetMemberActionItem) t).object instanceof GetVariableActionItem) {
|
||||
GetVariableActionItem v = (GetVariableActionItem) ((GetMemberActionItem) t).object;
|
||||
if (v.name instanceof DirectValueActionItem) {
|
||||
if (((DirectValueActionItem) v.name).value instanceof String) {
|
||||
if (((DirectValueActionItem) v.name).value.equals("_global")) {
|
||||
GetVariableActionItem gvt = new GetVariableActionItem(null, null, ((GetMemberActionItem) t).memberName);
|
||||
if (lastMember == null) {
|
||||
return gvt;
|
||||
} else {
|
||||
lastMember.object = gvt;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ti;
|
||||
}
|
||||
|
||||
private String getAsString(GraphTargetItem item, String itemName) throws AssertException {
|
||||
if (!(item instanceof DirectValueActionItem)) {
|
||||
throw new AssertException(itemName + " not DirectValue");
|
||||
}
|
||||
DirectValueActionItem mnDv = (DirectValueActionItem) item;
|
||||
if (!mnDv.isString()) {
|
||||
throw new AssertException(itemName + " not string");
|
||||
}
|
||||
return mnDv.getAsString();
|
||||
}
|
||||
|
||||
private boolean checkClassContent(List<GraphTargetItem> parts, int partsPos, int commandsStartPos, int commandsEndPos, List<GraphTargetItem> commands, List<String> classNamePath, String scriptPath) {
|
||||
|
||||
try {
|
||||
GraphTargetItem item = parts.get(partsPos);
|
||||
GraphTargetItem extendsOp = null;
|
||||
List<GraphTargetItem> implementsOp = new ArrayList<>();
|
||||
if (item instanceof ExtendsActionItem) {
|
||||
ExtendsActionItem et = (ExtendsActionItem) parts.get(partsPos);
|
||||
extendsOp = getWithoutGlobal(et.superclass);
|
||||
partsPos++;
|
||||
item = parts.get(partsPos);
|
||||
}
|
||||
int instanceReg = -1;
|
||||
int classReg = -1;
|
||||
GraphTargetItem classNameTargetPath = null;
|
||||
GraphTargetItem constructor = null;
|
||||
if (item instanceof StoreRegisterActionItem) {
|
||||
StoreRegisterActionItem sr = (StoreRegisterActionItem) item;
|
||||
instanceReg = sr.register.number;
|
||||
if (sr.value instanceof GetMemberActionItem) {
|
||||
GetMemberActionItem gm = (GetMemberActionItem) sr.value;
|
||||
if (gm.object instanceof TemporaryRegister) {
|
||||
TemporaryRegister treg = (TemporaryRegister) gm.object;
|
||||
classReg = treg.getRegId();
|
||||
if (!"prototype".equals(getAsString(gm.memberName, "memberName"))) {
|
||||
throw new AssertException("memberName not \"prototype\"");
|
||||
}
|
||||
if ((treg.value instanceof SetMemberActionItem) || (treg.value instanceof SetVariableActionItem)) {
|
||||
List<String> path = getSetMembersPath(treg.value);
|
||||
if (path == null || path.isEmpty()) {
|
||||
throw new AssertException("Cannot detect class - tempreg value is not a path");
|
||||
}
|
||||
//remove _global if it's there - happens for classes in global package
|
||||
if ("_global".equals(path.get(0))) {
|
||||
path.remove(0);
|
||||
}
|
||||
if (classNamePath.equals(path)) {
|
||||
//can start with _global for classes on top level
|
||||
classNameTargetPath = getWithoutGlobal(setMemberToGetMember(treg.value));
|
||||
|
||||
//treg.value.value is the value being set - treg.value is setmember ot setvariable
|
||||
if (!(treg.value.value instanceof StoreRegisterActionItem)) {
|
||||
throw new AssertException("Constructor expected to be in storeregister");
|
||||
}
|
||||
if (!(treg.value.value.value instanceof FunctionActionItem)) {
|
||||
throw new AssertException("Constructor expected as functionitem");
|
||||
}
|
||||
constructor = treg.value.value.value;
|
||||
} else {
|
||||
throw new AssertException("temporaryreg value does not match class path");
|
||||
}
|
||||
} else {
|
||||
throw new AssertException("temporaryreg value not setmember/setvariable");
|
||||
}
|
||||
} else {
|
||||
throw new AssertException("Getmember does not have TemporaryRegister as object");
|
||||
}
|
||||
} else {
|
||||
throw new AssertException("Not Getmember in StoreRegister");
|
||||
}
|
||||
partsPos++;
|
||||
}
|
||||
List<MyEntry<GraphTargetItem, GraphTargetItem>> traits = new ArrayList<>();
|
||||
List<Boolean> traitsStatic = new ArrayList<>();
|
||||
loopsetmembers:
|
||||
for (; partsPos < parts.size(); partsPos++) {
|
||||
item = parts.get(partsPos);
|
||||
if (item instanceof PushItem) { //push is optional
|
||||
PushItem pi = (PushItem) item;
|
||||
item = pi.value;
|
||||
}
|
||||
if (item instanceof SetMemberActionItem) {
|
||||
SetMemberActionItem sm = (SetMemberActionItem) item;
|
||||
GraphTargetItem regValue;
|
||||
int currentRegId = -1;
|
||||
if (sm.object instanceof TemporaryRegister) {
|
||||
TemporaryRegister tempReg = (TemporaryRegister) sm.object;
|
||||
currentRegId = tempReg.getRegId();
|
||||
regValue = tempReg.value;
|
||||
} else if ((sm.object instanceof DirectValueActionItem) && (((DirectValueActionItem) sm.object).value instanceof RegisterNumber)) {
|
||||
DirectValueActionItem dv = (DirectValueActionItem) sm.object;
|
||||
RegisterNumber rn = ((RegisterNumber) dv.value);
|
||||
currentRegId = rn.number;
|
||||
regValue = dv.computedRegValue;
|
||||
} else {
|
||||
//might be an interface
|
||||
List<String> path = getSetMembersPath(item);
|
||||
if (path == null || path.isEmpty()) {
|
||||
throw new AssertException("invalid setmember");
|
||||
}
|
||||
//remove _global if it's there - happens for classes in global package
|
||||
if ("_global".equals(path.get(0))) {
|
||||
path.remove(0);
|
||||
}
|
||||
if (!path.equals(classNamePath)) {
|
||||
throw new AssertException("wrong path in setmember");
|
||||
}
|
||||
GraphTargetItem interfaceClass = getWithoutGlobal(setMemberToGetMember(item));
|
||||
if (!(sm.value instanceof FunctionActionItem)) {
|
||||
throw new AssertException("not a function in setmember");
|
||||
}
|
||||
FunctionActionItem f = (FunctionActionItem) sm.value;
|
||||
if (!"".equals(f.functionName)) {
|
||||
throw new AssertException("not unnamed func in setmember");
|
||||
}
|
||||
if (!f.actions.isEmpty()) {
|
||||
throw new AssertException("not empty function in setmember");
|
||||
}
|
||||
if (!f.paramNames.isEmpty()) {
|
||||
throw new AssertException("not empty params for function in setmember");
|
||||
}
|
||||
partsPos++;
|
||||
for (; partsPos < parts.size(); partsPos++) {
|
||||
item = parts.get(partsPos);
|
||||
if (item instanceof ImplementsOpActionItem) {
|
||||
if (!implementsOp.isEmpty()) {
|
||||
throw new AssertException("multiple implementsAction");
|
||||
}
|
||||
ImplementsOpActionItem io = (ImplementsOpActionItem) item;
|
||||
implementsOp = io.superclasses;
|
||||
} else {
|
||||
throw new AssertException("unknown iface item: " + item.getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
|
||||
InterfaceActionItem ifsItem = new InterfaceActionItem(interfaceClass, implementsOp);
|
||||
for (int k = commandsStartPos; k <= commandsEndPos; k++) {
|
||||
commands.remove(commandsStartPos);
|
||||
}
|
||||
commands.add(commandsStartPos, ifsItem);
|
||||
|
||||
//remove §§pop after, if it's there
|
||||
if (commandsStartPos + 1 < commands.size()) {
|
||||
if (commands.get(commandsStartPos + 1) instanceof PopItem) {
|
||||
commands.remove(commandsStartPos + 1);
|
||||
}
|
||||
}
|
||||
|
||||
// goto next line and check next classes
|
||||
return true;
|
||||
}
|
||||
//it was register .. continue class detection
|
||||
if (currentRegId != instanceReg && currentRegId != classReg) {
|
||||
if (!(regValue instanceof SetMemberActionItem)) {
|
||||
throw new AssertException("temp register do not contain setmember");
|
||||
}
|
||||
SetMemberActionItem sm2 = (SetMemberActionItem) regValue;
|
||||
GraphTargetItem pathSource;
|
||||
boolean isPrototype;
|
||||
if ("prototype".equals(getAsString(sm2.objectName, "objectName"))) {
|
||||
pathSource = sm2.object;
|
||||
isPrototype = true;
|
||||
} else {
|
||||
pathSource = setMemberToGetMember(sm2);
|
||||
isPrototype = false;
|
||||
}
|
||||
List<String> memPath = getMembersPath(pathSource);
|
||||
if (memPath == null) {
|
||||
throw new AssertException("Invalid pathsource");
|
||||
}
|
||||
if (!classNamePath.equals(memPath)) {
|
||||
throw new AssertException("Invalid path of setmember:" + String.join(".", memPath));
|
||||
}
|
||||
classNameTargetPath = pathSource;
|
||||
if (!(sm2.value instanceof StoreRegisterActionItem)) {
|
||||
throw new AssertException("Not storeregister");
|
||||
}
|
||||
StoreRegisterActionItem sr = (StoreRegisterActionItem) sm2.value;
|
||||
if (sr.register.number != currentRegId) {
|
||||
throw new AssertException("Invalid storeregister");
|
||||
}
|
||||
if (isPrototype && ((sr.value instanceof NewMethodActionItem) || (sr.value instanceof NewObjectActionItem))) {
|
||||
extendsOp = newToGetMember(sr.value);
|
||||
instanceReg = currentRegId;
|
||||
} else if (!isPrototype && (sr.value instanceof FunctionActionItem)) { //constructor
|
||||
constructor = sr.value;
|
||||
classReg = currentRegId;
|
||||
} else {
|
||||
throw new AssertException("invalid storeregister value: " + sr.value.getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
|
||||
MyEntry<GraphTargetItem, GraphTargetItem> trait = new MyEntry<>(sm.objectName, sm.value);
|
||||
if (sm.value instanceof FunctionActionItem) {
|
||||
FunctionActionItem f = (FunctionActionItem) sm.value;
|
||||
f.calculatedFunctionName = sm.objectName;
|
||||
}
|
||||
traits.add(trait);
|
||||
if (currentRegId == instanceReg) {
|
||||
traitsStatic.add(false);
|
||||
} else if (currentRegId == classReg) {
|
||||
traitsStatic.add(true);
|
||||
}
|
||||
} else if (item instanceof ImplementsOpActionItem) {
|
||||
ImplementsOpActionItem iot = (ImplementsOpActionItem) item;
|
||||
implementsOp = iot.superclasses;
|
||||
} else if (item instanceof CallMethodActionItem) {
|
||||
CallMethodActionItem cm = (CallMethodActionItem) item;
|
||||
String pushMethodName = getAsString(cm.methodName, "push methodName");
|
||||
if ("addProperty".equals(pushMethodName)) {
|
||||
int rnumObject = getAsRegisterNum(cm.scriptObject, "addProperty not on register");
|
||||
if ((rnumObject != instanceReg) && (rnumObject != classReg)) {
|
||||
throw new AssertException("unexpected addProperty object register " + rnumObject);
|
||||
}
|
||||
|
||||
if (cm.arguments.size() != 3) {
|
||||
throw new AssertException("invalid number of arguments to addProperty: " + cm.arguments.size());
|
||||
}
|
||||
GraphTargetItem propertyName = cm.arguments.get(0);
|
||||
GraphTargetItem propertyGetter = cm.arguments.get(1);
|
||||
GraphTargetItem propertySetter = cm.arguments.get(2);
|
||||
String propertyNameStr = getAsString(propertyName, "propertyName");
|
||||
if (propertyGetter instanceof GetMemberActionItem) {
|
||||
int regId = getAsRegisterNum(((GetMemberActionItem) propertyGetter).object, "getter member not register");
|
||||
if (rnumObject != regId) {
|
||||
throw new AssertException("getter register does not match property register " + regId + " <=> " + rnumObject);
|
||||
}
|
||||
String getterNameStr = getAsString(((GetMemberActionItem) propertyGetter).memberName, "getter memberName");
|
||||
if (!(getterNameStr.equals("__get__" + propertyNameStr))) {
|
||||
throw new AssertException("getter does not match property name");
|
||||
}
|
||||
//TODO: handle getter HERE
|
||||
|
||||
} else if (propertyGetter instanceof FunctionActionItem) {
|
||||
FunctionActionItem getterFunc = (FunctionActionItem) propertyGetter;
|
||||
if (!(getterFunc.actions.isEmpty() && getterFunc.functionName.isEmpty() && ((FunctionActionItem) propertyGetter).paramNames.isEmpty())) {
|
||||
throw new AssertException("unexpected getter value for property " + propertyNameStr);
|
||||
}
|
||||
//we got empty getter
|
||||
} else {
|
||||
throw new AssertException("unexpected getter value for property " + propertyNameStr + ": " + propertyGetter.getClass().getSimpleName());
|
||||
}
|
||||
|
||||
if (propertySetter instanceof GetMemberActionItem) {
|
||||
int regId = getAsRegisterNum(((GetMemberActionItem) propertySetter).object, "setter member");
|
||||
if (rnumObject != regId) {
|
||||
throw new AssertException("setter register does not match property register " + regId + " <=> " + rnumObject);
|
||||
}
|
||||
String setterNameStr = getAsString(((GetMemberActionItem) propertySetter).memberName, "setter memberNAme");
|
||||
if (!(setterNameStr.equals("__set__" + propertyNameStr))) {
|
||||
throw new AssertException("setter does not match property name");
|
||||
}
|
||||
//TODO: handle setter HERE
|
||||
} else if (propertySetter instanceof FunctionActionItem) {
|
||||
FunctionActionItem setterFunc = (FunctionActionItem) propertySetter;
|
||||
if (!(setterFunc.actions.isEmpty() && setterFunc.functionName.isEmpty() && ((FunctionActionItem) propertySetter).paramNames.isEmpty())) {
|
||||
throw new AssertException("unexpected getter value for property " + propertyNameStr);
|
||||
}
|
||||
//we got empty setter
|
||||
} else {
|
||||
throw new AssertException("unexpected setter value for property " + propertyNameStr + ": " + propertySetter.getClass().getSimpleName());
|
||||
}
|
||||
|
||||
} else {
|
||||
throw new AssertException("unknown push method name: " + pushMethodName);
|
||||
}
|
||||
} else if (item instanceof CallFunctionActionItem) {
|
||||
CallFunctionActionItem cf = (CallFunctionActionItem) item;
|
||||
String funName = getAsString(cf.functionName, "pushitem function name");
|
||||
if (funName.equals("ASSetPropFlags")) {
|
||||
//it should be ASSetPropFlags(a.b.c.D.prototype,null,1) as it sets prototype to hidden
|
||||
//see http://www.ryanjuckett.com/programming/how-to-use-assetpropflags-in-actionscript-2-0/
|
||||
if (cf.arguments.size() != 3) {
|
||||
throw new AssertException("Invalid number of arguments to ASSetPropFlags:" + cf.arguments.size() + ", 3 expected");
|
||||
}
|
||||
GraphTargetItem obj = cf.arguments.get(0);
|
||||
GraphTargetItem props = cf.arguments.get(1);
|
||||
GraphTargetItem flags = cf.arguments.get(2);
|
||||
if ((obj instanceof DirectValueActionItem) && (((DirectValueActionItem) obj).value instanceof RegisterNumber)) {
|
||||
RegisterNumber rn = (RegisterNumber) ((DirectValueActionItem) obj).value;
|
||||
if (rn.number != instanceReg) {
|
||||
throw new AssertException("ASSetPropFlags not on instanceReg");
|
||||
}
|
||||
} else {
|
||||
List<String> path = getMembersPath(obj);
|
||||
if (path != null && !path.isEmpty() && "_global".equals(path.get(0))) { //For classes in toplevel package, there's _global in path
|
||||
path.remove(0); //remove that _global
|
||||
}
|
||||
List<String> classPathWithPrototype = new ArrayList<>();
|
||||
classPathWithPrototype.addAll(classNamePath);
|
||||
classPathWithPrototype.add("prototype");
|
||||
if (!classPathWithPrototype.equals(path)) {
|
||||
throw new AssertException("ASSetPropFlags not on prototype");
|
||||
}
|
||||
}
|
||||
if (!((props instanceof DirectValueActionItem) && (((DirectValueActionItem) props).value == Null.INSTANCE))) {
|
||||
throw new AssertException("ASSetPropFlags properties param not null");
|
||||
}
|
||||
if (!((flags instanceof DirectValueActionItem) && (((DirectValueActionItem) flags).value == (Long) 1L))) {
|
||||
throw new AssertException("ASSetPropFlags flags not set to 1");
|
||||
}
|
||||
} else {
|
||||
throw new AssertException("unknown pushitem function call " + funName);
|
||||
}
|
||||
} else {
|
||||
throw new AssertException("unknown item - " + item.getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
|
||||
if (constructor != null) { //constructor should be there always, but just in calse
|
||||
//add constructor as trait
|
||||
traitsStatic.add(0, false);
|
||||
DirectValueActionItem classBaseName = new DirectValueActionItem(classNamePath.get(classNamePath.size() - 1));
|
||||
((FunctionActionItem) constructor).calculatedFunctionName = classBaseName;
|
||||
traits.add(0, new MyEntry<>(classBaseName, constructor));
|
||||
} else {
|
||||
throw new AssertException("No constructor found");
|
||||
}
|
||||
|
||||
ClassActionItem clsItem = new ClassActionItem(classNameTargetPath, extendsOp, implementsOp, traits, traitsStatic);
|
||||
for (int k = commandsStartPos; k <= commandsEndPos; k++) {
|
||||
commands.remove(commandsStartPos);
|
||||
}
|
||||
commands.add(commandsStartPos, clsItem);
|
||||
|
||||
//remove §§pop after, if it's there
|
||||
if (commandsStartPos + 1 < commands.size()) {
|
||||
if (commands.get(commandsStartPos + 1) instanceof PopItem) {
|
||||
commands.remove(commandsStartPos + 1);
|
||||
}
|
||||
}
|
||||
|
||||
// goto next line and check next classes
|
||||
return true;
|
||||
} catch (AssertException ex) {
|
||||
logger.log(Level.WARNING, "{0}: Cannot detect class - {1}", new Object[]{scriptPath, ex.getCondition()});
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean checkIfVariants(List<GraphTargetItem> commands, int pos, String scriptPath) {
|
||||
|
||||
|
||||
/*
|
||||
Variant 1:
|
||||
|
||||
if(!_global.a)
|
||||
{
|
||||
_global.a = new Object();
|
||||
}
|
||||
§§pop();
|
||||
if(!_global.a.b)
|
||||
{
|
||||
_global.a.b = new Object();
|
||||
}
|
||||
§§pop();
|
||||
if(!_global.a.b.c)
|
||||
{
|
||||
_global.a.b.c = new Object();
|
||||
}
|
||||
§§pop();
|
||||
if(!_global.a.b.c.D)
|
||||
{
|
||||
..class_content...
|
||||
}
|
||||
§§pop();
|
||||
*/
|
||||
List<String> pathToSearchVariant1 = new ArrayList<>();
|
||||
pathToSearchVariant1.add("_global");
|
||||
|
||||
check_variant1:
|
||||
for (int checkPos = pos; checkPos < commands.size(); checkPos++) {
|
||||
GraphTargetItem t = commands.get(checkPos);
|
||||
if (t instanceof IfItem) {
|
||||
IfItem ifItem = (IfItem) t;
|
||||
if (ifItem.expression instanceof NotItem) {
|
||||
NotItem nti = (NotItem) ifItem.expression;
|
||||
GraphTargetItem condType = nti.value;
|
||||
Reference<String> newMemberNameRef = new Reference<>("");
|
||||
|
||||
if (isMemberOfPath(condType, pathToSearchVariant1, newMemberNameRef)) {
|
||||
pathToSearchVariant1.add(newMemberNameRef.getVal());
|
||||
|
||||
//_global.a.b.c = new Object();
|
||||
if ((ifItem.onTrue.size() == 1) && (ifItem.onTrue.get(0) instanceof SetMemberActionItem) && (((SetMemberActionItem) ifItem.onTrue.get(0)).value instanceof NewObjectActionItem)) {
|
||||
//skip §§pop item if its there right after if
|
||||
if (checkPos + 1 < commands.size()) {
|
||||
GraphTargetItem tnext = commands.get(checkPos + 1);
|
||||
if (tnext instanceof PopItem) {
|
||||
checkPos++;
|
||||
}
|
||||
}
|
||||
continue check_variant1;
|
||||
}
|
||||
List<String> classPath = pathToSearchVariant1;
|
||||
classPath.remove(0); //remove _global
|
||||
if (this.checkClassContent(ifItem.onTrue, 0, pos, checkPos, commands, classPath, scriptPath)) {
|
||||
return true;
|
||||
} else {
|
||||
break check_variant1;
|
||||
}
|
||||
} else {
|
||||
break check_variant1;
|
||||
}
|
||||
} else {
|
||||
break check_variant1; //not an if !
|
||||
}
|
||||
} else {
|
||||
break check_variant1; //not an if
|
||||
}
|
||||
} //check_variant1
|
||||
|
||||
/*
|
||||
|
||||
Variant 2:
|
||||
|
||||
if(!a.b.c.D)
|
||||
{
|
||||
if(!a)
|
||||
{
|
||||
_global.a = new Object();
|
||||
}
|
||||
if(!a.b)
|
||||
{
|
||||
_global.a.b = new Object();
|
||||
}
|
||||
if(!a.b.c)
|
||||
{
|
||||
_global.a.b.c = new Object();
|
||||
}
|
||||
..class_content..
|
||||
}
|
||||
*/
|
||||
List<String> variant2CurrentPath = new ArrayList<>();
|
||||
check_variant2:
|
||||
if (commands.get(pos) instanceof IfItem) {
|
||||
IfItem ifItem = (IfItem) commands.get(pos);
|
||||
if (ifItem.expression instanceof NotItem) {
|
||||
NotItem nti = (NotItem) ifItem.expression;
|
||||
List<String> memPath = getMembersPath(nti.value);
|
||||
if (memPath == null) {
|
||||
break check_variant2;
|
||||
}
|
||||
if (ifItem.onTrue.size() < memPath.size()) {
|
||||
break check_variant2;
|
||||
}
|
||||
variant2CurrentPath.clear();
|
||||
List<GraphTargetItem> parts = ifItem.onTrue;
|
||||
int checkPos = 0;
|
||||
for (; checkPos < memPath.size() - 1; checkPos++) {
|
||||
variant2CurrentPath.add(memPath.get(checkPos));
|
||||
if (!(parts.get(checkPos) instanceof IfItem)) {
|
||||
break check_variant2;
|
||||
}
|
||||
IfItem ifItem2 = (IfItem) parts.get(checkPos);
|
||||
if (ifItem2.expression instanceof NotItem) {
|
||||
NotItem nti2 = (NotItem) ifItem2.expression;
|
||||
List<String> if2Path = getMembersPath(nti2.value);
|
||||
if (!variant2CurrentPath.equals(if2Path)) {
|
||||
break check_variant2;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (checkClassContent(parts, checkPos, pos, pos, commands, memPath, scriptPath)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}//check_variant2
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void checkClass(List<GraphTargetItem> commands, String scriptPath) {
|
||||
for (int pos = 0; pos < commands.size(); pos++) {
|
||||
checkIfVariants(commands, pos, scriptPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,9 +12,11 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
*/
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action;
|
||||
|
||||
import com.jpexs.decompiler.flash.ecma.Null;
|
||||
import com.jpexs.decompiler.flash.ecma.Undefined;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
@@ -181,6 +183,6 @@ public class ActionScriptObject implements Cloneable {
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return Undefined.INSTANCE;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -12,7 +12,8 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
*/
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.deobfuscation;
|
||||
|
||||
import com.jpexs.decompiler.flash.IdentifiersDeobfuscation;
|
||||
|
||||
+3
-2
@@ -12,7 +12,8 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
*/
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.flashlite;
|
||||
|
||||
import com.jpexs.decompiler.flash.BaseLocalData;
|
||||
@@ -42,7 +43,7 @@ public class ActionFSCommand2 extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartItem, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartItem, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
long numArgs = popLong(stack);
|
||||
GraphTargetItem command = stack.pop();
|
||||
List<GraphTargetItem> args = new ArrayList<>();
|
||||
|
||||
+3
-2
@@ -12,7 +12,8 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
*/
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.flashlite;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
@@ -73,7 +74,7 @@ public class ActionStrictMode extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartItem, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartItem, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
output.add(new StrictModeActionItem(this, lineStartItem, mode));
|
||||
}
|
||||
}
|
||||
|
||||
+3
-2
@@ -12,7 +12,8 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
*/
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.model;
|
||||
|
||||
import com.jpexs.decompiler.flash.IdentifiersDeobfuscation;
|
||||
@@ -303,7 +304,7 @@ public class FunctionActionItem extends ActionItem {
|
||||
needsFun2 = true;
|
||||
}
|
||||
if (localData.inMethod) {
|
||||
needsFun2 = true;
|
||||
//needsFun2 = true;
|
||||
}
|
||||
if (localData.inFunction > 1) {
|
||||
needsFun2 = true;
|
||||
|
||||
+7
-2
@@ -12,7 +12,8 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
*/
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.model;
|
||||
|
||||
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
|
||||
@@ -41,7 +42,11 @@ public class RandomNumberActionItem extends ActionItem {
|
||||
}
|
||||
|
||||
public static Integer getResult(Object maximum) {
|
||||
return rnd.nextInt(EcmaScript.toInt32(maximum));
|
||||
int maximumInt = EcmaScript.toInt32(maximum);
|
||||
if (maximumInt <= 0) {
|
||||
return 0;
|
||||
}
|
||||
return rnd.nextInt(maximumInt);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+50
-55
@@ -12,7 +12,8 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
*/
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.model.clauses;
|
||||
|
||||
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
|
||||
@@ -44,56 +45,39 @@ import java.util.Set;
|
||||
*/
|
||||
public class ClassActionItem extends ActionItem implements Block {
|
||||
|
||||
public List<GraphTargetItem> functions;
|
||||
|
||||
public List<GraphTargetItem> staticFunctions;
|
||||
|
||||
public GraphTargetItem extendsOp;
|
||||
|
||||
public List<GraphTargetItem> implementsOp;
|
||||
|
||||
public GraphTargetItem className;
|
||||
|
||||
public GraphTargetItem constructor;
|
||||
|
||||
public List<MyEntry<GraphTargetItem, GraphTargetItem>> vars;
|
||||
|
||||
public List<MyEntry<GraphTargetItem, GraphTargetItem>> staticVars;
|
||||
//public GraphTargetItem constructor;
|
||||
public List<MyEntry<GraphTargetItem, GraphTargetItem>> traits;
|
||||
public List<Boolean> traitsStatic;
|
||||
|
||||
public Set<String> uninitializedVars;
|
||||
|
||||
@Override
|
||||
public List<List<GraphTargetItem>> getSubs() {
|
||||
List<List<GraphTargetItem>> ret = new ArrayList<>();
|
||||
if (functions != null) {
|
||||
ret.add(functions);
|
||||
}
|
||||
if (staticFunctions != null) {
|
||||
ret.add(staticFunctions);
|
||||
}
|
||||
//? is this needed for traits ?
|
||||
return ret;
|
||||
}
|
||||
|
||||
public ClassActionItem(GraphTargetItem className, GraphTargetItem extendsOp, List<GraphTargetItem> implementsOp, GraphTargetItem constructor, List<GraphTargetItem> functions, List<MyEntry<GraphTargetItem, GraphTargetItem>> vars, List<GraphTargetItem> staticFunctions, List<MyEntry<GraphTargetItem, GraphTargetItem>> staticVars) {
|
||||
public ClassActionItem(GraphTargetItem className, GraphTargetItem extendsOp, List<GraphTargetItem> implementsOp, List<MyEntry<GraphTargetItem, GraphTargetItem>> traits, List<Boolean> traitsStatic) {
|
||||
super(null, null, NOPRECEDENCE);
|
||||
this.className = className;
|
||||
this.functions = functions;
|
||||
this.vars = vars;
|
||||
this.traits = traits;
|
||||
this.traitsStatic = traitsStatic;
|
||||
this.extendsOp = extendsOp;
|
||||
this.implementsOp = implementsOp;
|
||||
this.staticFunctions = staticFunctions;
|
||||
this.staticVars = staticVars;
|
||||
this.constructor = constructor;
|
||||
//this.constructor = constructor;
|
||||
|
||||
List<GraphTargetItem> allFunc = new ArrayList<>(functions);
|
||||
if (constructor != null) {
|
||||
allFunc.add(constructor);
|
||||
}
|
||||
this.uninitializedVars = new HashSet<>();
|
||||
List<GraphTargetItem> allUsages = new ArrayList<>();
|
||||
for (GraphTargetItem it : allFunc) {
|
||||
if (it instanceof FunctionActionItem) {
|
||||
FunctionActionItem f = (FunctionActionItem) it;
|
||||
for (MyEntry<GraphTargetItem, GraphTargetItem> it : traits) {
|
||||
if (it.getValue() instanceof FunctionActionItem) {
|
||||
FunctionActionItem f = (FunctionActionItem) it.getValue();
|
||||
detectUnitializedVars(f.actions, allUsages);
|
||||
}
|
||||
}
|
||||
@@ -102,7 +86,7 @@ public class ClassActionItem extends ActionItem implements Block {
|
||||
allMembers.add(it.toStringNoQuotes(LocalData.empty));
|
||||
}
|
||||
uninitializedVars.addAll(allMembers);
|
||||
for (MyEntry<GraphTargetItem, GraphTargetItem> v : vars) {
|
||||
for (MyEntry<GraphTargetItem, GraphTargetItem> v : traits) {
|
||||
String s = v.getKey().toStringNoQuotes(LocalData.empty);
|
||||
if (uninitializedVars.contains(s)) {
|
||||
uninitializedVars.remove(s);
|
||||
@@ -176,38 +160,49 @@ public class ClassActionItem extends ActionItem implements Block {
|
||||
}
|
||||
writer.startBlock();
|
||||
|
||||
if (constructor != null) {
|
||||
/*if (constructor != null) {
|
||||
constructor.toString(writer, localData).newLine();
|
||||
}
|
||||
}*/
|
||||
for (int pass = 1; pass <= 2; pass++) {
|
||||
looptraits:
|
||||
for (int i = 0; i < traits.size(); i++) {
|
||||
MyEntry<GraphTargetItem, GraphTargetItem> item = traits.get(i);
|
||||
|
||||
for (MyEntry<GraphTargetItem, GraphTargetItem> item : vars) {
|
||||
writer.append("var ");
|
||||
item.getKey().toStringNoQuotes(writer, localData);
|
||||
writer.append(" = ");
|
||||
item.getValue().toString(writer, localData);
|
||||
writer.append(";").newLine();
|
||||
switch (pass) {
|
||||
//pass 1: add variables
|
||||
case 1:
|
||||
if (item.getValue() instanceof FunctionActionItem) { //ignore methods
|
||||
continue looptraits;
|
||||
}
|
||||
break;
|
||||
//pass 2: add methods
|
||||
case 2:
|
||||
if (!(item.getValue() instanceof FunctionActionItem)) { //ignore nonmethods
|
||||
continue looptraits;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if (traitsStatic.get(i)) {
|
||||
writer.append("static ");
|
||||
}
|
||||
if (item.getValue() instanceof FunctionActionItem) {
|
||||
item.getValue().toString(writer, localData).newLine();
|
||||
} else {
|
||||
writer.append("var ");
|
||||
item.getKey().toStringNoQuotes(writer, localData);
|
||||
writer.append(" = ");
|
||||
item.getValue().toString(writer, localData);
|
||||
writer.append(";").newLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
for (String v : uninitializedVars) {
|
||||
writer.append("var ");
|
||||
writer.append(v);
|
||||
writer.append(";").newLine();
|
||||
}
|
||||
for (MyEntry<GraphTargetItem, GraphTargetItem> item : staticVars) {
|
||||
writer.append("static var ");
|
||||
item.getKey().toStringNoQuotes(writer, localData);
|
||||
writer.append(" = ");
|
||||
item.getValue().toString(writer, localData);
|
||||
writer.append(";").newLine();
|
||||
}
|
||||
|
||||
for (GraphTargetItem f : functions) {
|
||||
f.toString(writer, localData).newLine();
|
||||
}
|
||||
for (GraphTargetItem f : staticFunctions) {
|
||||
writer.append("static ");
|
||||
f.toString(writer, localData).newLine();
|
||||
}
|
||||
|
||||
writer.endBlock();
|
||||
writer.endClass();
|
||||
return writer;
|
||||
@@ -230,7 +225,7 @@ public class ClassActionItem extends ActionItem implements Block {
|
||||
ActionSourceGenerator asGenerator = (ActionSourceGenerator) generator;
|
||||
SourceGeneratorLocalData localData2 = Helper.deepCopy(localData);
|
||||
asGenerator.setInMethod(localData2, true);
|
||||
ret.addAll(asGenerator.generateTraits(localData2, false, className, extendsOp, implementsOp, constructor, functions, vars, staticFunctions, staticVars));
|
||||
ret.addAll(asGenerator.generateTraits(localData2, false, className, extendsOp, implementsOp, traits, traitsStatic));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -12,7 +12,8 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
*/
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.model.clauses;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
|
||||
+4
-2
@@ -12,7 +12,8 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
*/
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.model.clauses;
|
||||
|
||||
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
|
||||
@@ -20,6 +21,7 @@ import com.jpexs.decompiler.flash.action.Action;
|
||||
import com.jpexs.decompiler.flash.action.model.ActionItem;
|
||||
import com.jpexs.decompiler.flash.action.parser.script.ActionSourceGenerator;
|
||||
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.flash.helpers.collections.MyEntry;
|
||||
import com.jpexs.decompiler.graph.CompilationException;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
@@ -72,7 +74,7 @@ public class InterfaceActionItem extends ActionItem {
|
||||
public List<GraphSourceItem> toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException {
|
||||
List<GraphSourceItem> ret = new ArrayList<>();
|
||||
ActionSourceGenerator asGenerator = (ActionSourceGenerator) generator;
|
||||
ret.addAll(asGenerator.generateTraits(localData, true, name, null, superInterfaces, null, null, null, null, null));
|
||||
ret.addAll(asGenerator.generateTraits(localData, true, name, null, superInterfaces, new ArrayList<MyEntry<GraphTargetItem, GraphTargetItem>>(), new ArrayList<>()));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
+104
-15
@@ -12,7 +12,8 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
*/
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.model.clauses;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
@@ -20,9 +21,21 @@ import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
|
||||
import com.jpexs.decompiler.flash.action.Action;
|
||||
import com.jpexs.decompiler.flash.action.model.ActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.ConstantPool;
|
||||
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.ActionPop;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionPush;
|
||||
import com.jpexs.decompiler.flash.action.swf4.RegisterNumber;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionDefineLocal;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionEquals2;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionPushDuplicate;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionStackSwap;
|
||||
import com.jpexs.decompiler.flash.action.swf7.ActionCastOp;
|
||||
import com.jpexs.decompiler.flash.action.swf7.ActionThrow;
|
||||
import com.jpexs.decompiler.flash.action.swf7.ActionTry;
|
||||
import com.jpexs.decompiler.flash.ecma.Null;
|
||||
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.graph.Block;
|
||||
import com.jpexs.decompiler.graph.CompilationException;
|
||||
@@ -33,6 +46,8 @@ import com.jpexs.decompiler.graph.model.ContinueItem;
|
||||
import com.jpexs.decompiler.graph.model.LocalData;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -42,7 +57,9 @@ public class TryActionItem extends ActionItem implements Block {
|
||||
|
||||
public List<GraphTargetItem> tryCommands;
|
||||
|
||||
public List<GraphTargetItem> catchExceptions;
|
||||
public List<GraphTargetItem> catchExceptionNames;
|
||||
|
||||
public List<GraphTargetItem> catchExceptionTypes;
|
||||
|
||||
public List<List<GraphTargetItem>> catchCommands;
|
||||
|
||||
@@ -61,10 +78,11 @@ public class TryActionItem extends ActionItem implements Block {
|
||||
return ret;
|
||||
}
|
||||
|
||||
public TryActionItem(List<GraphTargetItem> tryCommands, List<GraphTargetItem> catchExceptions, List<List<GraphTargetItem>> catchCommands, List<GraphTargetItem> finallyCommands) {
|
||||
public TryActionItem(List<GraphTargetItem> tryCommands, List<GraphTargetItem> catchExceptionNames, List<GraphTargetItem> catchExceptionTypes, List<List<GraphTargetItem>> catchCommands, List<GraphTargetItem> finallyCommands) {
|
||||
super(null, null, NOPRECEDENCE);
|
||||
this.tryCommands = tryCommands;
|
||||
this.catchExceptions = catchExceptions;
|
||||
this.catchExceptionNames = catchExceptionNames;
|
||||
this.catchExceptionTypes = catchExceptionTypes;
|
||||
this.catchCommands = catchCommands;
|
||||
this.finallyCommands = finallyCommands;
|
||||
}
|
||||
@@ -73,19 +91,23 @@ public class TryActionItem extends ActionItem implements Block {
|
||||
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException {
|
||||
writer.append("try");
|
||||
appendBlock(null, writer, localData, tryCommands);
|
||||
for (int e = 0; e < catchExceptions.size(); e++) {
|
||||
for (int e = 0; e < catchExceptionNames.size(); e++) {
|
||||
writer.newLine();
|
||||
writer.append("catch");
|
||||
if (writer.getFormatting().spaceBeforeParenthesesCatchParentheses) {
|
||||
writer.append(" ");
|
||||
}
|
||||
writer.append("(");
|
||||
catchExceptions.get(e).toStringNoQuotes(writer, localData);
|
||||
catchExceptionNames.get(e).toStringNoQuotes(writer, localData);
|
||||
if (catchExceptionTypes.get(e) != null) {
|
||||
writer.append(":");
|
||||
catchExceptionTypes.get(e).toStringNoQuotes(writer, localData);
|
||||
}
|
||||
writer.append(")");
|
||||
List<GraphTargetItem> commands = catchCommands.get(e);
|
||||
appendBlock(null, writer, localData, commands);
|
||||
}
|
||||
if (catchExceptions.isEmpty() || finallyCommands.size() > 0) {
|
||||
if (catchExceptionNames.isEmpty() || finallyCommands.size() > 0) {
|
||||
writer.newLine();
|
||||
writer.append("finally");
|
||||
appendBlock(null, writer, localData, finallyCommands);
|
||||
@@ -140,15 +162,82 @@ public class TryActionItem extends ActionItem implements Block {
|
||||
List<Action> finallyCommandsA = finallyCommands == null ? null : asGenerator.toActionList(asGenerator.generate(localData, finallyCommands));
|
||||
List<Action> catchCommandsA = null;
|
||||
String catchName = null;
|
||||
if (catchExceptions != null) {
|
||||
if (!catchExceptions.isEmpty()) {
|
||||
catchName = catchExceptions.get(0).toStringNoQuotes(LocalData.create(new ConstantPool(asGenerator.getConstantPool())));
|
||||
}
|
||||
|
||||
}
|
||||
int catchSize = 0;
|
||||
int catchRegister = 0;
|
||||
boolean catchInRegisterFlag = false;
|
||||
if (catchCommands != null && !catchCommands.isEmpty()) {
|
||||
catchCommandsA = asGenerator.toActionList(asGenerator.generate(localData, catchCommands.get(0)));
|
||||
|
||||
List<GraphSourceItem> fullCatchBody = new ArrayList<>();
|
||||
|
||||
if (catchExceptionNames.size() == 1 && catchExceptionTypes.get(0) == null) { //catch everything without any type
|
||||
GraphTargetItem ename = catchExceptionNames.get(0);
|
||||
if (ename instanceof DirectValueActionItem) {
|
||||
catchName = ((DirectValueActionItem) ename).getAsString();
|
||||
} else {
|
||||
Logger.getLogger(TryActionItem.class.getName()).log(Level.SEVERE, "Invalid catchName, string expected");
|
||||
}
|
||||
catchInRegisterFlag = false;
|
||||
fullCatchBody = GraphTargetItem.toSourceMerge(localData, generator, catchCommands.get(0));
|
||||
} else {
|
||||
catchInRegisterFlag = true;
|
||||
catchRegister = asGenerator.getTempRegister(localData);
|
||||
boolean allCatched = false;
|
||||
for (int i = catchExceptionNames.size() - 1; i >= 0; i--) {
|
||||
GraphTargetItem etype = catchExceptionTypes.get(i);
|
||||
if (etype == null) {
|
||||
allCatched = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!allCatched) {
|
||||
fullCatchBody.addAll(0, GraphTargetItem.toSourceMerge(localData, generator,
|
||||
new ActionPush(new RegisterNumber(catchRegister)),
|
||||
new ActionThrow()
|
||||
));
|
||||
}
|
||||
|
||||
for (int i = catchExceptionNames.size() - 1; i >= 0; i--) {
|
||||
GraphTargetItem ename = catchExceptionNames.get(i);
|
||||
GraphTargetItem etype = catchExceptionTypes.get(i);
|
||||
List<GraphTargetItem> ebody = catchCommands.get(i);
|
||||
if (etype == null) {
|
||||
fullCatchBody.addAll(0, GraphTargetItem.toSourceMerge(localData, generator,
|
||||
new DirectValueActionItem(new RegisterNumber(catchRegister)),
|
||||
ename,
|
||||
new ActionStackSwap(),
|
||||
new ActionDefineLocal(),
|
||||
ebody
|
||||
));
|
||||
} else {
|
||||
List<GraphSourceItem> ifBody = GraphTargetItem.toSourceMerge(localData, generator,
|
||||
ename,
|
||||
new ActionStackSwap(),
|
||||
new ActionDefineLocal(),
|
||||
ebody);
|
||||
fullCatchBody.add(0, new ActionPop());
|
||||
int toFinishSize = Action.actionsToBytes(asGenerator.toActionList(fullCatchBody), false, SWF.DEFAULT_VERSION).length;
|
||||
ActionJump finishJump = new ActionJump(toFinishSize);
|
||||
ifBody.add(finishJump);
|
||||
List<Action> ifBodyA = asGenerator.toActionList(ifBody);
|
||||
int ifBodySize = Action.actionsToBytes(ifBodyA, false, SWF.DEFAULT_VERSION).length;
|
||||
fullCatchBody.addAll(0, ifBody);
|
||||
fullCatchBody.addAll(0,
|
||||
GraphTargetItem.toSourceMerge(localData, generator,
|
||||
etype,
|
||||
new ActionPush(new RegisterNumber(catchRegister)),
|
||||
new ActionCastOp(),
|
||||
new ActionPushDuplicate(),
|
||||
new ActionPush(Null.INSTANCE),
|
||||
new ActionEquals2(),
|
||||
new ActionIf(ifBodySize)
|
||||
));
|
||||
|
||||
}
|
||||
}
|
||||
asGenerator.releaseTempRegister(localData, catchRegister);
|
||||
}
|
||||
catchCommandsA = asGenerator.toActionList(fullCatchBody);
|
||||
catchSize = Action.actionsToBytes(catchCommandsA, false, SWF.DEFAULT_VERSION).length;
|
||||
tryCommandsA.add(new ActionJump(catchSize));
|
||||
}
|
||||
@@ -157,7 +246,7 @@ public class TryActionItem extends ActionItem implements Block {
|
||||
finallySize = Action.actionsToBytes(finallyCommandsA, false, SWF.DEFAULT_VERSION).length;
|
||||
}
|
||||
int trySize = Action.actionsToBytes(tryCommandsA, false, SWF.DEFAULT_VERSION).length;
|
||||
ret.add(new ActionTry(false, finallyCommands != null, catchCommands != null, catchName, 0, trySize, catchSize, finallySize, SWF.DEFAULT_VERSION));
|
||||
ret.add(new ActionTry(catchInRegisterFlag, finallyCommands != null, catchCommands != null, catchName, catchRegister, trySize, catchSize, finallySize, SWF.DEFAULT_VERSION));
|
||||
ret.addAll(tryCommandsA);
|
||||
if (catchCommandsA != null) {
|
||||
ret.addAll(catchCommandsA);
|
||||
|
||||
+98
-28
@@ -12,7 +12,8 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
*/
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.parser.script;
|
||||
|
||||
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
|
||||
@@ -119,6 +120,7 @@ import com.jpexs.decompiler.flash.action.model.operations.SubtractActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.operations.URShiftActionItem;
|
||||
import com.jpexs.decompiler.flash.action.parser.ActionParseException;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionIf;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionPush;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ConstantIndex;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionConstantPool;
|
||||
import com.jpexs.decompiler.flash.ecma.Null;
|
||||
@@ -338,11 +340,8 @@ public class ActionScript2Parser {
|
||||
globalClassTypeStr.addAll(nameStr);*/
|
||||
|
||||
ParsedSymbol s;
|
||||
FunctionActionItem constr = null;
|
||||
List<GraphTargetItem> staticFunctions = new ArrayList<>();
|
||||
List<MyEntry<GraphTargetItem, GraphTargetItem>> staticVars = new ArrayList<>();
|
||||
List<GraphTargetItem> instanceFunctions = new ArrayList<>();
|
||||
List<MyEntry<GraphTargetItem, GraphTargetItem>> vars = new ArrayList<>();
|
||||
List<MyEntry<GraphTargetItem, GraphTargetItem>> traits = new ArrayList<>();
|
||||
List<Boolean> traitsStatic = new ArrayList<>();
|
||||
|
||||
String classNameStr = "";
|
||||
if (nameStr instanceof GetMemberActionItem) {
|
||||
@@ -373,16 +372,21 @@ public class ActionScript2Parser {
|
||||
expected(s, lexer.yyline(), SymbolType.IDENTIFIER, SymbolGroup.GLOBALFUNC);
|
||||
String fname = s.value.toString();
|
||||
if (fname.equals(classNameStr)) { //constructor
|
||||
constr = (function(!isInterface, "", true, variables, functions));
|
||||
} else if (!isInterface) {
|
||||
//actually there's no difference, it's instance trait
|
||||
}
|
||||
if (!isInterface) {
|
||||
if (isStatic) {
|
||||
FunctionActionItem ft = function(!isInterface, "", true, variables, functions);
|
||||
ft.calculatedFunctionName = pushConst(fname);
|
||||
staticFunctions.add(ft);
|
||||
//staticFunctions.add(ft);
|
||||
traits.add(new MyEntry<>(ft.calculatedFunctionName, ft));
|
||||
traitsStatic.add(true);
|
||||
} else {
|
||||
FunctionActionItem ft = function(!isInterface, "", true, variables, functions);
|
||||
ft.calculatedFunctionName = pushConst(fname);
|
||||
instanceFunctions.add(ft);
|
||||
//instanceFunctions.add(ft);
|
||||
traits.add(new MyEntry<>(ft.calculatedFunctionName, ft));
|
||||
traitsStatic.add(false);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -396,11 +400,8 @@ public class ActionScript2Parser {
|
||||
s = lex();
|
||||
}
|
||||
if (s.type == SymbolType.ASSIGN) {
|
||||
if (isStatic) {
|
||||
staticVars.add(new MyEntry<>(pushConst(ident), expression(false, false, true, variables, functions)));
|
||||
} else {
|
||||
vars.add(new MyEntry<>(pushConst(ident), expression(false, false, true, variables, functions)));
|
||||
}
|
||||
traits.add(new MyEntry<>(pushConst(ident), expression(false, false, true, variables, functions)));
|
||||
traitsStatic.add(isStatic);
|
||||
s = lex();
|
||||
}
|
||||
if (s.type != SymbolType.SEMICOLON) {
|
||||
@@ -417,7 +418,7 @@ public class ActionScript2Parser {
|
||||
if (isInterface) {
|
||||
return new InterfaceActionItem(nameStr, implementsStr);
|
||||
} else {
|
||||
return new ClassActionItem(nameStr, extendsStr, implementsStr, constr, instanceFunctions, vars, staticFunctions, staticVars);
|
||||
return new ClassActionItem(nameStr, extendsStr, implementsStr, traits, traitsStatic);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1151,14 +1152,25 @@ public class ActionScript2Parser {
|
||||
s = lex();
|
||||
boolean found = false;
|
||||
List<List<GraphTargetItem>> catchCommands = null;
|
||||
List<GraphTargetItem> catchExceptions = new ArrayList<>();
|
||||
if (s.type == SymbolType.CATCH) {
|
||||
List<GraphTargetItem> catchExceptionNames = new ArrayList<>();
|
||||
List<GraphTargetItem> catchExceptionTypes = new ArrayList<>();
|
||||
|
||||
while (s.type == SymbolType.CATCH) {
|
||||
expectedType(SymbolType.PARENT_OPEN);
|
||||
s = lex();
|
||||
expected(s, lexer.yyline(), SymbolType.IDENTIFIER, SymbolType.STRING);
|
||||
catchExceptions.add(pushConst((String) s.value));
|
||||
catchExceptionNames.add(pushConst((String) s.value));
|
||||
s = lex();
|
||||
if (s.type == SymbolType.COLON) {
|
||||
catchExceptionTypes.add(type(variables));
|
||||
} else {
|
||||
catchExceptionTypes.add(null);
|
||||
lexer.pushback(s);
|
||||
}
|
||||
expectedType(SymbolType.PARENT_CLOSE);
|
||||
catchCommands = new ArrayList<>();
|
||||
if (catchCommands == null) {
|
||||
catchCommands = new ArrayList<>();
|
||||
}
|
||||
List<GraphTargetItem> cc = new ArrayList<>();
|
||||
cc.add(command(inFunction, inMethod, forinlevel, true, variables, functions));
|
||||
catchCommands.add(cc);
|
||||
@@ -1176,7 +1188,7 @@ public class ActionScript2Parser {
|
||||
expected(s, lexer.yyline(), SymbolType.CATCH, SymbolType.FINALLY);
|
||||
}
|
||||
lexer.pushback(s);
|
||||
ret = new TryActionItem(tryCommands, catchExceptions, catchCommands, finallyCommands);
|
||||
ret = new TryActionItem(tryCommands, catchExceptionNames, catchExceptionTypes, catchCommands, finallyCommands);
|
||||
break;
|
||||
case THROW:
|
||||
ret = new ThrowActionItem(null, null, expression(inFunction, inMethod, true, variables, functions));
|
||||
@@ -1872,12 +1884,58 @@ public class ActionScript2Parser {
|
||||
return retTree;
|
||||
}
|
||||
|
||||
public List<Action> actionsFromTree(List<GraphTargetItem> tree, List<String> constantPool) throws CompilationException {
|
||||
private List<GraphSourceItem> generateActionList(List<GraphTargetItem> tree, List<String> constantPool) throws CompilationException {
|
||||
ActionSourceGenerator gen = new ActionSourceGenerator(swfVersion, constantPool);
|
||||
SourceGeneratorLocalData localData = new SourceGeneratorLocalData(new HashMap<>(), 0, Boolean.FALSE, 0);
|
||||
return gen.generate(localData, tree);
|
||||
}
|
||||
|
||||
private List<Action> actionsFromTree(List<GraphTargetItem> tree, List<String> constantPool, boolean doOrder) throws CompilationException, NeedsGenerateAgainException {
|
||||
List<Action> ret = new ArrayList<>();
|
||||
SourceGeneratorLocalData localData = new SourceGeneratorLocalData(
|
||||
new HashMap<>(), 0, Boolean.FALSE, 0);
|
||||
List<GraphSourceItem> srcList = gen.generate(localData, tree);
|
||||
|
||||
List<GraphSourceItem> srcList = generateActionList(tree, constantPool);
|
||||
|
||||
if (doOrder) {
|
||||
List<String> orderedConstantPool = new ArrayList<>();
|
||||
boolean canChangeInPlace;
|
||||
int lastIndex = constantPool.size() - 1;
|
||||
if (lastIndex <= ActionPush.MAX_CONSTANT_INDEX_TYPE8) {
|
||||
//can change constant indices as ActionPush contains always 1 byte per constant
|
||||
canChangeInPlace = true;
|
||||
} else {
|
||||
//variable number bytes per ActionPush constant,
|
||||
//must generate again to make relative offsets in jumps work
|
||||
canChangeInPlace = false;
|
||||
}
|
||||
|
||||
//create ordered constant pool, update constantindices when we can changeinplace
|
||||
for (GraphSourceItem src : srcList) {
|
||||
if (src instanceof ActionPush) {
|
||||
ActionPush ap = (ActionPush) src;
|
||||
for (int i = 0; i < ap.values.size(); i++) {
|
||||
Object val = ap.values.get(i);
|
||||
if (val instanceof ConstantIndex) {
|
||||
ConstantIndex ci = (ConstantIndex) val;
|
||||
String cval = constantPool.get(ci.index);
|
||||
int orderedIndex = orderedConstantPool.indexOf(cval);
|
||||
if (orderedIndex == -1) {
|
||||
orderedIndex = orderedConstantPool.size();
|
||||
orderedConstantPool.add(cval);
|
||||
}
|
||||
if (canChangeInPlace) {
|
||||
//Do NOT change ci.index directly - it may be cloned from other location
|
||||
ap.values.set(i, new ConstantIndex(orderedIndex));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!canChangeInPlace) {
|
||||
//generate again, as number of bytes per ActionPush can change
|
||||
throw new NeedsGenerateAgainException(orderedConstantPool);
|
||||
}
|
||||
constantPool = orderedConstantPool;
|
||||
}
|
||||
for (GraphSourceItem s : srcList) {
|
||||
if (s instanceof Action) {
|
||||
ret.add((Action) s);
|
||||
@@ -1888,9 +1946,21 @@ public class ActionScript2Parser {
|
||||
}
|
||||
|
||||
public List<Action> actionsFromString(String s) throws ActionParseException, IOException, CompilationException {
|
||||
List<String> constantPool = new ArrayList<>();
|
||||
List<GraphTargetItem> tree = treeFromString(s, constantPool);
|
||||
return actionsFromTree(tree, constantPool);
|
||||
try {
|
||||
List<String> constantPool = new ArrayList<>();
|
||||
List<GraphTargetItem> tree = treeFromString(s, constantPool);
|
||||
return actionsFromTree(tree, constantPool, true);
|
||||
} catch (NeedsGenerateAgainException nga) {
|
||||
//Can happen when constantpool needs reordering and number of constants > 256
|
||||
try {
|
||||
List<String> newConstantPool = nga.getNewConstantPool();
|
||||
List<GraphTargetItem> tree = treeFromString(s, newConstantPool);
|
||||
return actionsFromTree(tree, newConstantPool, false /*do not order again*/);
|
||||
} catch (NeedsGenerateAgainException ex) {
|
||||
//should not happen as doOrder parameter is set to false
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void versionRequired(ParsedSymbol s, int min) throws ActionParseException {
|
||||
|
||||
+41
-31
@@ -12,7 +12,8 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
*/
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.parser.script;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
@@ -655,7 +656,7 @@ public class ActionSourceGenerator implements SourceGenerator {
|
||||
return new ActionPush(new ConstantIndex(index));
|
||||
}
|
||||
|
||||
public List<GraphSourceItem> generateTraits(SourceGeneratorLocalData localData, boolean isInterface, GraphTargetItem name, GraphTargetItem extendsVal, List<GraphTargetItem> implementsStr, GraphTargetItem constructor, List<GraphTargetItem> functions, List<MyEntry<GraphTargetItem, GraphTargetItem>> vars, List<GraphTargetItem> staticFunctions, List<MyEntry<GraphTargetItem, GraphTargetItem>> staticVars) throws CompilationException {
|
||||
public List<GraphSourceItem> generateTraits(SourceGeneratorLocalData localData, boolean isInterface, GraphTargetItem name, GraphTargetItem extendsVal, List<GraphTargetItem> implementsStr, List<MyEntry<GraphTargetItem, GraphTargetItem>> traits, List<Boolean> traitsStatic) throws CompilationException {
|
||||
List<String> extendsStr = getVarParts(extendsVal);
|
||||
List<GraphSourceItem> ret = new ArrayList<>();
|
||||
List<String> nameStr = getVarParts(name);
|
||||
@@ -668,7 +669,7 @@ public class ActionSourceGenerator implements SourceGenerator {
|
||||
}
|
||||
|
||||
List<Action> val = new ArrayList<>();
|
||||
val.add(new ActionPush((Long) 0L));
|
||||
val.add(new ActionPush((Double) 0.0));
|
||||
val.add(pushConst("Object"));
|
||||
val.add(new ActionNewObject());
|
||||
notBody.addAll(typeToActions(globalClassTypeStr, val));
|
||||
@@ -677,12 +678,26 @@ public class ActionSourceGenerator implements SourceGenerator {
|
||||
ret.add(new ActionNot());
|
||||
ret.add(new ActionIf(Action.actionsToBytes(notBody, false, SWF.DEFAULT_VERSION).length));
|
||||
ret.addAll(notBody);
|
||||
ret.add(new ActionPop());
|
||||
}
|
||||
List<Action> ifbody = new ArrayList<>();
|
||||
List<String> globalClassTypeStr = new ArrayList<>();
|
||||
globalClassTypeStr.add("_global");
|
||||
globalClassTypeStr.addAll(nameStr);
|
||||
|
||||
String constructorName = nameStr.get(nameStr.size() - 1); //com.jpexs.MyClass => MyClass
|
||||
GraphTargetItem constructor = null;
|
||||
int constructorIndex = -1;
|
||||
for (int t = 0; t < traits.size(); t++) {
|
||||
MyEntry<GraphTargetItem, GraphTargetItem> en = traits.get(t);
|
||||
if (en.getValue() instanceof FunctionActionItem) {
|
||||
if (constructorName.equals(getName(en.getKey()))) {
|
||||
constructorIndex = t;
|
||||
constructor = en.getValue();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
ParsedSymbol s = null;
|
||||
List<Action> constr = new ArrayList<>();
|
||||
|
||||
@@ -692,45 +707,40 @@ public class ActionSourceGenerator implements SourceGenerator {
|
||||
if (!isInterface) {
|
||||
val.add(new ActionStoreRegister(1));
|
||||
}
|
||||
constr.addAll(typeToActions(globalClassTypeStr, val));
|
||||
constr.addAll(typeToActions(nameStr, val));
|
||||
} else {
|
||||
constr.addAll(toActionList(((FunctionActionItem) constructor).toSource(localData, this)));
|
||||
constr.add(new ActionStoreRegister(1));
|
||||
constr = (typeToActions(globalClassTypeStr, constr));
|
||||
constr = (typeToActions(nameStr, constr));
|
||||
}
|
||||
if (!isInterface) {
|
||||
for (GraphTargetItem f : staticFunctions) {
|
||||
FunctionActionItem fi = (FunctionActionItem) f;
|
||||
ifbody.add(new ActionPush(new RegisterNumber(1/*static*/)));
|
||||
ifbody.add(new ActionPush(getName(fi.calculatedFunctionName)));
|
||||
ifbody.addAll(toActionList(fi.toSource(localData, this)));
|
||||
ifbody.add(new ActionSetMember());
|
||||
}
|
||||
for (GraphTargetItem f : functions) {
|
||||
FunctionActionItem fi = (FunctionActionItem) f;
|
||||
ifbody.add(new ActionPush(new RegisterNumber(2/*instance*/)));
|
||||
ifbody.add(new ActionPush(getName(fi.calculatedFunctionName)));
|
||||
ifbody.addAll(toActionList(fi.toSource(localData, this)));
|
||||
ifbody.add(new ActionSetMember());
|
||||
}
|
||||
for (MyEntry<GraphTargetItem, GraphTargetItem> en : staticVars) {
|
||||
ifbody.add(new ActionPush(new RegisterNumber(1/*static*/)));
|
||||
ifbody.add(new ActionPush(getName(en.getKey())));
|
||||
ifbody.addAll(toActionList(en.getValue().toSource(localData, this)));
|
||||
ifbody.add(new ActionSetMember());
|
||||
}
|
||||
for (MyEntry<GraphTargetItem, GraphTargetItem> en : vars) {
|
||||
ifbody.add(new ActionPush(new RegisterNumber(2/*instance*/)));
|
||||
ifbody.add(new ActionPush(getName(en.getKey())));
|
||||
ifbody.addAll(toActionList(en.getValue().toSource(localData, this)));
|
||||
ifbody.add(new ActionSetMember());
|
||||
for (int pass = 1; pass <= 2; pass++) { //two passes, methods first, then variables
|
||||
for (int t = 0; t < traits.size(); t++) {
|
||||
if (constructorIndex == t) { //constructor already handled
|
||||
continue;
|
||||
}
|
||||
MyEntry<GraphTargetItem, GraphTargetItem> en = traits.get(t);
|
||||
boolean isFunc = (en.getValue() instanceof FunctionActionItem);
|
||||
if (pass == 1 && isFunc) { //Add methods in first pass
|
||||
FunctionActionItem fi = (FunctionActionItem) en.getValue();
|
||||
ifbody.add(new ActionPush(new RegisterNumber(traitsStatic.get(t) ? 1 : 2)));
|
||||
ifbody.add(pushConst(getName(en.getKey())));
|
||||
ifbody.addAll(toActionList(fi.toSource(localData, this)));
|
||||
ifbody.add(new ActionSetMember());
|
||||
} else if (pass == 2 && !isFunc) { //add variables in second pass
|
||||
ifbody.add(new ActionPush(new RegisterNumber(traitsStatic.get(t) ? 1 : 2)));
|
||||
ifbody.add(pushConst(getName(en.getKey())));
|
||||
ifbody.addAll(toActionList(en.getValue().toSource(localData, this)));
|
||||
ifbody.add(new ActionSetMember());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isInterface) {
|
||||
ifbody.add(new ActionPush((Long) 1L));
|
||||
ifbody.add(new ActionPush(Null.INSTANCE));
|
||||
ifbody.addAll(typeToActions(globalClassTypeStr, null));
|
||||
ifbody.addAll(typeToActions(nameStr, null));
|
||||
ifbody.add(pushConst("prototype"));
|
||||
ifbody.add(new ActionGetMember());
|
||||
ifbody.add(new ActionPush((Long) 3L));
|
||||
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2018 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 java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class NeedsGenerateAgainException extends Exception {
|
||||
|
||||
private List<String> newConstantPool;
|
||||
|
||||
public NeedsGenerateAgainException(List<String> newConstantPool) {
|
||||
this.newConstantPool = newConstantPool;
|
||||
}
|
||||
|
||||
public List<String> getNewConstantPool() {
|
||||
return newConstantPool;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -12,7 +12,8 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
*/
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.special;
|
||||
|
||||
import com.jpexs.decompiler.flash.action.Action;
|
||||
@@ -52,7 +53,7 @@ public class ActionEnd extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartItem, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartItem, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
//output.add(new SimpleActionTreeItem(this, "end()"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
*/
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.special;
|
||||
|
||||
import com.jpexs.decompiler.flash.action.Action;
|
||||
@@ -48,7 +49,7 @@ public class ActionNop extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartItem, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartItem, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
//output.add(new SimpleActionTreeItem(this, "nop();"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
*/
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.special;
|
||||
|
||||
import com.jpexs.decompiler.flash.action.LocalDataArea;
|
||||
@@ -45,6 +46,6 @@ public class ActionUnknown extends ActionNop {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartItem, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartItem, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ public class ActionGetURL extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
String fsCommandPrefix = "FSCommand:";
|
||||
if (urlString.startsWith(fsCommandPrefix) && targetString.isEmpty()) {
|
||||
String command = urlString.substring(fsCommandPrefix.length());
|
||||
|
||||
@@ -86,7 +86,7 @@ public class ActionGoToLabel extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
output.add(new GotoLabelActionItem(this, lineStartAction, label));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ public class ActionGotoFrame extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
output.add(new GotoFrameActionItem(this, lineStartAction, frame));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ public class ActionNextFrame extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
output.add(new NextFrameActionItem(this, lineStartAction));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ public class ActionPlay extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
if (!output.isEmpty() && (output.get(output.size() - 1) instanceof GotoFrameActionItem)) {
|
||||
GotoFrameActionItem gta = (GotoFrameActionItem) output.remove(output.size() - 1);
|
||||
output.add(new GotoFrame2ActionItem(this, lineStartAction, new DirectValueActionItem(gta.frame + 1), false, true, 0));
|
||||
|
||||
@@ -53,7 +53,7 @@ public class ActionPrevFrame extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
output.add(new PrevFrameActionItem(this, lineStartAction));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ public class ActionSetTarget extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
output.add(new SetTargetActionItem(this, lineStartAction, targetName));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ public class ActionStop extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
output.add(new StopActionItem(this, lineStartAction));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ public class ActionStopSounds extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
output.add(new StopAllSoundsActionItem(this, lineStartAction));
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -48,7 +48,7 @@ public class ActionToggleQuality extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
output.add(new ToggleHighQualityActionItem(this, lineStartAction));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
*/
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.swf3;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
@@ -99,9 +100,9 @@ public class ActionWaitForFrame extends Action implements ActionStore {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) throws InterruptedException {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, 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, null, 0, new Long(frame), new ArrayList<>());
|
||||
List<GraphTargetItem> body = ActionGraph.translateViaGraph(regNames, variables, functions, skipped, SWF.DEFAULT_VERSION, staticOperation, path);
|
||||
List<GraphTargetItem> body = ActionGraph.translateViaGraph(insideDoInitAction, regNames, variables, functions, skipped, SWF.DEFAULT_VERSION, staticOperation, path);
|
||||
output.add(new IfFrameLoadedActionItem(frameTi, body, this, lineStartAction));
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
*/
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.swf4;
|
||||
|
||||
import com.jpexs.decompiler.flash.BaseLocalData;
|
||||
@@ -53,7 +54,7 @@ public class ActionAdd extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
GraphTargetItem a = stack.pop();
|
||||
GraphTargetItem b = stack.pop();
|
||||
stack.push(new AddActionItem(this, lineStartAction, b, a, false));
|
||||
|
||||
@@ -53,7 +53,7 @@ public class ActionAnd extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
GraphTargetItem a = stack.pop();
|
||||
GraphTargetItem b = stack.pop();
|
||||
stack.push(new AndActionItem(this, lineStartAction, b, a));
|
||||
|
||||
@@ -53,7 +53,7 @@ public class ActionAsciiToChar extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
GraphTargetItem a = stack.pop();
|
||||
stack.push(new AsciiToCharActionItem(this, lineStartAction, a));
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ public class ActionCall extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
output.add(new CallActionItem(this, lineStartAction, stack.pop()));
|
||||
}
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ public class ActionCharToAscii extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
GraphTargetItem a = stack.pop();
|
||||
stack.push(new CharToAsciiActionItem(this, lineStartAction, a));
|
||||
}
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
*/
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.swf4;
|
||||
|
||||
import com.jpexs.decompiler.flash.BaseLocalData;
|
||||
@@ -21,6 +22,7 @@ import com.jpexs.decompiler.flash.action.ActionScriptObject;
|
||||
import com.jpexs.decompiler.flash.action.LocalDataArea;
|
||||
import com.jpexs.decompiler.flash.action.model.CloneSpriteActionItem;
|
||||
import com.jpexs.decompiler.flash.ecma.EcmaScript;
|
||||
import com.jpexs.decompiler.flash.ecma.Undefined;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFVersion;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
@@ -53,13 +55,16 @@ public class ActionCloneSprite extends Action {
|
||||
int depth = EcmaScript.toInt32(lda.stack.pop());
|
||||
String source = EcmaScript.toString(lda.stack.pop());
|
||||
String target = EcmaScript.toString(lda.stack.pop());
|
||||
lda.stage.setMember(target, ((ActionScriptObject) lda.stage.getMember(source)).clone());
|
||||
lda.stage.addToDisplayList(depth, lda.stage.getMember(target));
|
||||
Object clonedMember = lda.stage.getMember(source);
|
||||
if (clonedMember != Undefined.INSTANCE) {
|
||||
lda.stage.setMember(target, ((ActionScriptObject) clonedMember).clone());
|
||||
lda.stage.addToDisplayList(depth, lda.stage.getMember(target));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
GraphTargetItem depth = stack.pop();
|
||||
GraphTargetItem source = stack.pop();
|
||||
GraphTargetItem target = stack.pop();
|
||||
|
||||
@@ -53,7 +53,7 @@ public class ActionDivide extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
GraphTargetItem a = stack.pop();
|
||||
GraphTargetItem b = stack.pop();
|
||||
stack.push(new DivideActionItem(this, lineStartAction, b, a));
|
||||
|
||||
@@ -52,7 +52,7 @@ public class ActionEndDrag extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
output.add(new StopDragActionItem(this, lineStartAction));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ public class ActionEquals extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
GraphTargetItem a = stack.pop();
|
||||
GraphTargetItem b = stack.pop();
|
||||
stack.push(new EqActionItem(this, lineStartAction, b, a, false));
|
||||
|
||||
@@ -64,7 +64,7 @@ public class ActionGetProperty extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
GraphTargetItem index = stack.pop();
|
||||
GraphTargetItem target = stack.pop();
|
||||
int indexInt = 0;
|
||||
|
||||
@@ -49,7 +49,7 @@ public class ActionGetTime extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
stack.push(new GetTimeActionItem(this, lineStartAction));
|
||||
}
|
||||
|
||||
|
||||
@@ -124,7 +124,7 @@ public class ActionGetURL2 extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
GraphTargetItem targetString = stack.pop();
|
||||
GraphTargetItem urlString = stack.pop();
|
||||
Integer num = null;
|
||||
|
||||
@@ -64,7 +64,7 @@ public class ActionGetVariable extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
GraphTargetItem name = stack.pop();
|
||||
String nameStr;
|
||||
if (name instanceof DirectValueActionItem) {
|
||||
|
||||
@@ -143,7 +143,7 @@ public class ActionGotoFrame2 extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
GraphTargetItem frame = stack.pop();
|
||||
output.add(new GotoFrame2ActionItem(this, lineStartAction, frame, sceneBiasFlag, playFlag, sceneBias));
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ public class ActionLess extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
GraphTargetItem a = stack.pop();
|
||||
GraphTargetItem b = stack.pop();
|
||||
stack.push(new LtActionItem(this, lineStartAction, b, a, false));
|
||||
|
||||
+1
-1
@@ -53,7 +53,7 @@ public class ActionMBAsciiToChar extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
GraphTargetItem a = stack.pop();
|
||||
stack.push(new MBAsciiToCharActionItem(this, lineStartAction, a));
|
||||
}
|
||||
|
||||
+1
-1
@@ -53,7 +53,7 @@ public class ActionMBCharToAscii extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
GraphTargetItem a = stack.pop();
|
||||
stack.push(new MBCharToAsciiActionItem(this, lineStartAction, a));
|
||||
}
|
||||
|
||||
+1
-1
@@ -53,7 +53,7 @@ public class ActionMBStringExtract extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
GraphTargetItem count = stack.pop();
|
||||
GraphTargetItem index = stack.pop();
|
||||
GraphTargetItem value = stack.pop();
|
||||
|
||||
+1
-1
@@ -53,7 +53,7 @@ public class ActionMBStringLength extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
GraphTargetItem a = stack.pop();
|
||||
stack.push(new MBStringLengthActionItem(this, lineStartAction, a));
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ public class ActionMultiply extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
GraphTargetItem a = stack.pop();
|
||||
GraphTargetItem b = stack.pop();
|
||||
stack.push(new MultiplyActionItem(this, lineStartAction, b, a));
|
||||
|
||||
@@ -53,7 +53,7 @@ public class ActionNot extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
GraphTargetItem a = stack.pop();
|
||||
stack.push(a.invert(this));
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ public class ActionOr extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
GraphTargetItem a = stack.pop();
|
||||
GraphTargetItem b = stack.pop();
|
||||
stack.push(new OrActionItem(this, lineStartAction, b, a));
|
||||
|
||||
@@ -52,7 +52,7 @@ public class ActionPop extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
GraphTargetItem val = stack.pop();
|
||||
output.add(val);
|
||||
}
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
*/
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.swf4;
|
||||
|
||||
import com.jpexs.decompiler.flash.BaseLocalData;
|
||||
@@ -62,6 +63,12 @@ public class ActionPush extends Action {
|
||||
|
||||
public List<String> constantPool;
|
||||
|
||||
/**
|
||||
* Maximum constant index for storing in type 8, greater indices must be
|
||||
* stored in type 9
|
||||
*/
|
||||
public static final int MAX_CONSTANT_INDEX_TYPE8 = 255;
|
||||
|
||||
public ActionPush(int actionLength, SWFInputStream sis, int version) throws IOException {
|
||||
super(0x96, actionLength);
|
||||
int type;
|
||||
@@ -151,7 +158,7 @@ public class ActionPush extends Action {
|
||||
}
|
||||
} else if (o instanceof ConstantIndex) {
|
||||
int cIndex = ((ConstantIndex) o).index;
|
||||
if (cIndex < 256) {
|
||||
if (cIndex <= MAX_CONSTANT_INDEX_TYPE8) {
|
||||
sos.writeUI8(8);
|
||||
sos.writeUI8(cIndex);
|
||||
} else {
|
||||
@@ -382,7 +389,7 @@ public class ActionPush extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
int pos = 0;
|
||||
for (Object o : values) {
|
||||
if (o instanceof ConstantIndex) {
|
||||
|
||||
@@ -53,7 +53,7 @@ public class ActionRandomNumber extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
GraphTargetItem maximum = stack.pop();
|
||||
stack.push(new RandomNumberActionItem(this, lineStartAction, maximum));
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ public class ActionRemoveSprite extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
GraphTargetItem target = stack.pop();
|
||||
output.add(new RemoveSpriteActionItem(this, lineStartAction, target));
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ public class ActionSetProperty extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
GraphTargetItem value = stack.pop().getThroughDuplicate();
|
||||
GraphTargetItem index = stack.pop().getThroughDuplicate();
|
||||
GraphTargetItem target = stack.pop().getThroughDuplicate();
|
||||
|
||||
@@ -54,7 +54,7 @@ public class ActionSetTarget2 extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
GraphTargetItem target = stack.pop();
|
||||
output.add(new SetTarget2ActionItem(this, lineStartAction, target));
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ public class ActionSetVariable extends Action implements StoreTypeAction {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
GraphTargetItem value = stack.pop().getThroughDuplicate();
|
||||
GraphTargetItem name = stack.pop();
|
||||
String nameStr;
|
||||
|
||||
@@ -54,7 +54,7 @@ public class ActionStartDrag extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
GraphTargetItem target = stack.pop();
|
||||
GraphTargetItem lockCenter = stack.pop();
|
||||
GraphTargetItem constrain = stack.pop();
|
||||
|
||||
@@ -53,7 +53,7 @@ public class ActionStringAdd extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
GraphTargetItem a = stack.pop();
|
||||
GraphTargetItem b = stack.pop();
|
||||
stack.push(new StringAddActionItem(this, lineStartAction, b, a));
|
||||
|
||||
@@ -53,7 +53,7 @@ public class ActionStringEquals extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
GraphTargetItem a = stack.pop();
|
||||
GraphTargetItem b = stack.pop();
|
||||
stack.push(new StringEqActionItem(this, lineStartAction, b, a));
|
||||
|
||||
+1
-1
@@ -53,7 +53,7 @@ public class ActionStringExtract extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
GraphTargetItem count = stack.pop();
|
||||
GraphTargetItem index = stack.pop();
|
||||
GraphTargetItem value = stack.pop();
|
||||
|
||||
@@ -53,7 +53,7 @@ public class ActionStringLength extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
GraphTargetItem a = stack.pop();
|
||||
stack.push(new StringLengthActionItem(this, lineStartAction, a));
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ public class ActionStringLess extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
GraphTargetItem a = stack.pop();
|
||||
GraphTargetItem b = stack.pop();
|
||||
stack.push(new StringLtActionItem(this, lineStartAction, b, a));
|
||||
|
||||
@@ -53,7 +53,7 @@ public class ActionSubtract extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
GraphTargetItem a = stack.pop();
|
||||
GraphTargetItem b = stack.pop();
|
||||
stack.push(new SubtractActionItem(this, lineStartAction, b, a));
|
||||
|
||||
@@ -53,7 +53,7 @@ public class ActionToInteger extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
GraphTargetItem a = stack.pop();
|
||||
stack.push(new ToIntegerActionItem(this, lineStartAction, a));
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ public class ActionTrace extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
GraphTargetItem value = stack.pop();
|
||||
output.add(new TraceActionItem(this, lineStartAction, value));
|
||||
}
|
||||
|
||||
+4
-3
@@ -12,7 +12,8 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
*/
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.swf4;
|
||||
|
||||
import com.jpexs.decompiler.flash.BaseLocalData;
|
||||
@@ -145,9 +146,9 @@ public class ActionWaitForFrame2 extends Action implements ActionStore {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) throws InterruptedException {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, 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);
|
||||
List<GraphTargetItem> body = ActionGraph.translateViaGraph(insideDoInitAction, regNames, variables, functions, skipped, SWF.DEFAULT_VERSION, staticOperation, path);
|
||||
output.add(new IfFrameLoadedActionItem(frame, body, this, lineStartAction));
|
||||
}
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ public class ActionAdd2 extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
GraphTargetItem a = stack.pop();
|
||||
GraphTargetItem b = stack.pop();
|
||||
stack.push(new AddActionItem(this, lineStartAction, b, a, true));
|
||||
|
||||
@@ -53,7 +53,7 @@ public class ActionBitAnd extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
GraphTargetItem a = stack.pop();
|
||||
GraphTargetItem b = stack.pop();
|
||||
stack.push(new BitAndActionItem(this, lineStartAction, b, a));
|
||||
|
||||
@@ -53,7 +53,7 @@ public class ActionBitLShift extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
GraphTargetItem a = stack.pop();
|
||||
GraphTargetItem b = stack.pop();
|
||||
stack.push(new LShiftActionItem(this, lineStartAction, b, a));
|
||||
|
||||
@@ -53,7 +53,7 @@ public class ActionBitOr extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
GraphTargetItem a = stack.pop();
|
||||
GraphTargetItem b = stack.pop();
|
||||
stack.push(new BitOrActionItem(this, lineStartAction, b, a));
|
||||
|
||||
@@ -53,7 +53,7 @@ public class ActionBitRShift extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
public void translate(boolean insideDoInitAction, GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
GraphTargetItem a = stack.pop();
|
||||
GraphTargetItem b = stack.pop();
|
||||
stack.push(new RShiftActionItem(this, lineStartAction, b, a));
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user