Issue #153 Better deobfuscation

This commit is contained in:
Jindra Pet��k
2013-07-07 22:50:09 +02:00
parent cff3ca6899
commit 82f1d5fcde
102 changed files with 1067 additions and 518 deletions
+130 -19
View File
@@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash;
import SevenZip.Compression.LZMA.Encoder;
import com.jpexs.decompiler.flash.abc.ABC;
import com.jpexs.decompiler.flash.abc.ClassPath;
import com.jpexs.decompiler.flash.abc.RenameType;
import com.jpexs.decompiler.flash.abc.ScriptPack;
import com.jpexs.decompiler.flash.action.Action;
@@ -28,7 +29,6 @@ import com.jpexs.decompiler.flash.action.swf4.ActionIf;
import com.jpexs.decompiler.flash.action.swf4.ActionPush;
import com.jpexs.decompiler.flash.action.swf4.ActionSetVariable;
import com.jpexs.decompiler.flash.action.swf4.ConstantIndex;
import com.jpexs.decompiler.flash.action.swf4.Null;
import com.jpexs.decompiler.flash.action.swf5.ActionCallFunction;
import com.jpexs.decompiler.flash.action.swf5.ActionCallMethod;
import com.jpexs.decompiler.flash.action.swf5.ActionConstantPool;
@@ -48,6 +48,7 @@ import com.jpexs.decompiler.flash.action.treemodel.GetMemberTreeItem;
import com.jpexs.decompiler.flash.action.treemodel.GetVariableTreeItem;
import com.jpexs.decompiler.flash.action.treemodel.clauses.ClassTreeItem;
import com.jpexs.decompiler.flash.action.treemodel.clauses.InterfaceTreeItem;
import com.jpexs.decompiler.flash.ecma.Null;
import com.jpexs.decompiler.flash.flv.AUDIODATA;
import com.jpexs.decompiler.flash.flv.FLVOutputStream;
import com.jpexs.decompiler.flash.flv.FLVTAG;
@@ -113,6 +114,13 @@ import java.util.Locale;
import java.util.Map;
import java.util.Random;
import java.util.Stack;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;
@@ -492,6 +500,123 @@ public class SWF {
return false;
}
private List<KeyValue<ClassPath, ScriptPack>> uniqueAS3Packs(List<KeyValue<ClassPath, ScriptPack>> packs) {
List<KeyValue<ClassPath, ScriptPack>> ret = new ArrayList<>();
for (KeyValue<ClassPath, ScriptPack> item : packs) {
System.err.println(item.key);
for (KeyValue<ClassPath, ScriptPack> itemOld : ret) {
if (item.key.equals(itemOld.key)) {
Logger.getLogger(SWF.class.getName()).log(Level.SEVERE, "Duplicate pack path found!");
break;
}
}
ret.add(item);
}
return ret;
}
public List<KeyValue<ClassPath, ScriptPack>> getAS3Packs() {
List<ABCContainerTag> abcTags = new ArrayList<>();
for (Tag t : tags) {
if (t instanceof ABCContainerTag) {
abcTags.add((ABCContainerTag) t);
}
}
List<KeyValue<ClassPath, ScriptPack>> packs = new ArrayList<>();
for (int i = 0; i < abcTags.size(); i++) {
ABCContainerTag t = abcTags.get(i);
packs.addAll(t.getABC().getScriptPacks());
}
return uniqueAS3Packs(packs);
}
private class ExportPackTask implements Callable<File> {
ScriptPack pack;
String directory;
List<ABCContainerTag> abcList;
boolean pcode;
String informStr;
ClassPath path;
AtomicInteger index;
int count;
boolean paralel;
public ExportPackTask(AtomicInteger index, int count, ClassPath path, ScriptPack pack, String directory, List<ABCContainerTag> abcList, boolean pcode, String informStr, boolean paralel) {
this.pack = pack;
this.directory = directory;
this.abcList = abcList;
this.pcode = pcode;
this.informStr = informStr;
this.path = path;
this.index = index;
this.count = count;
this.paralel = paralel;
}
@Override
public File call() throws Exception {
try {
return pack.export(directory, abcList, pcode, paralel);
} catch (IOException ex) {
Logger.getLogger(ABC.class.getName()).log(Level.SEVERE, null, ex);
}
synchronized (ABC.class) {
informListeners("export", "Exported " + informStr + " script " + index.getAndIncrement() + "/" + count + " " + path);
}
return null;
}
}
public List<File> exportActionScript2(String outdir, boolean isPcode, boolean paralel, EventListener evl) {
List<File> ret = new ArrayList<>();
List<Object> list2 = new ArrayList<>();
list2.addAll(tags);
List<TagNode> list = createASTagList(list2, null);
TagNode.setExport(list, true);
if (!outdir.endsWith(File.separator)) {
outdir += File.separator;
}
outdir += "scripts" + File.separator;
ret.addAll(TagNode.exportNodeAS(list, outdir, isPcode, evl));
return ret;
}
public List<File> exportActionScript3(String outdir, boolean isPcode, boolean paralel) {
ExecutorService executor = Executors.newFixedThreadPool(20);
List<Future<File>> futureResults = new ArrayList<>();
AtomicInteger cnt = new AtomicInteger(1);
List<ABCContainerTag> abcTags = new ArrayList<>();
for (Tag t : tags) {
if (t instanceof ABCContainerTag) {
abcTags.add((ABCContainerTag) t);
}
}
List<KeyValue<ClassPath, ScriptPack>> packs = getAS3Packs();
for (KeyValue<ClassPath, ScriptPack> item : packs) {
Future<File> future = executor.submit(new ExportPackTask(cnt, packs.size(), item.key, item.value, outdir, abcTags, isPcode, "", paralel));
futureResults.add(future);
}
List<File> ret = new ArrayList<>();
for (int f = 0; f < futureResults.size(); f++) {
try {
ret.add(futureResults.get(f).get());
} catch (InterruptedException | ExecutionException ex) {
Logger.getLogger(SWF.class.getName()).log(Level.SEVERE, "Error during ABC export", ex);
}
}
try {
executor.shutdown();
executor.awaitTermination(30, TimeUnit.MINUTES);
} catch (InterruptedException ex) {
Logger.getLogger(ABC.class.getName()).log(Level.SEVERE, "30 minutes ActionScript export limit reached", ex);
}
return ret;
}
public List<File> exportActionScript(String outdir, boolean isPcode, boolean paralel) throws Exception {
boolean asV3Found = false;
List<File> ret = new ArrayList<>();
@@ -503,30 +628,16 @@ public class SWF {
}
}
};
List<ABCContainerTag> abcTags = new ArrayList<>();
for (Tag t : tags) {
if (t instanceof ABCContainerTag) {
abcTags.add((ABCContainerTag) t);
asV3Found = true;
}
}
for (int i = 0; i < abcTags.size(); i++) {
ABCContainerTag t = abcTags.get(i);
t.getABC().addEventListener(evl);
ret.addAll(t.getABC().export(outdir, isPcode, abcTags, "tag " + (i + 1) + "/" + abcTags.size() + " ", paralel));
}
if (!asV3Found) {
List<Object> list2 = new ArrayList<>();
list2.addAll(tags);
List<TagNode> list = createASTagList(list2, null);
TagNode.setExport(list, true);
if (!outdir.endsWith(File.separator)) {
outdir += File.separator;
}
outdir += "scripts" + File.separator;
ret.addAll(TagNode.exportNodeAS(list, outdir, isPcode, evl));
if (asV3Found) {
ret.addAll(exportActionScript3(outdir, isPcode, paralel));
} else {
ret.addAll(exportActionScript2(outdir, isPcode, paralel, evl));
}
return ret;
}
@@ -28,6 +28,8 @@ import com.jpexs.decompiler.flash.action.swf6.*;
import com.jpexs.decompiler.flash.action.swf7.*;
import com.jpexs.decompiler.flash.action.treemodel.ConstantPool;
import com.jpexs.decompiler.flash.action.treemodel.DirectValueTreeItem;
import com.jpexs.decompiler.flash.ecma.EcmaScript;
import com.jpexs.decompiler.flash.ecma.Null;
import com.jpexs.decompiler.flash.graph.GraphSourceItem;
import com.jpexs.decompiler.flash.graph.GraphSourceItemContainer;
import com.jpexs.decompiler.flash.graph.GraphSourceItemPos;
@@ -658,7 +660,7 @@ public class SWFInputStream extends InputStream {
}
}
}
boolean condition = stack.peek().toBoolean();
boolean condition = EcmaScript.toBoolean(stack.peek().getResult());
if (debugMode) {
if (condition) {
System.err.println("JUMP");
@@ -945,7 +947,7 @@ public class SWFInputStream extends InputStream {
if (debugMode) {
System.err.print("is compiletime -> ");
}
if (top.toBoolean()) {
if (EcmaScript.toBoolean(top.getResult())) {
newip = rri.getPos() + aif.getJumpOffset();
//rri.setPos(newip);
if (((!enableVariables) || (!top.isVariableComputed())) && (!aif.ignoreUsed)) {
@@ -1156,7 +1158,11 @@ public class SWFInputStream extends InputStream {
@Override
public Tag call() throws Exception {
return SWFInputStream.resolveTag(tag, version, level, paralel);
try {
return SWFInputStream.resolveTag(tag, version, level, paralel);
} catch (Exception ex) {
return null;
}
}
}
@@ -17,6 +17,7 @@
package com.jpexs.decompiler.flash.abc;
import com.jpexs.decompiler.flash.EventListener;
import com.jpexs.decompiler.flash.KeyValue;
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
import com.jpexs.decompiler.flash.abc.avm2.UnknownInstructionCode;
@@ -31,7 +32,6 @@ import com.jpexs.decompiler.flash.abc.types.traits.TraitMethodGetterSetter;
import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst;
import com.jpexs.decompiler.flash.abc.types.traits.Traits;
import com.jpexs.decompiler.flash.abc.usages.*;
import com.jpexs.decompiler.flash.tags.ABCContainerTag;
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
@@ -39,16 +39,8 @@ import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;
@@ -711,77 +703,45 @@ public class ABC {
}
}
public void export(String directory, boolean pcode, List<ABCContainerTag> abcList, boolean paralel) throws IOException {
export(directory, pcode, abcList, "", paralel);
}
private class ExportPackTask implements Callable<File> {
ScriptPack pack;
String directory;
List<ABCContainerTag> abcList;
boolean pcode;
String informStr;
ClassPath path;
AtomicInteger index;
int count;
boolean paralel;
public ExportPackTask(AtomicInteger index, int count, ClassPath path, ScriptPack pack, String directory, List<ABCContainerTag> abcList, boolean pcode, String informStr, boolean paralel) {
this.pack = pack;
this.directory = directory;
this.abcList = abcList;
this.pcode = pcode;
this.informStr = informStr;
this.path = path;
this.index = index;
this.count = count;
this.paralel = paralel;
}
@Override
public File call() throws Exception {
try {
return pack.export(directory, abcList, pcode, paralel);
} catch (IOException ex) {
Logger.getLogger(ABC.class.getName()).log(Level.SEVERE, null, ex);
}
synchronized (ABC.class) {
informListeners("export", "Exported " + informStr + " script " + index.getAndIncrement() + "/" + count + " " + path);
}
return null;
}
}
public List<File> export(String directory, boolean pcode, List<ABCContainerTag> abcList, String abcStr, boolean paralel) throws IOException {
ExecutorService executor = Executors.newFixedThreadPool(20);
List<Future<File>> futureResults = new ArrayList<>();
AtomicInteger cnt = new AtomicInteger(1);
/*public void export(String directory, boolean pcode, List<ABCContainerTag> abcList, boolean paralel) throws IOException {
export(directory, pcode, abcList, "", paralel);
}*/
public List<KeyValue<ClassPath, ScriptPack>> getScriptPacks() {
List<KeyValue<ClassPath, ScriptPack>> ret = new ArrayList<>();
for (int i = 0; i < script_info.length; i++) {
HashMap<ClassPath, ScriptPack> packs = script_info[i].getPacks(this, i);
for (Entry<ClassPath, ScriptPack> entry : packs.entrySet()) {
Future<File> future = executor.submit(new ExportPackTask(cnt, script_info.length, entry.getKey(), entry.getValue(), directory, abcList, pcode, abcStr, paralel));
futureResults.add(future);
}
}
List<File> ret = new ArrayList<>();
for (int f = 0; f < futureResults.size(); f++) {
try {
ret.add(futureResults.get(f).get());
} catch (InterruptedException | ExecutionException ex) {
Logger.getLogger(Traits.class.getName()).log(Level.SEVERE, "Error during ABC export", ex);
}
}
try {
executor.shutdown();
executor.awaitTermination(30, TimeUnit.MINUTES);
} catch (InterruptedException ex) {
Logger.getLogger(ABC.class.getName()).log(Level.SEVERE, "30 minutes ActionScript export limit reached", ex);
ret.addAll(script_info[i].getPacks(this, i));
}
return ret;
}
/*public List<File> export(String directory, boolean pcode, List<ABCContainerTag> abcList, String abcStr, boolean paralel) throws IOException {
ExecutorService executor = Executors.newFixedThreadPool(20);
List<Future<File>> futureResults = new ArrayList<>();
AtomicInteger cnt = new AtomicInteger(1);
for (int i = 0; i < script_info.length; i++) {
HashMap<ClassPath, ScriptPack> packs = script_info[i].getPacks(this, i);
for (Entry<ClassPath, ScriptPack> entry : packs.entrySet()) {
Future<File> future = executor.submit(new ExportPackTask(cnt, script_info.length, entry.getKey(), entry.getValue(), directory, abcList, pcode, abcStr, paralel));
futureResults.add(future);
}
}
List<File> ret = new ArrayList<>();
for (int f = 0; f < futureResults.size(); f++) {
try {
ret.add(futureResults.get(f).get());
} catch (InterruptedException | ExecutionException ex) {
Logger.getLogger(Traits.class.getName()).log(Level.SEVERE, "Error during ABC export", ex);
}
}
try {
executor.shutdown();
executor.awaitTermination(30, TimeUnit.MINUTES);
} catch (InterruptedException ex) {
Logger.getLogger(ABC.class.getName()).log(Level.SEVERE, "30 minutes ActionScript export limit reached", ex);
}
return ret;
}*/
public void dump(OutputStream os) {
PrintStream output;
@@ -16,6 +16,8 @@
*/
package com.jpexs.decompiler.flash.abc;
import java.util.Objects;
/**
*
* @author JPEXS
@@ -34,4 +36,30 @@ public class ClassPath {
public String toString() {
return (packageStr == null || packageStr.equals("")) ? className : packageStr + "." + className;
}
@Override
public int hashCode() {
int hash = 7;
hash = 37 * hash + Objects.hashCode(this.packageStr);
hash = 37 * hash + Objects.hashCode(this.className);
return hash;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final ClassPath other = (ClassPath) obj;
if (!Objects.equals(this.packageStr, other.packageStr)) {
return false;
}
if (!Objects.equals(this.className, other.className)) {
return false;
}
return true;
}
}
@@ -54,6 +54,7 @@ import com.jpexs.decompiler.flash.abc.types.Multiname;
import com.jpexs.decompiler.flash.abc.types.traits.Trait;
import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst;
import com.jpexs.decompiler.flash.abc.types.traits.Traits;
import com.jpexs.decompiler.flash.ecma.EcmaScript;
import com.jpexs.decompiler.flash.graph.Graph;
import com.jpexs.decompiler.flash.graph.GraphPart;
import com.jpexs.decompiler.flash.graph.GraphSourceItem;
@@ -2030,7 +2031,7 @@ public class AVM2Code implements Serializable {
List<Integer> branches = ins.getBranches(code);
if ((ins instanceof AVM2Instruction) && (((AVM2Instruction) ins).definition instanceof LookupSwitchIns)
&& (!stack.isEmpty()) && (stack.peek().isCompileTime()) && (!stack.peek().hasSideEffect())) {
int c = (int) stack.peek().toNumber();
int c = (int) (double) EcmaScript.toNumber(stack.peek().getResult());
Decision dec = new Decision();
if (decisions.containsKey(ins)) {
dec = decisions.get(ins);
@@ -2076,7 +2077,7 @@ public class AVM2Code implements Serializable {
continue;
} else if ((ins instanceof AVM2Instruction) && ((AVM2Instruction) ins).definition instanceof IfTypeIns
&& (!(((AVM2Instruction) ins).definition instanceof JumpIns)) && (!stack.isEmpty()) && (stack.peek().isCompileTime()) && (!stack.peek().hasSideEffect())) {
boolean condition = stack.peek().toBoolean();
boolean condition = EcmaScript.toBoolean(stack.peek().getResult());
if (debugMode) {
if (condition) {
System.out.println("JUMP");
@@ -46,15 +46,10 @@ public class BooleanTreeItem extends TreeItem {
}
@Override
public boolean toBoolean() {
public Object getResult() {
return value;
}
@Override
public double toNumber() {
return value ? 1 : 0;
}
@Override
public boolean isCompileTime() {
return true;
@@ -18,6 +18,8 @@ package com.jpexs.decompiler.flash.abc.avm2.treemodel;
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.ecma.Null;
import com.jpexs.decompiler.flash.ecma.Undefined;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
import java.util.HashMap;
import java.util.List;
@@ -43,4 +45,28 @@ public class CoerceTreeItem extends TreeItem {
public GraphTargetItem getNotCoerced() {
return value.getNotCoerced();
}
@Override
public boolean isCompileTime() {
return value.isCompileTime();
}
@Override
public Object getResult() {
Object ret = value.getResult();
switch (type) {
case "String":
if (ret instanceof Null) {
return ret;
}
if (ret instanceof Undefined) {
return new Null();
}
return ret.toString();
case "*":
break;
}
return ret;
}
}
@@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.abc.avm2.treemodel;
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.ecma.EcmaScript;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
import java.util.HashMap;
import java.util.List;
@@ -44,77 +45,27 @@ public class ConvertTreeItem extends TreeItem {
}
@Override
public double toNumber() {
return toBoolean() ? 1 : 0;
}
@Override
public boolean toBoolean() {
if (type.contains("Boolean")) {
if (value instanceof UndefinedTreeItem) {
return false;
}
if (value instanceof NullTreeItem) {
return false;
}
if (value instanceof BooleanTreeItem) {
return ((BooleanTreeItem) value).value;
}
if (value instanceof IntegerValueTreeItem) {
IntegerValueTreeItem iv = (IntegerValueTreeItem) value;
return iv.value != 0;
}
if (value instanceof FloatValueTreeItem) {
FloatValueTreeItem fv = (FloatValueTreeItem) value;
return !(fv.value == 0 || fv.value.isNaN());
}
if (value instanceof StringTreeItem) {
StringTreeItem sv = (StringTreeItem) value;
return !sv.value.equals("");
}
if (value instanceof ThisTreeItem) {
return true;
}
if (value instanceof ClassTreeItem) {
return true;
}
//object
return false;
public Object getResult() {
switch (type) {
case "Boolean":
return EcmaScript.toBoolean(value.getResult());
case "Number":
return EcmaScript.toNumber(value.getResult());
case "int":
return (int) (double) EcmaScript.toNumber(value.getResult());
case "uint":
return (int) (double) EcmaScript.toUint32(value.getResult());
case "String":
return value.getResult().toString();
case "Object":
return value.getResult(); //if not object throw TypeError
default:
return new Object();
}
return false;
}
@Override
public boolean isCompileTime() {
if (type.contains("Boolean")) {
if (value instanceof UndefinedTreeItem) {
return true;
}
if (value instanceof NullTreeItem) {
return true;
}
if (value instanceof BooleanTreeItem) {
return true;
}
if (value instanceof IntegerValueTreeItem) {
return true;
}
if (value instanceof FloatValueTreeItem) {
return true;
}
if (value instanceof StringTreeItem) {
return true;
}
if (value instanceof ThisTreeItem) {
return true;
}
if (value instanceof ClassTreeItem) {
return true;
}
//object
return false;
}
return false;
return value.isCompileTime();
}
}
@@ -36,7 +36,7 @@ public class FloatValueTreeItem extends NumberValueTreeItem {
}
@Override
public double toNumber() {
public Object getResult() {
return value;
}
@@ -36,8 +36,8 @@ public class IntegerValueTreeItem extends NumberValueTreeItem {
}
@Override
public double toNumber() {
return value;
public Object getResult() {
return (Double) (double) (long) value;
}
@Override
@@ -19,6 +19,7 @@ package com.jpexs.decompiler.flash.abc.avm2.treemodel;
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.abc.avm2.treemodel.clauses.FilterTreeItem;
import com.jpexs.decompiler.flash.ecma.Undefined;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
import com.jpexs.decompiler.flash.helpers.Helper;
import java.util.HashMap;
@@ -55,19 +56,12 @@ public class LocalRegTreeItem extends TreeItem {
}
@Override
public double toNumber() {
public Object getResult() {
if (computedValue == null) {
return 0;
return new Undefined();
}
return computedValue.toNumber();
}
return computedValue.getResult();
@Override
public boolean toBoolean() {
if (computedValue == null) {
return false;
}
return computedValue.toBoolean();
}
@Override
@@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.abc.avm2.treemodel;
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.ecma.Null;
import java.util.HashMap;
import java.util.List;
@@ -38,12 +39,7 @@ public class NullTreeItem extends TreeItem {
}
@Override
public double toNumber() {
return 0;
}
@Override
public boolean toBoolean() {
return false;
public Object getResult() {
return new Null();
}
}
@@ -35,4 +35,14 @@ public class StringTreeItem extends TreeItem {
public String toString(ConstantPool constants, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
return hilight("\"" + Helper.escapeString(value) + "\"");
}
@Override
public boolean isCompileTime() {
return true;
}
@Override
public Object getResult() {
return value;
}
}
@@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.abc.avm2.treemodel;
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.ecma.Undefined;
import java.util.HashMap;
import java.util.List;
@@ -38,12 +39,7 @@ public class UndefinedTreeItem extends TreeItem {
}
@Override
public double toNumber() {
return 0;
}
@Override
public boolean toBoolean() {
return false;
public Object getResult() {
return new Undefined();
}
}
@@ -17,6 +17,8 @@
package com.jpexs.decompiler.flash.abc.avm2.treemodel.operations;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.ecma.EcmaScript;
import com.jpexs.decompiler.flash.ecma.EcmaType;
import com.jpexs.decompiler.flash.graph.BinaryOpItem;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
import java.util.List;
@@ -45,7 +47,10 @@ public class AddTreeItem extends BinaryOpItem {
}
@Override
public double toNumber() {
return leftSide.toNumber() + rightSide.toNumber();
public Object getResult() {
if (EcmaScript.type(leftSide.getResult()) == EcmaType.STRING || EcmaScript.type(rightSide.getResult()) == EcmaType.STRING) {
return leftSide.getResult().toString() + rightSide.getResult().toString();
}
return EcmaScript.toNumber(leftSide.getResult()) + EcmaScript.toNumber(rightSide.getResult());
}
}
@@ -17,6 +17,7 @@
package com.jpexs.decompiler.flash.abc.avm2.treemodel.operations;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.ecma.EcmaScript;
import com.jpexs.decompiler.flash.graph.BinaryOpItem;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
@@ -27,7 +28,7 @@ public class BitAndTreeItem extends BinaryOpItem {
}
@Override
public double toNumber() {
return ((int) leftSide.toNumber()) & ((int) rightSide.toNumber());
public Object getResult() {
return ((long) (double) EcmaScript.toNumber(leftSide.getResult())) & ((long) (double) EcmaScript.toNumber(rightSide.getResult()));
}
}
@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.abc.avm2.treemodel.operations;
import com.jpexs.decompiler.flash.ecma.EcmaScript;
import com.jpexs.decompiler.flash.graph.GraphSourceItem;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
import com.jpexs.decompiler.flash.graph.UnaryOpItem;
@@ -27,7 +28,7 @@ public class BitNotTreeItem extends UnaryOpItem {
}
@Override
public double toNumber() {
return ~((int) value.toNumber());
public Object getResult() {
return ~((long) (double) EcmaScript.toNumber(value.getResult()));
}
}
@@ -17,6 +17,7 @@
package com.jpexs.decompiler.flash.abc.avm2.treemodel.operations;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.ecma.EcmaScript;
import com.jpexs.decompiler.flash.graph.BinaryOpItem;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
@@ -27,7 +28,7 @@ public class BitOrTreeItem extends BinaryOpItem {
}
@Override
public double toNumber() {
return ((int) leftSide.toNumber()) | ((int) rightSide.toNumber());
public Object getResult() {
return ((long) (double) EcmaScript.toNumber(leftSide.getResult())) | ((long) (double) EcmaScript.toNumber(rightSide.getResult()));
}
}
@@ -17,6 +17,7 @@
package com.jpexs.decompiler.flash.abc.avm2.treemodel.operations;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.ecma.EcmaScript;
import com.jpexs.decompiler.flash.graph.BinaryOpItem;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
@@ -27,7 +28,7 @@ public class BitXorTreeItem extends BinaryOpItem {
}
@Override
public double toNumber() {
return ((int) leftSide.toNumber()) ^ ((int) rightSide.toNumber());
public Object getResult() {
return ((long) (double) EcmaScript.toNumber(leftSide.getResult())) ^ ((long) (double) EcmaScript.toNumber(rightSide.getResult()));
}
}
@@ -17,6 +17,7 @@
package com.jpexs.decompiler.flash.abc.avm2.treemodel.operations;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.ecma.EcmaScript;
import com.jpexs.decompiler.flash.graph.BinaryOpItem;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
@@ -27,10 +28,10 @@ public class DivideTreeItem extends BinaryOpItem {
}
@Override
public double toNumber() {
if (Double.compare(rightSide.toNumber(), 0) == 0) {
public Object getResult() {
if (Double.compare(EcmaScript.toNumber(rightSide.getResult()), 0) == 0) {
return Double.NaN;
}
return leftSide.toNumber() / rightSide.toNumber();
return (EcmaScript.toNumber(leftSide.getResult())) / (EcmaScript.toNumber(rightSide.getResult()));
}
}
@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.abc.avm2.treemodel.operations;
import com.jpexs.decompiler.flash.ecma.EcmaScript;
import com.jpexs.decompiler.flash.graph.BinaryOpItem;
import com.jpexs.decompiler.flash.graph.GraphSourceItem;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
@@ -28,8 +29,8 @@ public class EqTreeItem extends BinaryOpItem implements LogicalOpItem {
}
@Override
public boolean toBoolean() {
return (leftSide.toBoolean() == rightSide.toBoolean()) && (leftSide.toNumber() == rightSide.toNumber());
public Object getResult() {
return EcmaScript.equals(leftSide.getResult(), rightSide.getResult());
}
@Override
@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.abc.avm2.treemodel.operations;
import com.jpexs.decompiler.flash.ecma.EcmaScript;
import com.jpexs.decompiler.flash.graph.BinaryOpItem;
import com.jpexs.decompiler.flash.graph.GraphSourceItem;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
@@ -33,7 +34,14 @@ public class GeTreeItem extends BinaryOpItem implements LogicalOpItem {
}
@Override
public boolean toBoolean() {
return leftSide.toNumber() >= rightSide.toNumber();
public Object getResult() {
Object ret = EcmaScript.compare(leftSide.getResult(), rightSide.getResult());
if (ret == Boolean.TRUE) {
return Boolean.FALSE;
}
if (ret == Boolean.FALSE) {
return Boolean.TRUE;
}
return ret;//undefined
}
}
@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.abc.avm2.treemodel.operations;
import com.jpexs.decompiler.flash.ecma.EcmaScript;
import com.jpexs.decompiler.flash.graph.BinaryOpItem;
import com.jpexs.decompiler.flash.graph.GraphSourceItem;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
@@ -33,7 +34,7 @@ public class GtTreeItem extends BinaryOpItem implements LogicalOpItem {
}
@Override
public boolean toBoolean() {
return leftSide.toNumber() > rightSide.toNumber();
public Object getResult() {
return EcmaScript.compare(rightSide.getResult(), leftSide.getResult());
}
}
@@ -17,6 +17,7 @@
package com.jpexs.decompiler.flash.abc.avm2.treemodel.operations;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.ecma.EcmaScript;
import com.jpexs.decompiler.flash.graph.BinaryOpItem;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
@@ -27,7 +28,7 @@ public class LShiftTreeItem extends BinaryOpItem {
}
@Override
public double toNumber() {
return ((int) leftSide.toNumber()) << ((int) rightSide.toNumber());
public Object getResult() {
return ((int) (double) EcmaScript.toNumber(leftSide.getResult())) << ((int) (double) EcmaScript.toNumber(rightSide.getResult()));
}
}
@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.abc.avm2.treemodel.operations;
import com.jpexs.decompiler.flash.ecma.EcmaScript;
import com.jpexs.decompiler.flash.graph.BinaryOpItem;
import com.jpexs.decompiler.flash.graph.GraphSourceItem;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
@@ -33,7 +34,14 @@ public class LeTreeItem extends BinaryOpItem implements LogicalOpItem {
}
@Override
public boolean toBoolean() {
return leftSide.toNumber() <= rightSide.toNumber();
public Object getResult() {
Object ret = EcmaScript.compare(rightSide.getResult(), leftSide.getResult());
if (ret == Boolean.TRUE) {
return Boolean.FALSE;
}
if (ret == Boolean.FALSE) {
return Boolean.TRUE;
}
return ret;//undefined
}
}
@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.abc.avm2.treemodel.operations;
import com.jpexs.decompiler.flash.ecma.EcmaScript;
import com.jpexs.decompiler.flash.graph.BinaryOpItem;
import com.jpexs.decompiler.flash.graph.GraphSourceItem;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
@@ -33,7 +34,7 @@ public class LtTreeItem extends BinaryOpItem implements LogicalOpItem {
}
@Override
public boolean toBoolean() {
return leftSide.toNumber() < rightSide.toNumber();
public Object getResult() {
return EcmaScript.compare(leftSide.getResult(), rightSide.getResult());
}
}
@@ -17,6 +17,7 @@
package com.jpexs.decompiler.flash.abc.avm2.treemodel.operations;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.ecma.EcmaScript;
import com.jpexs.decompiler.flash.graph.BinaryOpItem;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
@@ -27,7 +28,10 @@ public class ModuloTreeItem extends BinaryOpItem {
}
@Override
public double toNumber() {
return ((int) leftSide.toNumber()) % ((int) rightSide.toNumber());
public Object getResult() {
if (Double.compare(EcmaScript.toNumber(rightSide.getResult()), 0) == 0) {
return Double.NaN;
}
return ((long) (double) EcmaScript.toNumber(leftSide.getResult())) % ((long) (double) EcmaScript.toNumber(rightSide.getResult()));
}
}
@@ -17,6 +17,7 @@
package com.jpexs.decompiler.flash.abc.avm2.treemodel.operations;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.ecma.EcmaScript;
import com.jpexs.decompiler.flash.graph.BinaryOpItem;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
@@ -27,7 +28,7 @@ public class MultiplyTreeItem extends BinaryOpItem {
}
@Override
public double toNumber() {
return leftSide.toNumber() * rightSide.toNumber();
public Object getResult() {
return (EcmaScript.toNumber(leftSide.getResult())) * (EcmaScript.toNumber(rightSide.getResult()));
}
}
@@ -17,6 +17,7 @@
package com.jpexs.decompiler.flash.abc.avm2.treemodel.operations;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.ecma.EcmaScript;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
import com.jpexs.decompiler.flash.graph.UnaryOpItem;
@@ -27,7 +28,7 @@ public class NegTreeItem extends UnaryOpItem {
}
@Override
public double toNumber() {
return -value.toNumber();
public Object getResult() {
return -EcmaScript.toNumber(value.getResult());
}
}
@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.abc.avm2.treemodel.operations;
import com.jpexs.decompiler.flash.ecma.EcmaScript;
import com.jpexs.decompiler.flash.graph.BinaryOpItem;
import com.jpexs.decompiler.flash.graph.GraphSourceItem;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
@@ -28,8 +29,8 @@ public class NeqTreeItem extends BinaryOpItem implements LogicalOpItem {
}
@Override
public boolean toBoolean() {
return (leftSide.toNumber() != rightSide.toNumber()) || (leftSide.toBoolean() != rightSide.toBoolean());
public Object getResult() {
return !EcmaScript.equals(leftSide.getResult(), rightSide.getResult());
}
@Override
@@ -17,6 +17,7 @@
package com.jpexs.decompiler.flash.abc.avm2.treemodel.operations;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.ecma.EcmaScript;
import com.jpexs.decompiler.flash.graph.BinaryOpItem;
import com.jpexs.decompiler.flash.graph.GraphPart;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
@@ -30,7 +31,7 @@ public class OrTreeItem extends BinaryOpItem {
}
@Override
public boolean toBoolean() {
return leftSide.toBoolean() || rightSide.toBoolean();
public Object getResult() {
return EcmaScript.toBoolean(leftSide.getResult()) || EcmaScript.toBoolean(rightSide.getResult());
}
}
@@ -17,6 +17,7 @@
package com.jpexs.decompiler.flash.abc.avm2.treemodel.operations;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.ecma.EcmaScript;
import com.jpexs.decompiler.flash.graph.BinaryOpItem;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
@@ -27,7 +28,7 @@ public class RShiftTreeItem extends BinaryOpItem {
}
@Override
public double toNumber() {
return ((int) leftSide.toNumber()) >> ((int) rightSide.toNumber());
public Object getResult() {
return ((long) (double) EcmaScript.toNumber(leftSide.getResult())) >> ((long) (double) EcmaScript.toNumber(rightSide.getResult()));
}
}
@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.abc.avm2.treemodel.operations;
import com.jpexs.decompiler.flash.ecma.EcmaScript;
import com.jpexs.decompiler.flash.graph.BinaryOpItem;
import com.jpexs.decompiler.flash.graph.GraphSourceItem;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
@@ -28,8 +29,11 @@ public class StrictEqTreeItem extends BinaryOpItem implements LogicalOpItem {
}
@Override
public boolean toBoolean() {
return (leftSide.toBoolean() == rightSide.toBoolean()) && (leftSide.toNumber() == rightSide.toNumber());
public Object getResult() {
Object x = leftSide.getResult();
Object y = rightSide.getResult();
return EcmaScript.type(x) == EcmaScript.type(y)
&& EcmaScript.equals(x, y);
}
@Override
@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.abc.avm2.treemodel.operations;
import com.jpexs.decompiler.flash.ecma.EcmaScript;
import com.jpexs.decompiler.flash.graph.BinaryOpItem;
import com.jpexs.decompiler.flash.graph.GraphSourceItem;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
@@ -33,7 +34,10 @@ public class StrictNeqTreeItem extends BinaryOpItem implements LogicalOpItem {
}
@Override
public boolean toBoolean() {
return !((leftSide.toBoolean() == rightSide.toBoolean()) && (leftSide.toNumber() == rightSide.toNumber()));
public Object getResult() {
Object x = leftSide.getResult();
Object y = rightSide.getResult();
return EcmaScript.type(x) != EcmaScript.type(y)
|| (!EcmaScript.equals(x, y));
}
}
@@ -17,6 +17,7 @@
package com.jpexs.decompiler.flash.abc.avm2.treemodel.operations;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.ecma.EcmaScript;
import com.jpexs.decompiler.flash.graph.BinaryOpItem;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
import java.util.List;
@@ -28,8 +29,8 @@ public class SubtractTreeItem extends BinaryOpItem {
}
@Override
public double toNumber() {
return leftSide.toNumber() - rightSide.toNumber();
public Object getResult() {
return EcmaScript.toNumber(leftSide.getResult()) - EcmaScript.toNumber(rightSide.getResult());
}
@Override
@@ -17,6 +17,14 @@
package com.jpexs.decompiler.flash.abc.avm2.treemodel.operations;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.ecma.EcmaScript;
import com.jpexs.decompiler.flash.ecma.EcmaType;
import static com.jpexs.decompiler.flash.ecma.EcmaType.BOOLEAN;
import static com.jpexs.decompiler.flash.ecma.EcmaType.NULL;
import static com.jpexs.decompiler.flash.ecma.EcmaType.NUMBER;
import static com.jpexs.decompiler.flash.ecma.EcmaType.OBJECT;
import static com.jpexs.decompiler.flash.ecma.EcmaType.STRING;
import static com.jpexs.decompiler.flash.ecma.EcmaType.UNDEFINED;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
import com.jpexs.decompiler.flash.graph.UnaryOpItem;
@@ -25,4 +33,32 @@ public class TypeOfTreeItem extends UnaryOpItem {
public TypeOfTreeItem(AVM2Instruction instruction, GraphTargetItem value) {
super(instruction, PRECEDENCE_UNARY, value, "typeof ");
}
@Override
public boolean isCompileTime() {
return value.isCompileTime();
}
@Override
public Object getResult() {
Object res = value.getResult();
EcmaType type = EcmaScript.type(res);
switch (type) {
case UNDEFINED:
return "undefined";
case NULL:
return "object";
case BOOLEAN:
return "Boolean";
case NUMBER:
return "number";
case STRING:
return "string";
case OBJECT:
return "object";
}
//TODO: function,xml
return "object";
}
}
@@ -17,6 +17,7 @@
package com.jpexs.decompiler.flash.abc.avm2.treemodel.operations;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.ecma.EcmaScript;
import com.jpexs.decompiler.flash.graph.BinaryOpItem;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
@@ -27,7 +28,7 @@ public class URShiftTreeItem extends BinaryOpItem {
}
@Override
public double toNumber() {
return ((int) leftSide.toNumber()) >>> ((int) rightSide.toNumber());
public Object getResult() {
return ((long) (double) EcmaScript.toNumber(leftSide.getResult())) >>> ((long) (double) EcmaScript.toNumber(rightSide.getResult()));
}
}
@@ -16,15 +16,14 @@
*/
package com.jpexs.decompiler.flash.abc.types;
import com.jpexs.decompiler.flash.KeyValue;
import com.jpexs.decompiler.flash.abc.ABC;
import com.jpexs.decompiler.flash.abc.ClassPath;
import com.jpexs.decompiler.flash.abc.ScriptPack;
import com.jpexs.decompiler.flash.abc.types.traits.Trait;
import com.jpexs.decompiler.flash.abc.types.traits.Traits;
import com.jpexs.decompiler.flash.tags.ABCContainerTag;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class ScriptInfo {
@@ -32,8 +31,8 @@ public class ScriptInfo {
public int init_index; //MethodInfo
public Traits traits;
public HashMap<ClassPath, ScriptPack> getPacks(ABC abc, int scriptIndex) {
HashMap<ClassPath, ScriptPack> ret = new HashMap<>();
public List<KeyValue<ClassPath, ScriptPack>> getPacks(ABC abc, int scriptIndex) {
List<KeyValue<ClassPath, ScriptPack>> ret = new ArrayList<>();
List<Integer> otherTraits = new ArrayList<>();
for (int j = 0; j < traits.traits.length; j++) {
@@ -60,7 +59,7 @@ public class ScriptInfo {
traitIndices.addAll(otherTraits);
}
otherTraits = new ArrayList<>();
ret.put(new ClassPath(packageName, objectName), new ScriptPack(abc, scriptIndex, traitIndices));
ret.add(new KeyValue<>(new ClassPath(packageName, objectName), new ScriptPack(abc, scriptIndex, traitIndices)));
}
}
return ret;
@@ -82,11 +81,4 @@ public class ScriptInfo {
public String convert(List<ABCContainerTag> abcTags, ABC abc, boolean pcode, boolean highlighting, int scriptIndex, boolean paralel) {
return traits.convert("", abcTags, abc, false, pcode, true, scriptIndex, -1, highlighting, new ArrayList<String>(), paralel);
}
public void export(ABC abc, List<ABCContainerTag> abcList, String directory, boolean pcode, int scriptIndex, boolean paralel) throws IOException {
HashMap<ClassPath, ScriptPack> packs = getPacks(abc, scriptIndex);
for (ScriptPack pack : packs.values()) {
pack.export(directory, abcList, pcode, paralel);
}
}
}
@@ -30,6 +30,7 @@ import com.jpexs.decompiler.flash.action.swf5.*;
import com.jpexs.decompiler.flash.action.swf7.ActionDefineFunction2;
import com.jpexs.decompiler.flash.action.treemodel.*;
import com.jpexs.decompiler.flash.action.treemodel.clauses.*;
import com.jpexs.decompiler.flash.ecma.Null;
import com.jpexs.decompiler.flash.graph.CommentItem;
import com.jpexs.decompiler.flash.graph.Graph;
import com.jpexs.decompiler.flash.graph.GraphSource;
@@ -1292,4 +1293,17 @@ public class Action implements GraphSourceItem {
public String getASMSourceReplaced(List<? extends GraphSourceItem> container, List<Long> knownAddreses, List<String> constantPool, int version, boolean hex) {
return getASMSource(container, knownAddreses, constantPool, version, hex);
}
public static double toFloatPoint(Object o) {
if (o instanceof Double) {
return (Double) o;
}
if (o instanceof Integer) {
return (Integer) o;
}
if (o instanceof Long) {
return (Long) o;
}
return 0;
}
}
@@ -20,7 +20,6 @@ import com.jpexs.decompiler.flash.action.swf4.ActionEquals;
import com.jpexs.decompiler.flash.action.swf4.ActionIf;
import com.jpexs.decompiler.flash.action.swf4.ActionNot;
import com.jpexs.decompiler.flash.action.swf4.ActionPush;
import com.jpexs.decompiler.flash.action.swf4.Null;
import com.jpexs.decompiler.flash.action.swf4.RegisterNumber;
import com.jpexs.decompiler.flash.action.swf5.ActionEquals2;
import com.jpexs.decompiler.flash.action.swf5.ActionStoreRegister;
@@ -33,6 +32,7 @@ import com.jpexs.decompiler.flash.action.treemodel.StoreRegisterTreeItem;
import com.jpexs.decompiler.flash.action.treemodel.clauses.ForInTreeItem;
import com.jpexs.decompiler.flash.action.treemodel.operations.NeqTreeItem;
import com.jpexs.decompiler.flash.action.treemodel.operations.StrictEqTreeItem;
import com.jpexs.decompiler.flash.ecma.Null;
import com.jpexs.decompiler.flash.graph.BreakItem;
import com.jpexs.decompiler.flash.graph.ContinueItem;
import com.jpexs.decompiler.flash.graph.Graph;
@@ -5,9 +5,9 @@ package com.jpexs.decompiler.flash.action.parser.pcode;
import com.jpexs.decompiler.flash.action.parser.ParseException;
import com.jpexs.decompiler.flash.action.swf4.ConstantIndex;
import com.jpexs.decompiler.flash.action.swf4.Null;
import com.jpexs.decompiler.flash.action.swf4.RegisterNumber;
import com.jpexs.decompiler.flash.action.swf4.Undefined;
import com.jpexs.decompiler.flash.ecma.Null;
import com.jpexs.decompiler.flash.ecma.Undefined;
/**
* This class is a scanner generated by
@@ -37,6 +37,8 @@ import com.jpexs.decompiler.flash.action.swf7.ActionImplementsOp;
import com.jpexs.decompiler.flash.action.swf7.ActionThrow;
import com.jpexs.decompiler.flash.action.swf7.ActionTry;
import com.jpexs.decompiler.flash.action.treemodel.ConstantPool;
import com.jpexs.decompiler.flash.ecma.Null;
import com.jpexs.decompiler.flash.ecma.Undefined;
import com.jpexs.decompiler.flash.graph.GraphSourceItem;
import java.io.ByteArrayInputStream;
import java.io.IOException;
@@ -38,6 +38,6 @@ public class ActionAdd extends Action {
public void translate(Stack<GraphTargetItem> stack, List<GraphTargetItem> output, java.util.HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions) {
GraphTargetItem a = stack.pop();
GraphTargetItem b = stack.pop();
stack.push(new AddTreeItem(this, b, a));
stack.push(new AddTreeItem(this, b, a, false));
}
}
@@ -38,6 +38,6 @@ public class ActionEquals extends Action {
public void translate(Stack<GraphTargetItem> stack, List<GraphTargetItem> output, java.util.HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions) {
GraphTargetItem a = stack.pop();
GraphTargetItem b = stack.pop();
stack.push(new EqTreeItem(this, b, a));
stack.push(new EqTreeItem(this, b, a, false));
}
}
@@ -38,6 +38,6 @@ public class ActionLess extends Action {
public void translate(Stack<GraphTargetItem> stack, List<GraphTargetItem> output, java.util.HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions) {
GraphTargetItem a = stack.pop();
GraphTargetItem b = stack.pop();
stack.push(new LtTreeItem(this, b, a));
stack.push(new LtTreeItem(this, b, a, false));
}
}
@@ -24,6 +24,8 @@ import com.jpexs.decompiler.flash.action.parser.ParseException;
import com.jpexs.decompiler.flash.action.parser.pcode.ASMParsedSymbol;
import com.jpexs.decompiler.flash.action.parser.pcode.FlasmLexer;
import com.jpexs.decompiler.flash.action.treemodel.DirectValueTreeItem;
import com.jpexs.decompiler.flash.ecma.Null;
import com.jpexs.decompiler.flash.ecma.Undefined;
import com.jpexs.decompiler.flash.graph.GraphSourceItem;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
import com.jpexs.decompiler.flash.helpers.Helper;
@@ -19,6 +19,7 @@ package com.jpexs.decompiler.flash.action.swf4;
import com.jpexs.decompiler.flash.action.Action;
import com.jpexs.decompiler.flash.action.treemodel.DirectValueTreeItem;
import com.jpexs.decompiler.flash.action.treemodel.StartDragTreeItem;
import com.jpexs.decompiler.flash.ecma.*;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
import java.util.HashMap;
import java.util.List;
@@ -43,7 +44,7 @@ public class ActionStartDrag extends Action {
boolean hasConstrains = true;
if (constrain instanceof DirectValueTreeItem) {
if (Double.compare(constrain.toNumber(), 0) == 0) {
if (Double.compare(EcmaScript.toNumber(constrain.getResult()), 0) == 0) {
hasConstrains = false;
}
}
@@ -38,6 +38,6 @@ public class ActionAdd2 extends Action {
public void translate(Stack<GraphTargetItem> stack, List<GraphTargetItem> output, java.util.HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions) {
GraphTargetItem a = stack.pop();
GraphTargetItem b = stack.pop();
stack.push(new AddTreeItem(this, b, a));
stack.push(new AddTreeItem(this, b, a, true));
}
}
@@ -17,9 +17,9 @@
package com.jpexs.decompiler.flash.action.swf5;
import com.jpexs.decompiler.flash.action.Action;
import com.jpexs.decompiler.flash.action.swf4.Null;
import com.jpexs.decompiler.flash.action.treemodel.DirectValueTreeItem;
import com.jpexs.decompiler.flash.action.treemodel.EnumerateTreeItem;
import com.jpexs.decompiler.flash.ecma.Null;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
import java.util.ArrayList;
import java.util.HashMap;
@@ -38,6 +38,6 @@ public class ActionEquals2 extends Action {
public void translate(Stack<GraphTargetItem> stack, List<GraphTargetItem> output, java.util.HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions) {
GraphTargetItem a = stack.pop();
GraphTargetItem b = stack.pop();
stack.push(new EqTreeItem(this, b, a));
stack.push(new EqTreeItem(this, b, a, true));
}
}
@@ -38,6 +38,6 @@ public class ActionLess2 extends Action {
public void translate(Stack<GraphTargetItem> stack, List<GraphTargetItem> output, java.util.HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions) {
GraphTargetItem a = stack.pop();
GraphTargetItem b = stack.pop();
stack.push(new LtTreeItem(this, b, a));
stack.push(new LtTreeItem(this, b, a, true));
}
}
@@ -17,9 +17,9 @@
package com.jpexs.decompiler.flash.action.swf6;
import com.jpexs.decompiler.flash.action.Action;
import com.jpexs.decompiler.flash.action.swf4.Null;
import com.jpexs.decompiler.flash.action.treemodel.DirectValueTreeItem;
import com.jpexs.decompiler.flash.action.treemodel.EnumerateTreeItem;
import com.jpexs.decompiler.flash.ecma.Null;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
import java.util.ArrayList;
import java.util.HashMap;
@@ -63,19 +63,11 @@ public class CallFunctionTreeItem extends TreeItem {
}
@Override
public boolean toBoolean() {
public Object getResult() {
if (calculatedFunction == null) {
return false;
return null;
}
return calculatedFunction.toBoolean();
}
@Override
public double toNumber() {
if (calculatedFunction == null) {
return 0;
}
return calculatedFunction.toNumber();
return calculatedFunction.getResult();
}
@Override
@@ -16,7 +16,7 @@
*/
package com.jpexs.decompiler.flash.action.treemodel;
import com.jpexs.decompiler.flash.action.swf4.Undefined;
import com.jpexs.decompiler.flash.ecma.Undefined;
import com.jpexs.decompiler.flash.graph.GraphSourceItem;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
import java.util.List;
@@ -56,22 +56,13 @@ public class CharToAsciiTreeItem extends TreeItem {
}
@Override
public double toNumber() {
if (value instanceof DirectValueTreeItem) {
DirectValueTreeItem dv = (DirectValueTreeItem) value;
if (dv.value instanceof String) {
String s = (String) dv.value;
if (s.length() > 0) {
char c = s.charAt(0);
return (int) c;
}
}
public Object getResult() {
Object res = value.getResult();
String s = res.toString();
if (s.length() > 0) {
char c = s.charAt(0);
return (int) c;
}
return 0;
}
@Override
public boolean toBoolean() {
return toNumber() != 0;
}
}
@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.action.treemodel;
import com.jpexs.decompiler.flash.ecma.*;
import com.jpexs.decompiler.flash.graph.GraphSourceItem;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
import java.util.List;
@@ -40,8 +41,8 @@ public class DecrementTreeItem extends TreeItem {
}
@Override
public double toNumber() {
return object.toNumber() - 1;
public Object getResult() {
return EcmaScript.toNumber(object.getResult()) - 1;
}
@Override
@@ -17,7 +17,9 @@
package com.jpexs.decompiler.flash.action.treemodel;
import com.jpexs.decompiler.flash.action.swf4.ConstantIndex;
import com.jpexs.decompiler.flash.action.swf4.Null;
import com.jpexs.decompiler.flash.action.swf4.RegisterNumber;
import com.jpexs.decompiler.flash.ecma.Null;
import com.jpexs.decompiler.flash.ecma.Undefined;
import com.jpexs.decompiler.flash.graph.GraphSourceItem;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
import com.jpexs.decompiler.flash.helpers.Helper;
@@ -46,82 +48,33 @@ public class DirectValueTreeItem extends TreeItem {
}
@Override
public double toNumber() {
public Object getResult() {
if (computedRegValue != null) {
return computedRegValue.toNumber();
return computedRegValue.getResult();
}
if (value instanceof Double) {
return (Double) value;
}
if (value instanceof Float) {
return (Float) value;
return (double) (Float) value;
}
if (value instanceof Long) {
return (Long) value;
return (double) (Long) value;
}
if (value instanceof Boolean) {
return ((Boolean) value) ? 1 : 0;
return value;
}
if (value instanceof String) {
String s = (String) value;
if (s.length() == 1) {
return s.charAt(0);
}
double ret = 0.0;
try {
ret = Double.parseDouble(s);
} catch (NumberFormatException nex) {
}
return ret;
return value;
}
if (value instanceof ConstantIndex) {
String s = (this.constants.get(((ConstantIndex) value).index));
if (s.length() == 1) {
return s.charAt(0);
}
double ret = 0.0;
try {
ret = Double.parseDouble(s);
} catch (NumberFormatException nex) {
}
return ret;
return (this.constants.get(((ConstantIndex) value).index));
}
return super.toNumber();
}
@Override
public boolean toBoolean() {
if (computedRegValue != null) {
return computedRegValue.toBoolean();
if (value instanceof RegisterNumber) {
return new Undefined(); //has not computed value
}
if (value instanceof Boolean) {
return (Boolean) value;
}
if (value instanceof Double) {
return Double.compare((Double) value, 0.0) != 0;
}
if (value instanceof Float) {
return Float.compare((Float) value, 0.0f) != 0;
}
if (value instanceof Long) {
return ((Long) value) != 0;
}
if (value instanceof String) {
String s = (String) value;
if (s.length() == 1) {
return toNumber() == 0;
}
return !s.equals("");
}
if (value instanceof ConstantIndex) {
String s = (this.constants.get(((ConstantIndex) value).index));
if (s.length() == 1) {
return toNumber() == 0;
}
return !s.equals("");
}
return false;
return value;
}
@Override
@@ -90,22 +90,11 @@ public class FunctionTreeItem extends TreeItem {
}
@Override
public boolean toBoolean() {
public Object getResult() {
if (!actions.isEmpty()) {
if (actions.get(actions.size() - 1) instanceof ReturnTreeItem) {
ReturnTreeItem r = (ReturnTreeItem) actions.get(actions.size() - 1);
return r.value.toBoolean();
}
}
return false;
}
@Override
public double toNumber() {
if (!actions.isEmpty()) {
if (actions.get(actions.size() - 1) instanceof ReturnTreeItem) {
ReturnTreeItem r = (ReturnTreeItem) actions.get(actions.size() - 1);
return r.value.toNumber();
return r.value.getResult();
}
}
return 0;
@@ -36,12 +36,7 @@ public class GetTimeTreeItem extends TreeItem {
}
@Override
public double toNumber() {
return new Random().nextInt(10000) + 1000;
}
@Override
public boolean toBoolean() {
return true;
public Object getResult() {
return (Double) (double) new Random().nextInt(10000) + 1000;
}
}
@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.action.treemodel;
import com.jpexs.decompiler.flash.ecma.Undefined;
import com.jpexs.decompiler.flash.graph.GraphSourceItem;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
import java.util.List;
@@ -24,8 +25,7 @@ public class GetVariableTreeItem extends TreeItem {
public GraphTargetItem name;
private GraphTargetItem computedValue;
private double computedNumber = 0;
private boolean computedBool = false;
private Object computedResult;
private boolean computedCompiletime = false;
private boolean computedVariableComputed = false;
@@ -64,26 +64,17 @@ public class GetVariableTreeItem extends TreeItem {
}
@Override
public boolean toBoolean() {
public Object getResult() {
if (computedValue == null) {
return false;
return new Undefined();
}
return computedBool;
}
@Override
public double toNumber() {
if (computedValue == null) {
return 0;
}
return computedNumber;
return computedResult;
}
public void setComputedValue(GraphTargetItem computedValue) {
this.computedValue = computedValue;
if (computedValue != null) {
computedNumber = computedValue.toNumber();
computedBool = computedValue.toBoolean();
computedResult = computedValue.getResult();
computedCompiletime = computedValue.isCompileTime();
computedVariableComputed = computedValue.isVariableComputed();
}
@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.action.treemodel;
import com.jpexs.decompiler.flash.ecma.*;
import com.jpexs.decompiler.flash.graph.GraphSourceItem;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
import java.util.List;
@@ -40,8 +41,8 @@ public class IncrementTreeItem extends TreeItem {
}
@Override
public double toNumber() {
return object.toNumber() + 1;
public Object getResult() {
return EcmaScript.toNumber(object.getResult()) + 1;
}
@Override
@@ -16,7 +16,7 @@
*/
package com.jpexs.decompiler.flash.action.treemodel;
import com.jpexs.decompiler.flash.action.swf4.Undefined;
import com.jpexs.decompiler.flash.ecma.Undefined;
import com.jpexs.decompiler.flash.graph.GraphSourceItem;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
import java.util.List;
@@ -47,7 +47,7 @@ public class PostIncrementTreeItem extends TreeItem implements SetTypeTreeItem {
@Override
public GraphTargetItem getValue() {
return new AddTreeItem(null, object, new DirectValueTreeItem(null, 0, new Long(1), null));
return new AddTreeItem(null, object, new DirectValueTreeItem(null, 0, new Long(1), null), true);
}
@Override
@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.action.treemodel;
import com.jpexs.decompiler.flash.ecma.*;
import com.jpexs.decompiler.flash.graph.GraphSourceItem;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
import java.util.List;
@@ -45,7 +46,7 @@ public class StartDragTreeItem extends TreeItem {
public String toString(ConstantPool constants) {
boolean hasConstrains = true;
if (constrain instanceof DirectValueTreeItem) {
if (Double.compare(constrain.toNumber(), 0) == 0) {
if (Double.compare(EcmaScript.toNumber(constrain.getResult()), 0) == 0) {
hasConstrains = false;
}
}
@@ -16,6 +16,8 @@
*/
package com.jpexs.decompiler.flash.action.treemodel;
import com.jpexs.decompiler.flash.ecma.EcmaScript;
import com.jpexs.decompiler.flash.ecma.EcmaType;
import com.jpexs.decompiler.flash.graph.GraphSourceItem;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
import com.jpexs.decompiler.flash.helpers.Helper;
@@ -41,4 +43,31 @@ public class TypeOfTreeItem extends TreeItem {
ret.addAll(value.getNeededSources());
return ret;
}
@Override
public Object getResult() {
Object res = value.getResult();
EcmaType type = EcmaScript.type(res);
switch (type) {
case STRING:
return "string";
case BOOLEAN:
return "boolean";
case NUMBER:
return "number";
case OBJECT:
return "object";
case UNDEFINED:
return "undefined";
case NULL:
return "null";
}
//TODO: function,movieclip
return "object";
}
@Override
public boolean isCompileTime() {
return value.isCompileTime();
}
}
@@ -16,18 +16,30 @@
*/
package com.jpexs.decompiler.flash.action.treemodel.operations;
import com.jpexs.decompiler.flash.action.Action;
import com.jpexs.decompiler.flash.ecma.*;
import com.jpexs.decompiler.flash.graph.BinaryOpItem;
import com.jpexs.decompiler.flash.graph.GraphSourceItem;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
public class AddTreeItem extends BinaryOpItem {
public AddTreeItem(GraphSourceItem instruction, GraphTargetItem leftSide, GraphTargetItem rightSide) {
boolean version2;
public AddTreeItem(GraphSourceItem instruction, GraphTargetItem leftSide, GraphTargetItem rightSide, boolean version2) {
super(instruction, PRECEDENCE_ADDITIVE, leftSide, rightSide, "+");
this.version2 = version2;
}
@Override
public double toNumber() {
return leftSide.toNumber() + rightSide.toNumber();
public Object getResult() {
if (version2) {
if (EcmaScript.type(leftSide.getResult()) == EcmaType.STRING || EcmaScript.type(rightSide.getResult()) == EcmaType.STRING) {
return leftSide.getResult().toString() + rightSide.getResult().toString();
}
return EcmaScript.toNumber(leftSide.getResult()) + EcmaScript.toNumber(rightSide.getResult());
} else {
return Action.toFloatPoint(leftSide.getResult()) + Action.toFloatPoint(rightSide.getResult());
}
}
}
@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.action.treemodel.operations;
import com.jpexs.decompiler.flash.ecma.*;
import com.jpexs.decompiler.flash.graph.BinaryOpItem;
import com.jpexs.decompiler.flash.graph.GraphSourceItem;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
@@ -27,7 +28,7 @@ public class AndTreeItem extends BinaryOpItem {
}
@Override
public boolean toBoolean() {
return leftSide.toBoolean() && rightSide.toBoolean();
public Object getResult() {
return EcmaScript.toBoolean(leftSide.getResult()) && EcmaScript.toBoolean(rightSide.getResult());
}
}
@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.action.treemodel.operations;
import com.jpexs.decompiler.flash.ecma.*;
import com.jpexs.decompiler.flash.graph.BinaryOpItem;
import com.jpexs.decompiler.flash.graph.GraphSourceItem;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
@@ -27,7 +28,7 @@ public class BitAndTreeItem extends BinaryOpItem {
}
@Override
public double toNumber() {
return ((int) leftSide.toNumber()) & ((int) rightSide.toNumber());
public Object getResult() {
return ((long) (double) EcmaScript.toNumber(leftSide.getResult())) & ((long) (double) EcmaScript.toNumber(rightSide.getResult()));
}
}
@@ -17,6 +17,7 @@
package com.jpexs.decompiler.flash.action.treemodel.operations;
import com.jpexs.decompiler.flash.action.treemodel.TreeItem;
import com.jpexs.decompiler.flash.ecma.*;
import com.jpexs.decompiler.flash.graph.GraphSourceItem;
import com.jpexs.decompiler.flash.graph.UnaryOpItem;
@@ -27,7 +28,7 @@ public class BitNotTreeItem extends UnaryOpItem {
}
@Override
public double toNumber() {
return ~((int) value.toNumber());
public Object getResult() {
return ~((long) (double) EcmaScript.toNumber(value.getResult()));
}
}
@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.action.treemodel.operations;
import com.jpexs.decompiler.flash.ecma.*;
import com.jpexs.decompiler.flash.graph.BinaryOpItem;
import com.jpexs.decompiler.flash.graph.GraphSourceItem;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
@@ -27,7 +28,7 @@ public class BitOrTreeItem extends BinaryOpItem {
}
@Override
public double toNumber() {
return ((int) leftSide.toNumber()) | ((int) rightSide.toNumber());
public Object getResult() {
return ((long) (double) EcmaScript.toNumber(leftSide.getResult())) | ((long) (double) EcmaScript.toNumber(rightSide.getResult()));
}
}
@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.action.treemodel.operations;
import com.jpexs.decompiler.flash.ecma.*;
import com.jpexs.decompiler.flash.graph.BinaryOpItem;
import com.jpexs.decompiler.flash.graph.GraphSourceItem;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
@@ -27,7 +28,7 @@ public class BitXorTreeItem extends BinaryOpItem {
}
@Override
public double toNumber() {
return ((int) leftSide.toNumber()) ^ ((int) rightSide.toNumber());
public Object getResult() {
return ((long) (double) EcmaScript.toNumber(leftSide.getResult())) ^ ((long) (double) EcmaScript.toNumber(rightSide.getResult()));
}
}
@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.action.treemodel.operations;
import com.jpexs.decompiler.flash.ecma.*;
import com.jpexs.decompiler.flash.graph.BinaryOpItem;
import com.jpexs.decompiler.flash.graph.GraphSourceItem;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
@@ -27,7 +28,10 @@ public class DivideTreeItem extends BinaryOpItem {
}
@Override
public double toNumber() {
return leftSide.toNumber() / rightSide.toNumber();
public Object getResult() {
if (Double.compare(EcmaScript.toNumber(rightSide.getResult()), 0) == 0) {
return Double.NaN;
}
return (EcmaScript.toNumber(leftSide.getResult())) / (EcmaScript.toNumber(rightSide.getResult()));
}
}
@@ -16,6 +16,8 @@
*/
package com.jpexs.decompiler.flash.action.treemodel.operations;
import com.jpexs.decompiler.flash.action.Action;
import com.jpexs.decompiler.flash.ecma.*;
import com.jpexs.decompiler.flash.graph.BinaryOpItem;
import com.jpexs.decompiler.flash.graph.GraphSourceItem;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
@@ -23,17 +25,25 @@ import com.jpexs.decompiler.flash.graph.LogicalOpItem;
public class EqTreeItem extends BinaryOpItem implements LogicalOpItem {
public EqTreeItem(GraphSourceItem instruction, GraphTargetItem leftSide, GraphTargetItem rightSide) {
boolean version2;
public EqTreeItem(GraphSourceItem instruction, GraphTargetItem leftSide, GraphTargetItem rightSide, boolean version2) {
super(instruction, PRECEDENCE_EQUALITY, leftSide, rightSide, "==");
this.version2 = version2;
}
@Override
public boolean toBoolean() {
return (leftSide.toBoolean() == rightSide.toBoolean()) && (leftSide.toNumber() == rightSide.toNumber());
public Object getResult() {
if (version2) {
return EcmaScript.equals(leftSide.getResult(), rightSide.getResult());
} else {
//For SWF 4 and older, it should return 1 or 0
return (Action.toFloatPoint(leftSide.getResult()) == Action.toFloatPoint(rightSide.getResult()));
}
}
@Override
public GraphTargetItem invert() {
return new NeqTreeItem(src, leftSide, rightSide);
return new NeqTreeItem(src, leftSide, rightSide, version2);
}
}
@@ -16,6 +16,8 @@
*/
package com.jpexs.decompiler.flash.action.treemodel.operations;
import com.jpexs.decompiler.flash.action.Action;
import com.jpexs.decompiler.flash.ecma.*;
import com.jpexs.decompiler.flash.graph.BinaryOpItem;
import com.jpexs.decompiler.flash.graph.GraphSourceItem;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
@@ -23,17 +25,32 @@ import com.jpexs.decompiler.flash.graph.LogicalOpItem;
public class GeTreeItem extends BinaryOpItem implements LogicalOpItem {
public GeTreeItem(GraphSourceItem instruction, GraphTargetItem leftSide, GraphTargetItem rightSide) {
boolean version2;
public GeTreeItem(GraphSourceItem instruction, GraphTargetItem leftSide, GraphTargetItem rightSide, boolean version2) {
super(instruction, PRECEDENCE_RELATIONAL, leftSide, rightSide, ">=");
this.version2 = version2;
}
@Override
public boolean toBoolean() {
return leftSide.toNumber() >= rightSide.toNumber();
public Object getResult() {
if (version2) {
Object ret = EcmaScript.compare(leftSide.getResult(), rightSide.getResult());
if (ret == Boolean.TRUE) {
return Boolean.FALSE;
}
if (ret == Boolean.FALSE) {
return Boolean.TRUE;
}
return ret;//undefined
} else {
//For SWF 4 and older, it should return 1 or 0
return Action.toFloatPoint(leftSide.getResult()) >= Action.toFloatPoint(rightSide.getResult());
}
}
@Override
public GraphTargetItem invert() {
return new LtTreeItem(src, leftSide, rightSide);
return new LtTreeItem(src, leftSide, rightSide, version2);
}
}
@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.action.treemodel.operations;
import com.jpexs.decompiler.flash.ecma.*;
import com.jpexs.decompiler.flash.graph.BinaryOpItem;
import com.jpexs.decompiler.flash.graph.GraphSourceItem;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
@@ -28,8 +29,8 @@ public class GtTreeItem extends BinaryOpItem implements LogicalOpItem {
}
@Override
public boolean toBoolean() {
return leftSide.toNumber() > rightSide.toNumber();
public Object getResult() {
return EcmaScript.compare(rightSide.getResult(), leftSide.getResult());
}
@Override
@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.action.treemodel.operations;
import com.jpexs.decompiler.flash.ecma.*;
import com.jpexs.decompiler.flash.graph.BinaryOpItem;
import com.jpexs.decompiler.flash.graph.GraphSourceItem;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
@@ -27,7 +28,7 @@ public class LShiftTreeItem extends BinaryOpItem {
}
@Override
public double toNumber() {
return ((int) leftSide.toNumber()) << ((int) rightSide.toNumber());
public Object getResult() {
return ((int) (double) EcmaScript.toNumber(leftSide.getResult())) << ((int) (double) EcmaScript.toNumber(rightSide.getResult()));
}
}
@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.action.treemodel.operations;
import com.jpexs.decompiler.flash.ecma.*;
import com.jpexs.decompiler.flash.graph.BinaryOpItem;
import com.jpexs.decompiler.flash.graph.GraphSourceItem;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
@@ -28,8 +29,15 @@ public class LeTreeItem extends BinaryOpItem implements LogicalOpItem {
}
@Override
public boolean toBoolean() {
return leftSide.toNumber() <= rightSide.toNumber();
public Object getResult() {
Object ret = EcmaScript.compare(rightSide.getResult(), leftSide.getResult());
if (ret == Boolean.TRUE) {
return Boolean.FALSE;
}
if (ret == Boolean.FALSE) {
return Boolean.TRUE;
}
return ret;//undefined
}
@Override
@@ -16,6 +16,8 @@
*/
package com.jpexs.decompiler.flash.action.treemodel.operations;
import com.jpexs.decompiler.flash.action.Action;
import com.jpexs.decompiler.flash.ecma.*;
import com.jpexs.decompiler.flash.graph.BinaryOpItem;
import com.jpexs.decompiler.flash.graph.GraphSourceItem;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
@@ -23,17 +25,25 @@ import com.jpexs.decompiler.flash.graph.LogicalOpItem;
public class LtTreeItem extends BinaryOpItem implements LogicalOpItem {
public LtTreeItem(GraphSourceItem instruction, GraphTargetItem leftSide, GraphTargetItem rightSide) {
boolean version2;
public LtTreeItem(GraphSourceItem instruction, GraphTargetItem leftSide, GraphTargetItem rightSide, boolean version2) {
super(instruction, PRECEDENCE_RELATIONAL, leftSide, rightSide, "<");
this.version2 = version2;
}
@Override
public boolean toBoolean() {
return leftSide.toNumber() < rightSide.toNumber();
public Object getResult() {
if (version2) {
return EcmaScript.compare(leftSide.getResult(), rightSide.getResult());
} else {
//For SWF 4 and older, it should return 1 or 0
return Action.toFloatPoint(leftSide.getResult()) < Action.toFloatPoint(rightSide.getResult());
}
}
@Override
public GraphTargetItem invert() {
return new GeTreeItem(src, leftSide, rightSide);
return new GeTreeItem(src, leftSide, rightSide, version2);
}
}
@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.action.treemodel.operations;
import com.jpexs.decompiler.flash.ecma.*;
import com.jpexs.decompiler.flash.graph.BinaryOpItem;
import com.jpexs.decompiler.flash.graph.GraphSourceItem;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
@@ -27,10 +28,10 @@ public class ModuloTreeItem extends BinaryOpItem {
}
@Override
public double toNumber() {
if (Double.compare(rightSide.toNumber(), 0) == 0) {
public Object getResult() {
if (Double.compare(EcmaScript.toNumber(rightSide.getResult()), 0) == 0) {
return Double.NaN;
}
return ((int) leftSide.toNumber()) % ((int) rightSide.toNumber());
return ((long) (double) EcmaScript.toNumber(leftSide.getResult())) % ((long) (double) EcmaScript.toNumber(rightSide.getResult()));
}
}
@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.action.treemodel.operations;
import com.jpexs.decompiler.flash.ecma.*;
import com.jpexs.decompiler.flash.graph.BinaryOpItem;
import com.jpexs.decompiler.flash.graph.GraphSourceItem;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
@@ -27,7 +28,7 @@ public class MultiplyTreeItem extends BinaryOpItem {
}
@Override
public double toNumber() {
return leftSide.toNumber() * rightSide.toNumber();
public Object getResult() {
return (EcmaScript.toNumber(leftSide.getResult())) * (EcmaScript.toNumber(rightSide.getResult()));
}
}
@@ -17,6 +17,7 @@
package com.jpexs.decompiler.flash.action.treemodel.operations;
import com.jpexs.decompiler.flash.action.treemodel.TreeItem;
import com.jpexs.decompiler.flash.ecma.*;
import com.jpexs.decompiler.flash.graph.GraphSourceItem;
import com.jpexs.decompiler.flash.graph.UnaryOpItem;
@@ -27,7 +28,7 @@ public class NegTreeItem extends UnaryOpItem {
}
@Override
public double toNumber() {
return -value.toNumber();
public Object getResult() {
return -EcmaScript.toNumber(value.getResult());
}
}
@@ -16,6 +16,8 @@
*/
package com.jpexs.decompiler.flash.action.treemodel.operations;
import com.jpexs.decompiler.flash.action.Action;
import com.jpexs.decompiler.flash.ecma.*;
import com.jpexs.decompiler.flash.graph.BinaryOpItem;
import com.jpexs.decompiler.flash.graph.GraphSourceItem;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
@@ -23,17 +25,25 @@ import com.jpexs.decompiler.flash.graph.LogicalOpItem;
public class NeqTreeItem extends BinaryOpItem implements LogicalOpItem {
public NeqTreeItem(GraphSourceItem instruction, GraphTargetItem leftSide, GraphTargetItem rightSide) {
boolean version2;
public NeqTreeItem(GraphSourceItem instruction, GraphTargetItem leftSide, GraphTargetItem rightSide, boolean version2) {
super(instruction, PRECEDENCE_EQUALITY, leftSide, rightSide, "!=");
this.version2 = version2;
}
@Override
public boolean toBoolean() {
return (leftSide.toNumber() != rightSide.toNumber()) || (leftSide.toBoolean() != rightSide.toBoolean());
public Object getResult() {
if (version2) {
return !EcmaScript.equals(leftSide.getResult(), rightSide.getResult());
} else {
//For SWF 4 and older, it should return 1 or 0
return (Action.toFloatPoint(leftSide.getResult()) != Action.toFloatPoint(rightSide.getResult()));
}
}
@Override
public GraphTargetItem invert() {
return new EqTreeItem(src, leftSide, rightSide);
return new EqTreeItem(src, leftSide, rightSide, version2);
}
}
@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.action.treemodel.operations;
import com.jpexs.decompiler.flash.ecma.*;
import com.jpexs.decompiler.flash.graph.BinaryOpItem;
import com.jpexs.decompiler.flash.graph.GraphSourceItem;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
@@ -27,7 +28,7 @@ public class OrTreeItem extends BinaryOpItem {
}
@Override
public boolean toBoolean() {
return leftSide.toBoolean() || rightSide.toBoolean();
public Object getResult() {
return EcmaScript.toBoolean(leftSide.getResult()) || EcmaScript.toBoolean(rightSide.getResult());
}
}
@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.action.treemodel.operations;
import com.jpexs.decompiler.flash.ecma.*;
import com.jpexs.decompiler.flash.graph.GraphSourceItem;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
import com.jpexs.decompiler.flash.graph.UnaryOpItem;
@@ -27,7 +28,7 @@ public class PreDecrementTreeItem extends UnaryOpItem {
}
@Override
public double toNumber() {
return value.toNumber() - 1;
public Object getResult() {
return EcmaScript.toNumber(value.getResult()) - 1;
}
}
@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.action.treemodel.operations;
import com.jpexs.decompiler.flash.ecma.*;
import com.jpexs.decompiler.flash.graph.GraphSourceItem;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
import com.jpexs.decompiler.flash.graph.UnaryOpItem;
@@ -27,7 +28,7 @@ public class PreIncrementTreeItem extends UnaryOpItem {
}
@Override
public double toNumber() {
return value.toNumber() + 1;
public Object getResult() {
return EcmaScript.toNumber(value.getResult()) + 1;
}
}
@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.action.treemodel.operations;
import com.jpexs.decompiler.flash.ecma.*;
import com.jpexs.decompiler.flash.graph.BinaryOpItem;
import com.jpexs.decompiler.flash.graph.GraphSourceItem;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
@@ -27,7 +28,7 @@ public class RShiftTreeItem extends BinaryOpItem {
}
@Override
public double toNumber() {
return ((int) leftSide.toNumber()) >> ((int) rightSide.toNumber());
public Object getResult() {
return ((long) (double) EcmaScript.toNumber(leftSide.getResult())) >> ((long) (double) EcmaScript.toNumber(rightSide.getResult()));
}
}
@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.action.treemodel.operations;
import com.jpexs.decompiler.flash.ecma.*;
import com.jpexs.decompiler.flash.graph.BinaryOpItem;
import com.jpexs.decompiler.flash.graph.GraphSourceItem;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
@@ -28,8 +29,11 @@ public class StrictEqTreeItem extends BinaryOpItem implements LogicalOpItem {
}
@Override
public boolean toBoolean() {
return (leftSide.toBoolean() == rightSide.toBoolean()) && (leftSide.toNumber() == rightSide.toNumber());
public Object getResult() {
Object x = leftSide.getResult();
Object y = rightSide.getResult();
return EcmaScript.type(x) == EcmaScript.type(y)
&& EcmaScript.equals(x, y);
}
@Override
@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.action.treemodel.operations;
import com.jpexs.decompiler.flash.ecma.*;
import com.jpexs.decompiler.flash.graph.BinaryOpItem;
import com.jpexs.decompiler.flash.graph.GraphSourceItem;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
@@ -28,8 +29,11 @@ public class StrictNeqTreeItem extends BinaryOpItem implements LogicalOpItem {
}
@Override
public boolean toBoolean() {
return (leftSide.toBoolean() != rightSide.toBoolean()) && (leftSide.toNumber() != rightSide.toNumber());
public Object getResult() {
Object x = leftSide.getResult();
Object y = rightSide.getResult();
return EcmaScript.type(x) != EcmaScript.type(y)
|| (!EcmaScript.equals(x, y));
}
@Override
@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.action.treemodel.operations;
import com.jpexs.decompiler.flash.ecma.*;
import com.jpexs.decompiler.flash.graph.BinaryOpItem;
import com.jpexs.decompiler.flash.graph.GraphSourceItem;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
@@ -28,8 +29,8 @@ public class SubtractTreeItem extends BinaryOpItem {
}
@Override
public double toNumber() {
return leftSide.toNumber() - rightSide.toNumber();
public Object getResult() {
return EcmaScript.toNumber(leftSide.getResult()) - EcmaScript.toNumber(rightSide.getResult());
}
@Override
@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.action.treemodel.operations;
import com.jpexs.decompiler.flash.ecma.*;
import com.jpexs.decompiler.flash.graph.BinaryOpItem;
import com.jpexs.decompiler.flash.graph.GraphSourceItem;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
@@ -27,7 +28,7 @@ public class URShiftTreeItem extends BinaryOpItem {
}
@Override
public double toNumber() {
return ((int) leftSide.toNumber()) >>> ((int) rightSide.toNumber());
public Object getResult() {
return ((long) (double) EcmaScript.toNumber(leftSide.getResult())) >>> ((long) (double) EcmaScript.toNumber(rightSide.getResult()));
}
}
@@ -0,0 +1,295 @@
/*
* Copyright (C) 2013 JPEXS
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.jpexs.decompiler.flash.ecma;
/**
*
* @author JPEXS
*/
public class EcmaScript {
public static Double toNumber(Object o) {
if (o == null) {
return 0.0;
}
if (o instanceof Undefined) {
return Double.NaN;
}
if (o instanceof Null) {
return 0.0;
}
if (o instanceof Boolean) {
return (Boolean) o ? 1.0 : 0.0;
}
if (o instanceof Double) {
return (Double) o;
}
if (o instanceof Long) {
return (double) (long) (Long) o;
}
if (o instanceof Integer) {
return (double) (int) (Integer) o;
}
if (o instanceof String) {
try {
return Double.parseDouble((String) o);
} catch (NumberFormatException nfe) {
return Double.NaN;
}
}
//TODO:ToPrimitive
return 0.0;
}
public static EcmaType type(Object o) {
if (o == null) {
return EcmaType.NULL;
}
if (o.getClass() == String.class) {
return EcmaType.STRING;
}
if (o.getClass() == Integer.class) {
return EcmaType.NUMBER;
}
if (o.getClass() == Double.class) {
return EcmaType.NUMBER;
}
if (o.getClass() == Long.class) {
return EcmaType.NUMBER;
}
if (o.getClass() == Null.class) {
return EcmaType.NULL;
}
if (o.getClass() == Undefined.class) {
return EcmaType.UNDEFINED;
}
return EcmaType.OBJECT;
}
public static Object compare(Object x, Object y) {
Object px = x;
Object py = y;
/*if (leftFirst) {
px = x; //toPrimitive
py = y; //toPrimitive
} else {
py = y; //toPrimitive
px = x; //toPrimitive
}*/
if (type(px) != EcmaType.STRING || type(py) != EcmaType.STRING) {
Double nx = toNumber(px);
Double ny = toNumber(py);
if (nx.isNaN()) {
return new Undefined();
}
if (ny.isNaN()) {
return new Undefined();
}
if (((Double) nx).compareTo((Double) ny) == 0) {
return false;
}
if ((Double.compare((Double) nx, -0.0) == 0) && (Double.compare((Double) ny, 0.0) == 0)) {
return false;
}
if ((Double.compare((Double) nx, 0.0) == 0) && (Double.compare((Double) ny, -0.0) == 0)) {
return false;
}
if (nx.isInfinite() && nx > 0) {
return false;
}
if (ny.isInfinite() && ny > 0) {
return true;
}
if (nx.isInfinite() && nx < 0) {
return false;
}
if (ny.isInfinite() && ny < 0) {
return true;
}
if (nx.compareTo(ny) < 0) {
return true;
}
return false;
} else {//Both are STRING
String sx = (String) px;
String sy = (String) py;
if (sx.startsWith(sy)) {
return false;
}
if (sy.startsWith(sx)) {
return true;
}
int len = sx.length() > sy.length() ? sx.length() : sy.length();
for (int k = 0; k < len; k++) {
int m = 0;
int n = 0;
if (sx.length() > k) {
m = sx.charAt(k);
}
if (sy.length() > k) {
n = sy.charAt(k);
}
if (m != n) {
if (m < n) {
return true;
} else {
return false;
}
}
}
return false;
}
}
public static boolean equals(Object x, Object y) {
EcmaType typeX = type(x);
EcmaType typeY = type(y);
if (typeX == typeY) {
if (typeX == null) {
return true;
}
if (typeX == EcmaType.NULL) {
return true;
}
if (typeX == EcmaType.UNDEFINED) {
return true;
}
if (typeX == EcmaType.NUMBER) {
if (x instanceof Integer) {
x = Double.valueOf((Integer) x);
}
if (x instanceof Long) {
x = Double.valueOf((Long) x);
}
if (y instanceof Integer) {
y = Double.valueOf((Integer) y);
}
if (y instanceof Long) {
y = Double.valueOf((Long) y);
}
if (((Double) x).isNaN()) {
return false;
}
if (((Double) y).isNaN()) {
return false;
}
if (((Double) x).compareTo((Double) y) == 0) {
return true;
}
if ((Double.compare((Double) x, -0.0) == 0) && (Double.compare((Double) y, 0.0) == 0)) {
return true;
}
if ((Double.compare((Double) x, 0.0) == 0) && (Double.compare((Double) y, -0.0) == 0)) {
return true;
}
return false;
}
if (typeX == EcmaType.STRING) {
return ((String) x).equals((String) y);
}
if (typeX == EcmaType.BOOLEAN) {
return x == y;
}
return x == y;
}
if ((typeX == EcmaType.NULL) && (typeY == EcmaType.UNDEFINED)) {
return true;
}
if ((typeX == EcmaType.UNDEFINED) && (typeY == EcmaType.NULL)) {
return true;
}
if ((typeX == EcmaType.NUMBER) && (typeY == EcmaType.STRING)) {
return equals(x, toNumber(y));
}
if ((typeX == EcmaType.STRING) && (typeY == EcmaType.NUMBER)) {
return equals(toNumber(x), y);
}
if (typeX == EcmaType.BOOLEAN) {
return equals(toNumber(x), y);
}
if (typeY == EcmaType.BOOLEAN) {
return equals(x, toNumber(y));
}
if (typeX == EcmaType.STRING || typeX == EcmaType.NUMBER) {
//y is object
//return ecmaEquals(ecmaToPrimitive(x), y);
}
if (typeY == EcmaType.STRING || typeY == EcmaType.NUMBER) {
//x is object
//return ecmaEquals(x, ecmaToPrimitive(y));
}
return false;
}
public static boolean toBoolean(Object o) {
if (o == null) {
return false;
}
if (o instanceof Undefined) {
return false;
}
if (o instanceof Null) {
return false;
}
if (o instanceof Boolean) {
return (Boolean) o;
}
if (o instanceof Long) {
return ((Long) o) != 0;
}
if (o instanceof Integer) {
return ((Integer) o) != 0;
}
if (o instanceof Double) {
Double d = (Double) o;
if (d.isNaN()) {
return false;
}
if (Double.compare(d, 0) == 0) {
return false;
}
return true;
}
if (o instanceof String) {
String s = (String) o;
return !s.equals("");
}
return true; //other Object
}
public static Long toUint32(Object o) {
Double n = toNumber(o);
if (n.isNaN()) {
return 0L;
}
if (Double.compare(n, 0.0) == 0) {
return 0L;
}
if (Double.compare(n, -0.0) == 0) {
return 0L;
}
if (Double.isInfinite(n)) {
return 0L;
}
Long posInt = (long) (double) (Math.signum(n) * Math.floor(Math.abs(n)));
posInt = posInt % (1 << 32);
return posInt;
}
}
@@ -0,0 +1,31 @@
/*
* Copyright (C) 2013 JPEXS
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.jpexs.decompiler.flash.ecma;
/**
*
* @author JPEXS
*/
public enum EcmaType {
NULL,
STRING,
NUMBER,
UNDEFINED,
OBJECT,
BOOLEAN
}
@@ -14,7 +14,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.jpexs.decompiler.flash.action.swf4;
package com.jpexs.decompiler.flash.ecma;
public class Null {
@@ -14,7 +14,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.jpexs.decompiler.flash.action.swf4;
package com.jpexs.decompiler.flash.ecma;
public class Undefined {
@@ -126,4 +126,16 @@ public abstract class BinaryOpItem extends GraphTargetItem {
}
return true;
}
/*@Override
public boolean toBoolean() {
double val=toNumber();
if(Double.isNaN(val)){
return false;
}
if(Double.compare(val, 0)==0){
return false;
}
return true;
}*/
}
@@ -30,13 +30,8 @@ public class DuplicateItem extends GraphTargetItem {
}
@Override
public boolean toBoolean() {
return value.toBoolean();
}
@Override
public double toNumber() {
return value.toNumber();
public Object getResult() {
return value.getResult();
}
@Override
@@ -54,6 +54,9 @@ public abstract class GraphTargetItem {
List<GraphSourceItemPos> ret = new ArrayList<>();
ret.add(new GraphSourceItemPos(src, pos));
ret.addAll(moreSrc);
if (value != null) {
ret.addAll(value.getNeededSources());
}
return ret;
}
@@ -111,12 +114,15 @@ public abstract class GraphTargetItem {
return false;
}
public double toNumber() {
return 0;
}
/*public double toNumber() {
return 0;
}
public boolean toBoolean() {
return Double.compare(toNumber(), 0.0) != 0;
public boolean toBoolean() {
return Double.compare(toNumber(), 0.0) != 0;
}*/
public Object getResult() {
return null;
}
public String toStringNoQuotes(List<Object> localData) {
@@ -1,5 +1,7 @@
package com.jpexs.decompiler.flash.graph;
import com.jpexs.decompiler.flash.ecma.EcmaScript;
/**
*
* @author JPEXS
@@ -11,11 +13,22 @@ public class NotItem extends UnaryOpItem implements LogicalOpItem {
}
@Override
public boolean toBoolean() {
boolean ret = !value.toBoolean();
public Object getResult() {
Object ret = EcmaScript.toBoolean(value.getResult());
if (ret == Boolean.TRUE) {
return Boolean.FALSE;
}
if (ret == Boolean.FALSE) {
return Boolean.TRUE;
}
return ret;
}
@Override
public boolean isCompileTime() {
return value.isCompileTime();
}
@Override
public GraphTargetItem invert() {
return value;
@@ -526,7 +526,7 @@ public class MainFrame extends AppFrame implements ActionListener, TreeSelection
abcList = new ArrayList<>();
getActionScript3(objs, abcList);
if (!abcList.isEmpty()) {
abcPanel = new ABCPanel(abcList);
abcPanel = new ABCPanel(abcList, swf);
detailPanel.add(abcPanel.tabbedPane, DETAILCARDAS3NAVIGATOR);
menuTools.add(miGotoDocumentClass);
} else {
@@ -17,6 +17,8 @@
package com.jpexs.decompiler.flash.gui.abc;
import com.jpexs.decompiler.flash.Configuration;
import com.jpexs.decompiler.flash.KeyValue;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.abc.ABC;
import com.jpexs.decompiler.flash.abc.ClassPath;
import com.jpexs.decompiler.flash.abc.ScriptPack;
@@ -42,7 +44,6 @@ import java.awt.event.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -91,7 +92,7 @@ public class ABCPanel extends JPanel implements ItemListener, ActionListener {
searchIgnoreCase = ignoreCase;
searchRegexp = regexp;
ClassesListTreeModel clModel = (ClassesListTreeModel) classTree.getModel();
HashMap<ClassPath, ScriptPack> allpacks = clModel.getList();
List<KeyValue<ClassPath, ScriptPack>> allpacks = clModel.getList();
found = new ArrayList<>();
Pattern pat = null;
if (regexp) {
@@ -99,10 +100,10 @@ public class ABCPanel extends JPanel implements ItemListener, ActionListener {
} else {
pat = Pattern.compile(Pattern.quote(txt), ignoreCase ? Pattern.CASE_INSENSITIVE : 0);
}
for (ScriptPack p : allpacks.values()) {
decompiledTextArea.cacheScriptPack(p, list);
if (pat.matcher(decompiledTextArea.getCachedText(p)).find()) {
found.add(p);
for (KeyValue<ClassPath, ScriptPack> item : allpacks) {
decompiledTextArea.cacheScriptPack(item.value, list);
if (pat.matcher(decompiledTextArea.getCachedText(item.value)).find()) {
found.add(item.value);
}
}
@@ -238,7 +239,7 @@ public class ABCPanel extends JPanel implements ItemListener, ActionListener {
}
@SuppressWarnings("unchecked")
public ABCPanel(List<ABCContainerTag> list) {
public ABCPanel(List<ABCContainerTag> list, SWF swf) {
DefaultSyntaxKit.initKit();
@@ -339,7 +340,7 @@ public class ABCPanel extends JPanel implements ItemListener, ActionListener {
JPanel treePanel = new JPanel();
treePanel.setLayout(new BorderLayout());
treePanel.add(new JScrollPane(classTree = new ClassesListTree(list, this)), BorderLayout.CENTER);
treePanel.add(new JScrollPane(classTree = new ClassesListTree(list, this, swf)), BorderLayout.CENTER);
JPanel filterPanel = new JPanel();
filterPanel.setLayout(new BorderLayout());
filterPanel.add(filterField, BorderLayout.CENTER);
@@ -466,17 +467,13 @@ public class ABCPanel extends JPanel implements ItemListener, ActionListener {
public void hilightScript(String name) {
ClassesListTreeModel clModel = (ClassesListTreeModel) classTree.getModel();
HashMap<ClassPath, ScriptPack> list = clModel.getList();
ClassPath path = null;
for (ClassPath p : list.keySet()) {
if (p.toString().equals(name)) {
path = p;
ScriptPack pack = null;
for (KeyValue<ClassPath, ScriptPack> item : clModel.getList()) {
if (item.key.toString().equals(name)) {
pack = item.value;
break;
}
}
if (path == null) {
return;
}
ScriptPack pack = clModel.getList().get(path);
if (pack != null) {
hilightScript(pack);
}

Some files were not shown because too many files have changed in this diff Show More