mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-09-25 07:30:48 +00:00
AS2: p-code deobfuscation
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
package com.jpexs.asdec;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class ReReadableInputStream extends InputStream {
|
||||
|
||||
InputStream is;
|
||||
ByteArrayOutputStream baos=new ByteArrayOutputStream();
|
||||
byte []converted;
|
||||
int pos=0;
|
||||
int count=0;
|
||||
|
||||
public byte[] getAllRead(){
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
public int getPos() {
|
||||
return pos;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public ReReadableInputStream(InputStream is) {
|
||||
this.is=is;
|
||||
}
|
||||
|
||||
|
||||
public void setPos(int pos) throws IOException{
|
||||
if(pos>count){
|
||||
skip(pos-count);
|
||||
}
|
||||
this.pos=pos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
if(pos<count){
|
||||
if(converted==null){
|
||||
converted=baos.toByteArray();
|
||||
}
|
||||
int ret=converted[pos]&0xff;
|
||||
pos++;
|
||||
return ret;
|
||||
}
|
||||
int i= is.read();
|
||||
baos.write(i);
|
||||
count++;
|
||||
pos++;
|
||||
converted=null;
|
||||
return i;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int available() throws IOException {
|
||||
return (pos<count?count-pos:0)+is.available();
|
||||
}
|
||||
}
|
||||
@@ -16,13 +16,18 @@
|
||||
*/
|
||||
package com.jpexs.asdec;
|
||||
|
||||
import com.jpexs.asdec.abc.avm2.instructions.other.NopIns;
|
||||
import com.jpexs.asdec.action.Action;
|
||||
import com.jpexs.asdec.action.special.ActionNop;
|
||||
import com.jpexs.asdec.action.swf3.*;
|
||||
import com.jpexs.asdec.action.swf4.*;
|
||||
import com.jpexs.asdec.action.swf5.*;
|
||||
import com.jpexs.asdec.action.swf6.*;
|
||||
import com.jpexs.asdec.action.swf7.*;
|
||||
import com.jpexs.asdec.action.treemodel.ConstantPool;
|
||||
import com.jpexs.asdec.action.treemodel.TreeItem;
|
||||
import com.jpexs.asdec.helpers.Helper;
|
||||
import com.jpexs.asdec.helpers.Highlighting;
|
||||
import com.jpexs.asdec.tags.*;
|
||||
import com.jpexs.asdec.types.*;
|
||||
import com.jpexs.asdec.types.filters.*;
|
||||
@@ -31,11 +36,13 @@ import com.jpexs.asdec.types.shaperecords.EndShapeRecord;
|
||||
import com.jpexs.asdec.types.shaperecords.SHAPERECORD;
|
||||
import com.jpexs.asdec.types.shaperecords.StraightEdgeRecord;
|
||||
import com.jpexs.asdec.types.shaperecords.StyleChangeRecord;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
import java.util.logging.Logger;
|
||||
@@ -54,6 +61,31 @@ public class SWFInputStream extends InputStream {
|
||||
private static final Logger log = Logger.getLogger(SWFInputStream.class.getName());
|
||||
private List<PercentListener> listeners = new ArrayList<PercentListener>();
|
||||
private long percentMax;
|
||||
private List<byte[]> buffered = new ArrayList<byte[]>();
|
||||
private ByteArrayOutputStream buffer;
|
||||
|
||||
public int getBufferLength() {
|
||||
return buffer.size();
|
||||
}
|
||||
|
||||
public void startBuffer() {
|
||||
stopBuffer();
|
||||
buffer = new ByteArrayOutputStream();
|
||||
}
|
||||
|
||||
public byte[] getBuffer() {
|
||||
return buffer.toByteArray();
|
||||
}
|
||||
|
||||
public byte[] stopBuffer() {
|
||||
if (buffer != null) {
|
||||
byte[] ret = buffer.toByteArray();
|
||||
buffered.add(ret);
|
||||
buffer = null;
|
||||
return ret;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void addPercentListener(PercentListener listener) {
|
||||
listeners.add(listener);
|
||||
@@ -448,14 +480,118 @@ public class SWFInputStream extends InputStream {
|
||||
* @throws IOException
|
||||
*/
|
||||
public List<Action> readActionList() throws IOException {
|
||||
List<Action> retdups = new ArrayList<Action>();
|
||||
ConstantPool cpool = null;
|
||||
|
||||
Stack<TreeItem> stack = new Stack<TreeItem>();
|
||||
|
||||
ReReadableInputStream rri = new ReReadableInputStream(this);
|
||||
SWFInputStream sis = new SWFInputStream(rri, version);
|
||||
readActionListAtPos(stack, cpool, sis, rri, 0, retdups);
|
||||
List<Action> ret = new ArrayList<Action>();
|
||||
Action a;
|
||||
while ((a = readAction()) != null) {
|
||||
ret.add(a);
|
||||
Action last = null;
|
||||
for (Action a : retdups) {
|
||||
if (a != last) {
|
||||
ret.add(a);
|
||||
}
|
||||
last = a;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private void readActionListAtPos(Stack<TreeItem> stack, ConstantPool cpool, SWFInputStream sis, ReReadableInputStream rri, int ip, List<Action> ret) throws IOException {
|
||||
rri.setPos(ip);
|
||||
Action a;
|
||||
List<TreeItem> output = new ArrayList<TreeItem>();
|
||||
long filePos = rri.getPos();
|
||||
while ((a = sis.readAction()) != null) {
|
||||
if (a instanceof ActionPush) {
|
||||
if (cpool != null) {
|
||||
((ActionPush) a).constantPool = cpool.constants;
|
||||
}
|
||||
}
|
||||
if (a instanceof ActionDefineFunction) {
|
||||
if (cpool != null) {
|
||||
((ActionDefineFunction) a).setConstantPool(cpool.constants);
|
||||
}
|
||||
}
|
||||
if (a instanceof ActionDefineFunction2) {
|
||||
if (cpool != null) {
|
||||
((ActionDefineFunction2) a).setConstantPool(cpool.constants);
|
||||
}
|
||||
}
|
||||
long newFilePos = rri.getPos();
|
||||
long actionLen = newFilePos - filePos;
|
||||
|
||||
ensureCapacity(ret, ip);
|
||||
int newip = -1;
|
||||
if (!(ret.get(ip) instanceof ActionNop)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (a instanceof ActionConstantPool) {
|
||||
if (cpool == null) {
|
||||
cpool = new ConstantPool();
|
||||
}
|
||||
cpool.constants = ((ActionConstantPool) a).constantPool;
|
||||
}
|
||||
Action beforeInsert = null;
|
||||
ActionIf aif = null;
|
||||
boolean goaif = false;
|
||||
if (a instanceof ActionIf) {
|
||||
aif = (ActionIf) a;
|
||||
TreeItem top = stack.pop();
|
||||
if (top.isCompileTime()) {
|
||||
if (top.toBoolean()) {
|
||||
newip = rri.getPos() + aif.offset;
|
||||
rri.setPos(newip);
|
||||
a = new ActionJump(aif.offset);
|
||||
} else {
|
||||
a = new ActionNop();
|
||||
}
|
||||
beforeInsert = new ActionPop();
|
||||
} else {
|
||||
goaif = true;
|
||||
}
|
||||
} else if (a instanceof ActionJump) {
|
||||
newip = rri.getPos() + ((ActionJump) a).offset;
|
||||
rri.setPos(newip);
|
||||
} else {
|
||||
a.translate(stack, cpool, output, new HashMap<Integer, String>());
|
||||
}
|
||||
for (int i = 0; i < actionLen; i++) {
|
||||
ensureCapacity(ret, ip + i);
|
||||
if (a instanceof ActionNop) {
|
||||
a = new ActionNop();
|
||||
if (i == 0) {
|
||||
a.beforeInsert = beforeInsert;
|
||||
}
|
||||
} else {
|
||||
a.beforeInsert = beforeInsert;
|
||||
}
|
||||
ret.set(ip + i, a);
|
||||
}
|
||||
|
||||
if (newip > -1) {
|
||||
ip = newip;
|
||||
} else {
|
||||
ip = ip + (int) actionLen;
|
||||
}
|
||||
filePos = rri.getPos();
|
||||
if (goaif) {
|
||||
int oldPos = rri.getPos();
|
||||
readActionListAtPos(stack, cpool, sis, rri, rri.getPos() + aif.offset, ret);
|
||||
rri.setPos(oldPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ensureCapacity(List<Action> ret, int index) {
|
||||
while (ret.size() <= index) {
|
||||
ret.add(new ActionNop());
|
||||
}
|
||||
}
|
||||
|
||||
private static void dumpTag(PrintStream out, int version, Tag tag, int level) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(Helper.formatHex((int) tag.getPos(), 8));
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.jpexs.asdec.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.asdec.helpers.Highlighting;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public abstract class TreeItem {
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.jpexs.asdec.SWFOutputStream;
|
||||
import com.jpexs.asdec.action.parser.FlasmLexer;
|
||||
import com.jpexs.asdec.action.parser.ParseException;
|
||||
import com.jpexs.asdec.action.parser.ParsedSymbol;
|
||||
import com.jpexs.asdec.action.special.ActionNop;
|
||||
import com.jpexs.asdec.action.swf4.*;
|
||||
import com.jpexs.asdec.action.swf5.*;
|
||||
import com.jpexs.asdec.action.swf6.ActionEnumerate2;
|
||||
@@ -46,6 +47,7 @@ import java.util.logging.Logger;
|
||||
*/
|
||||
public class Action {
|
||||
|
||||
public Action beforeInsert;
|
||||
/**
|
||||
* Action type identifier
|
||||
*/
|
||||
@@ -361,29 +363,17 @@ public class Action {
|
||||
}
|
||||
|
||||
offset = 0;
|
||||
if (Main.LATEST_CONSTANTPOOL_HACK) {
|
||||
for (Action a : list) {
|
||||
if (a instanceof ActionConstantPool) {
|
||||
constantPool.clear();
|
||||
constantPool.addAll(((ActionConstantPool) a).constantPool);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Action a : list) {
|
||||
if (!Main.LATEST_CONSTANTPOOL_HACK) {
|
||||
if (a instanceof ActionConstantPool) {
|
||||
constantPool.clear();
|
||||
constantPool.addAll(((ActionConstantPool) a).constantPool);
|
||||
}
|
||||
}
|
||||
if (a instanceof ActionPush) {
|
||||
((ActionPush) a).constantPool = constantPool;
|
||||
}
|
||||
for (Action a : list) {
|
||||
offset = a.getAddress();
|
||||
if (importantOffsets.contains(offset)) {
|
||||
ret += "loc" + Helper.formatAddress(offset) + ":";
|
||||
}
|
||||
ret += Highlighting.hilighOffset("", offset) + a.getASMSource(importantOffsets, constantPool, version) + "\r\n";
|
||||
if(a.beforeInsert!=null){
|
||||
ret+=a.beforeInsert.getASMSource(importantOffsets, constantPool, version) + "\r\n";
|
||||
}
|
||||
if(!(a instanceof ActionNop)){
|
||||
ret += Highlighting.hilighOffset("", offset) + a.getASMSource(importantOffsets, constantPool, version) + "\r\n";
|
||||
}
|
||||
offset += a.getBytes(version).length;
|
||||
}
|
||||
if (importantOffsets.contains(offset)) {
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.asdec.action.special;
|
||||
|
||||
import com.jpexs.asdec.action.Action;
|
||||
import com.jpexs.asdec.action.treemodel.ConstantPool;
|
||||
import com.jpexs.asdec.action.treemodel.SimpleActionTreeItem;
|
||||
import com.jpexs.asdec.action.treemodel.TreeItem;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class ActionNop extends Action {
|
||||
|
||||
public ActionNop() {
|
||||
super(-1, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Nop";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
output.add(new SimpleActionTreeItem(this, "nop();"));
|
||||
}
|
||||
}
|
||||
@@ -71,5 +71,5 @@ public class ActionGetURL extends Action {
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
output.add(new GetURLTreeItem(this, urlString, targetString));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,12 @@ public class ActionJump extends Action {
|
||||
public int offset;
|
||||
public String identifier;
|
||||
|
||||
public ActionJump(int offset){
|
||||
super(0x99,2);
|
||||
this.offset=offset;
|
||||
}
|
||||
|
||||
|
||||
public ActionJump(SWFInputStream sis) throws IOException {
|
||||
super(0x99, 2);
|
||||
offset = sis.readSI16();
|
||||
@@ -76,4 +82,11 @@ public class ActionJump extends Action {
|
||||
ret.add(this);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Jump";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -201,7 +201,11 @@ public class ActionPush extends Action {
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
|
||||
for (Object o : values) {
|
||||
if (o instanceof ConstantIndex) {
|
||||
o = constants.constants.get(((ConstantIndex) o).index);
|
||||
if((constants==null)||(((ConstantIndex) o).index>=constants.constants.size())){
|
||||
o="CONSTNOTFOUND";
|
||||
}else{
|
||||
o = constants.constants.get(((ConstantIndex) o).index);
|
||||
}
|
||||
}
|
||||
if (o instanceof RegisterNumber) {
|
||||
if (regNames.containsKey(((RegisterNumber) o).number)) {
|
||||
|
||||
@@ -28,7 +28,7 @@ public class ConstantIndex {
|
||||
|
||||
public ConstantIndex(int index) {
|
||||
this.index = index;
|
||||
this.constantPool = new ArrayList<String>();
|
||||
this.constantPool = new ArrayList<String>();
|
||||
}
|
||||
|
||||
public ConstantIndex(int index, List<String> constantPool) {
|
||||
|
||||
@@ -23,12 +23,19 @@ import com.jpexs.asdec.action.parser.ASMParser;
|
||||
import com.jpexs.asdec.action.parser.FlasmLexer;
|
||||
import com.jpexs.asdec.action.parser.Label;
|
||||
import com.jpexs.asdec.action.parser.ParseException;
|
||||
import com.jpexs.asdec.action.swf4.ActionPush;
|
||||
import com.jpexs.asdec.action.swf7.ActionDefineFunction2;
|
||||
import com.jpexs.asdec.action.treemodel.ConstantPool;
|
||||
import com.jpexs.asdec.action.treemodel.FunctionTreeItem;
|
||||
import com.jpexs.asdec.action.treemodel.TreeItem;
|
||||
import com.jpexs.asdec.helpers.Helper;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class ActionDefineFunction extends Action {
|
||||
|
||||
@@ -36,9 +43,24 @@ public class ActionDefineFunction extends Action {
|
||||
public List<String> paramNames = new ArrayList<String>();
|
||||
public List<Action> code;
|
||||
public int codeSize;
|
||||
private int version;
|
||||
|
||||
public void setConstantPool(List<String> constantPool){
|
||||
for(Action a:code){
|
||||
if(a instanceof ActionPush){
|
||||
((ActionPush)a).constantPool=constantPool;
|
||||
}
|
||||
if(a instanceof ActionDefineFunction2){
|
||||
((ActionDefineFunction2)a).setConstantPool(constantPool);
|
||||
}
|
||||
if(a instanceof ActionDefineFunction){
|
||||
((ActionDefineFunction)a).setConstantPool(constantPool);
|
||||
}
|
||||
}
|
||||
}
|
||||
public ActionDefineFunction(int actionLength, SWFInputStream sis, int version) throws IOException {
|
||||
super(0x9B, actionLength);
|
||||
this.version=version;
|
||||
//byte data[]=sis.readBytes(actionLength);
|
||||
//sis=new SWFInputStream(new ByteArrayInputStream(data),version);
|
||||
functionName = sis.readString();
|
||||
@@ -127,4 +149,10 @@ public class ActionDefineFunction extends Action {
|
||||
public List<Action> getAllIfsOrJumps() {
|
||||
return Action.getActionsAllIfsOrJumps(code);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, HashMap<Integer, String> regNames) {
|
||||
stack.push(new FunctionTreeItem(this, functionName, paramNames, Action.actionsToTree(regNames, code,version ), constants));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,12 +23,19 @@ import com.jpexs.asdec.action.parser.ASMParser;
|
||||
import com.jpexs.asdec.action.parser.FlasmLexer;
|
||||
import com.jpexs.asdec.action.parser.Label;
|
||||
import com.jpexs.asdec.action.parser.ParseException;
|
||||
import com.jpexs.asdec.action.swf4.ActionPush;
|
||||
import com.jpexs.asdec.action.swf5.ActionDefineFunction;
|
||||
import com.jpexs.asdec.action.treemodel.ConstantPool;
|
||||
import com.jpexs.asdec.action.treemodel.FunctionTreeItem;
|
||||
import com.jpexs.asdec.action.treemodel.TreeItem;
|
||||
import com.jpexs.asdec.helpers.Helper;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class ActionDefineFunction2 extends Action {
|
||||
|
||||
@@ -47,9 +54,25 @@ public class ActionDefineFunction2 extends Action {
|
||||
public int registerCount;
|
||||
public int codeSize;
|
||||
public List<Action> code;
|
||||
private int version;
|
||||
|
||||
public void setConstantPool(List<String> constantPool){
|
||||
for(Action a:code){
|
||||
if(a instanceof ActionPush){
|
||||
((ActionPush)a).constantPool=constantPool;
|
||||
}
|
||||
if(a instanceof ActionDefineFunction2){
|
||||
((ActionDefineFunction2)a).setConstantPool(constantPool);
|
||||
}
|
||||
if(a instanceof ActionDefineFunction){
|
||||
((ActionDefineFunction)a).setConstantPool(constantPool);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ActionDefineFunction2(int actionLength, SWFInputStream sis, int version) throws IOException {
|
||||
super(0x8E, actionLength);
|
||||
this.version=version;
|
||||
functionName = sis.readString();
|
||||
int numParams = sis.readUI16();
|
||||
registerCount = sis.readUI8();
|
||||
@@ -185,6 +208,18 @@ public class ActionDefineFunction2 extends Action {
|
||||
+ " " + preloadGlobalFlag).trim() + " " + paramStr + " {\r\n" + Action.actionsToString(code, knownAddreses, constantPool, version) + "}";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DefineFunction2";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, HashMap<Integer, String> regNames) {
|
||||
stack.push(new FunctionTreeItem(this, functionName, paramNames, Action.actionsToTree(regNames, code,version ), constants));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public List<Long> getAllRefs(int version) {
|
||||
return Action.getActionsAllRefs(code, version);
|
||||
|
||||
@@ -31,4 +31,16 @@ public class DecrementTreeItem extends TreeItem {
|
||||
public String toString(ConstantPool constants) {
|
||||
return object.toString(constants) + hilight("-1");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCompileTime(){
|
||||
return object.isCompileTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double toNumber() {
|
||||
return object.toNumber()-1;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -34,6 +34,29 @@ public class DirectValueTreeItem extends TreeItem {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double toNumber() {
|
||||
if(value instanceof Double){
|
||||
return (Double)value;
|
||||
}
|
||||
if(value instanceof Float){
|
||||
return (Float)value;
|
||||
}
|
||||
if(value instanceof Long){
|
||||
return (Long)value;
|
||||
}
|
||||
return super.toNumber();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean toBoolean() {
|
||||
boolean ret=(value instanceof Boolean)?(Boolean)value:false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public String toStringNoQuotes(ConstantPool constants) {
|
||||
if (value instanceof Double) {
|
||||
@@ -75,4 +98,9 @@ public class DirectValueTreeItem extends TreeItem {
|
||||
}
|
||||
return hilight(value.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCompileTime(){
|
||||
return (value instanceof Double)||(value instanceof Float)||(value instanceof Boolean)||(value instanceof Long);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ public class FunctionTreeItem extends TreeItem {
|
||||
public FunctionTreeItem(Action instruction, String functionName, List<String> paramNames, List<TreeItem> actions, ConstantPool constants) {
|
||||
super(instruction, PRECEDENCE_PRIMARY);
|
||||
this.actions = actions;
|
||||
this.constants = constants.constants;
|
||||
this.constants = constants==null?null:constants.constants;
|
||||
this.functionName = functionName;
|
||||
this.paramNames = paramNames;
|
||||
}
|
||||
|
||||
@@ -31,4 +31,16 @@ public class IncrementTreeItem extends TreeItem {
|
||||
public String toString(ConstantPool constants) {
|
||||
return object.toString(constants) + hilight("+1");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCompileTime(){
|
||||
return object.isCompileTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double toNumber() {
|
||||
return object.toNumber()+1;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -96,4 +96,17 @@ public abstract class TreeItem {
|
||||
return target.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isCompileTime(){
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public double toNumber(){
|
||||
return 0;
|
||||
}
|
||||
|
||||
public boolean toBoolean(){
|
||||
return Double.compare(toNumber(),0.0)!=0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,4 +24,11 @@ public class AddTreeItem extends BinaryOpTreeItem {
|
||||
public AddTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) {
|
||||
super(instruction, PRECEDENCE_ADDITIVE, leftSide, rightSide, "+");
|
||||
}
|
||||
|
||||
@Override
|
||||
public double toNumber() {
|
||||
return leftSide.toNumber()+rightSide.toNumber();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -24,4 +24,11 @@ public class AndTreeItem extends BinaryOpTreeItem {
|
||||
public AndTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) {
|
||||
super(instruction, PRECEDENCE_LOGICALAND, leftSide, rightSide, "&&");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean toBoolean() {
|
||||
return leftSide.toBoolean()&&rightSide.toBoolean();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -24,4 +24,11 @@ public class AsTypeTreeItem extends BinaryOpTreeItem {
|
||||
public AsTypeTreeItem(Action instruction, TreeItem value, TreeItem type) {
|
||||
super(instruction, PRECEDENCE_RELATIONAL, value, type, " as ");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCompileTime() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -49,4 +49,8 @@ public abstract class BinaryOpTreeItem extends TreeItem {
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@Override
|
||||
public boolean isCompileTime(){
|
||||
return leftSide.isCompileTime()&&rightSide.isCompileTime();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,4 +24,9 @@ public class BitAndTreeItem extends BinaryOpTreeItem {
|
||||
public BitAndTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) {
|
||||
super(instruction, PRECEDENCE_BITWISEAND, leftSide, rightSide, "&");
|
||||
}
|
||||
|
||||
@Override
|
||||
public double toNumber() {
|
||||
return ((int)leftSide.toNumber())&((int)rightSide.toNumber());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,4 +24,11 @@ public class BitNotTreeItem extends UnaryOpTreeItem {
|
||||
public BitNotTreeItem(Action instruction, TreeItem value) {
|
||||
super(instruction, PRECEDENCE_UNARY, value, "~");
|
||||
}
|
||||
|
||||
@Override
|
||||
public double toNumber() {
|
||||
return ~((int)value.toNumber());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -24,4 +24,9 @@ public class BitOrTreeItem extends BinaryOpTreeItem {
|
||||
public BitOrTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) {
|
||||
super(instruction, PRECEDENCE_BITWISEOR, leftSide, rightSide, "|");
|
||||
}
|
||||
|
||||
@Override
|
||||
public double toNumber() {
|
||||
return ((int)leftSide.toNumber())|((int)rightSide.toNumber());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,4 +24,9 @@ public class BitXorTreeItem extends BinaryOpTreeItem {
|
||||
public BitXorTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) {
|
||||
super(instruction, PRECEDENCE_BITWISEXOR, leftSide, rightSide, "^");
|
||||
}
|
||||
|
||||
@Override
|
||||
public double toNumber() {
|
||||
return ((int)leftSide.toNumber())^((int)rightSide.toNumber());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,4 +24,9 @@ public class DivideTreeItem extends BinaryOpTreeItem {
|
||||
public DivideTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) {
|
||||
super(instruction, PRECEDENCE_MULTIPLICATIVE, leftSide, rightSide, "/");
|
||||
}
|
||||
|
||||
@Override
|
||||
public double toNumber() {
|
||||
return leftSide.toNumber()/rightSide.toNumber();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,4 +24,11 @@ public class EqTreeItem extends BinaryOpTreeItem {
|
||||
public EqTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) {
|
||||
super(instruction, PRECEDENCE_EQUALITY, leftSide, rightSide, "==");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean toBoolean() {
|
||||
return (leftSide.toBoolean()==rightSide.toBoolean())&&(leftSide.toNumber()==rightSide.toNumber());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -24,4 +24,11 @@ public class GeTreeItem extends BinaryOpTreeItem {
|
||||
public GeTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) {
|
||||
super(instruction, PRECEDENCE_RELATIONAL, leftSide, rightSide, ">=");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean toBoolean() {
|
||||
return leftSide.toNumber()>=rightSide.toNumber();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -24,4 +24,9 @@ public class GtTreeItem extends BinaryOpTreeItem {
|
||||
public GtTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) {
|
||||
super(instruction, PRECEDENCE_RELATIONAL, leftSide, rightSide, ">");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean toBoolean() {
|
||||
return leftSide.toNumber()>rightSide.toNumber();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,4 +24,11 @@ public class InTreeItem extends BinaryOpTreeItem {
|
||||
public InTreeItem(Action instruction, TreeItem name, TreeItem object) {
|
||||
super(instruction, PRECEDENCE_RELATIONAL, name, object, " in ");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCompileTime() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -24,4 +24,11 @@ public class InstanceOfTreeItem extends BinaryOpTreeItem {
|
||||
public InstanceOfTreeItem(Action instruction, TreeItem value, TreeItem type) {
|
||||
super(instruction, PRECEDENCE_RELATIONAL, value, type, " instanceof ");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCompileTime() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -24,4 +24,11 @@ public class IsTypeTreeItem extends BinaryOpTreeItem {
|
||||
public IsTypeTreeItem(Action instruction, TreeItem value, TreeItem type) {
|
||||
super(instruction, PRECEDENCE_RELATIONAL, value, type, " is ");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCompileTime() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -24,4 +24,9 @@ public class LShiftTreeItem extends BinaryOpTreeItem {
|
||||
public LShiftTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) {
|
||||
super(instruction, PRECEDENCE_BITWISESHIFT, leftSide, rightSide, "<<");
|
||||
}
|
||||
|
||||
@Override
|
||||
public double toNumber() {
|
||||
return ((int)leftSide.toNumber())<<((int)rightSide.toNumber());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,4 +24,9 @@ public class LeTreeItem extends BinaryOpTreeItem {
|
||||
public LeTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) {
|
||||
super(instruction, PRECEDENCE_RELATIONAL, leftSide, rightSide, "<=");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean toBoolean() {
|
||||
return leftSide.toNumber()<=rightSide.toNumber();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,4 +24,9 @@ public class LtTreeItem extends BinaryOpTreeItem {
|
||||
public LtTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) {
|
||||
super(instruction, PRECEDENCE_RELATIONAL, leftSide, rightSide, "<");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean toBoolean() {
|
||||
return leftSide.toNumber()<rightSide.toNumber();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,4 +24,9 @@ public class ModuloTreeItem extends BinaryOpTreeItem {
|
||||
public ModuloTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) {
|
||||
super(instruction, PRECEDENCE_MULTIPLICATIVE, leftSide, rightSide, "%");
|
||||
}
|
||||
|
||||
@Override
|
||||
public double toNumber() {
|
||||
return ((int)leftSide.toNumber())%((int)rightSide.toNumber());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,4 +24,9 @@ public class MultiplyTreeItem extends BinaryOpTreeItem {
|
||||
public MultiplyTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) {
|
||||
super(instruction, PRECEDENCE_MULTIPLICATIVE, leftSide, rightSide, "*");
|
||||
}
|
||||
|
||||
@Override
|
||||
public double toNumber() {
|
||||
return leftSide.toNumber()*rightSide.toNumber();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,4 +24,11 @@ public class NegTreeItem extends UnaryOpTreeItem {
|
||||
public NegTreeItem(Action instruction, TreeItem value) {
|
||||
super(instruction, PRECEDENCE_UNARY, value, "-");
|
||||
}
|
||||
|
||||
@Override
|
||||
public double toNumber() {
|
||||
return -value.toNumber();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -24,4 +24,9 @@ public class NeqTreeItem extends BinaryOpTreeItem {
|
||||
public NeqTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) {
|
||||
super(instruction, PRECEDENCE_EQUALITY, leftSide, rightSide, "!=");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean toBoolean() {
|
||||
return (leftSide.toNumber()!=rightSide.toNumber())||(leftSide.toBoolean()!=rightSide.toBoolean());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,4 +34,12 @@ public class NotTreeItem extends UnaryOpTreeItem {
|
||||
public boolean isFalse() {
|
||||
return !value.isFalse();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean toBoolean() {
|
||||
boolean ret= !value.toBoolean();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -24,4 +24,11 @@ public class OrTreeItem extends BinaryOpTreeItem {
|
||||
public OrTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) {
|
||||
super(instruction, PRECEDENCE_LOGICALOR, leftSide, rightSide, "||");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean toBoolean() {
|
||||
return leftSide.toBoolean()||rightSide.toBoolean();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -24,4 +24,11 @@ public class PreDecrementTreeItem extends UnaryOpTreeItem {
|
||||
public PreDecrementTreeItem(Action instruction, TreeItem object) {
|
||||
super(instruction, PRECEDENCE_UNARY, object, "--");
|
||||
}
|
||||
|
||||
@Override
|
||||
public double toNumber() {
|
||||
return value.toNumber()-1;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -24,4 +24,11 @@ public class PreIncrementTreeItem extends UnaryOpTreeItem {
|
||||
public PreIncrementTreeItem(Action instruction, TreeItem object) {
|
||||
super(instruction, PRECEDENCE_UNARY, object, "++");
|
||||
}
|
||||
|
||||
@Override
|
||||
public double toNumber() {
|
||||
return value.toNumber()+1;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -24,4 +24,9 @@ public class RShiftTreeItem extends BinaryOpTreeItem {
|
||||
public RShiftTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) {
|
||||
super(instruction, PRECEDENCE_BITWISESHIFT, leftSide, rightSide, ">>");
|
||||
}
|
||||
|
||||
@Override
|
||||
public double toNumber() {
|
||||
return ((int)leftSide.toNumber())>>((int)rightSide.toNumber());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,4 +24,9 @@ public class StrictEqTreeItem extends BinaryOpTreeItem {
|
||||
public StrictEqTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) {
|
||||
super(instruction, PRECEDENCE_EQUALITY, leftSide, rightSide, "===");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean toBoolean() {
|
||||
return (leftSide.toBoolean()==rightSide.toBoolean())&&(leftSide.toNumber()==rightSide.toNumber());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,4 +24,9 @@ public class StrictNeqTreeItem extends BinaryOpTreeItem {
|
||||
public StrictNeqTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) {
|
||||
super(instruction, PRECEDENCE_EQUALITY, leftSide, rightSide, "!==");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean toBoolean() {
|
||||
return (leftSide.toBoolean()!=rightSide.toBoolean())&&(leftSide.toNumber()!=rightSide.toNumber());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,4 +24,9 @@ public class StringAddTreeItem extends BinaryOpTreeItem {
|
||||
public StringAddTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) {
|
||||
super(instruction, PRECEDENCE_ADDITIVE, leftSide, rightSide, "+");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCompileTime() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,4 +24,11 @@ public class StringEqTreeItem extends BinaryOpTreeItem {
|
||||
public StringEqTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) {
|
||||
super(instruction, PRECEDENCE_EQUALITY, leftSide, rightSide, "==");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCompileTime() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -37,4 +37,9 @@ public class StringLengthTreeItem extends TreeItem {
|
||||
}
|
||||
return s + hilight(".length");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCompileTime() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,4 +24,9 @@ public class StringLtTreeItem extends BinaryOpTreeItem {
|
||||
public StringLtTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) {
|
||||
super(instruction, PRECEDENCE_RELATIONAL, leftSide, rightSide, "<");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCompileTime() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,4 +24,11 @@ public class SubtractTreeItem extends BinaryOpTreeItem {
|
||||
public SubtractTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) {
|
||||
super(instruction, PRECEDENCE_ADDITIVE, leftSide, rightSide, "-");
|
||||
}
|
||||
|
||||
@Override
|
||||
public double toNumber() {
|
||||
return leftSide.toNumber()-rightSide.toNumber();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -24,4 +24,9 @@ public class URShiftTreeItem extends BinaryOpTreeItem {
|
||||
public URShiftTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) {
|
||||
super(instruction, PRECEDENCE_BITWISESHIFT, leftSide, rightSide, ">>>");
|
||||
}
|
||||
|
||||
@Override
|
||||
public double toNumber() {
|
||||
return ((int)leftSide.toNumber())>>>((int)rightSide.toNumber());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,4 +39,9 @@ public abstract class UnaryOpTreeItem extends TreeItem {
|
||||
}
|
||||
return hilight(operator) + s;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCompileTime(){
|
||||
return value.isCompileTime();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user