From 49ef4c0961d6502a5471a1e05c4d2740f3457a42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=F8=EDk?= Date: Mon, 15 Jul 2013 23:07:36 +0200 Subject: [PATCH] AS1/2 Improved direct editing AS1/2 Improved decompilation of various global functions --- .../flash/abc/avm2/treemodel/TreeItem.java | 5 + .../treemodel/clauses/ForEachInTreeItem.java | 5 + .../avm2/treemodel/clauses/ForInTreeItem.java | 5 + .../jpexs/decompiler/flash/action/Action.java | 31 +- .../decompiler/flash/action/ActionGraph.java | 61 + .../parser/script/ActionScriptLexer.java | 1615 +++++++------- .../parser/script/ActionScriptParser.java | 1876 +++++++---------- .../script/ActionScriptSourceGenerator.java | 766 +++++++ .../action/parser/script/LexBufferer.java | 48 + .../action/parser/script/LexListener.java | 28 + .../action/parser/script/SymbolType.java | 11 +- .../action/parser/script/actionscript.flex | 41 +- .../flash/action/swf3/ActionGetURL.java | 10 +- .../flash/action/swf3/ActionGotoFrame.java | 2 +- .../flash/action/swf3/ActionNextFrame.java | 4 +- .../flash/action/swf3/ActionPlay.java | 4 +- .../flash/action/swf3/ActionPrevFrame.java | 4 +- .../flash/action/swf3/ActionSetTarget.java | 5 + .../flash/action/swf3/ActionStop.java | 4 +- .../flash/action/swf3/ActionStopSounds.java | 4 +- .../action/swf3/ActionToggleQuality.java | 4 +- .../flash/action/swf4/ActionEndDrag.java | 4 +- .../flash/action/swf4/ActionGetURL2.java | 24 +- .../flash/action/swf4/ActionPush.java | 5 +- .../flash/action/swf4/ActionStringLength.java | 2 +- .../action/treemodel/AsciiToCharTreeItem.java | 12 + .../treemodel/CallFunctionTreeItem.java | 12 + .../action/treemodel/CallMethodTreeItem.java | 12 + .../flash/action/treemodel/CallTreeItem.java | 12 + .../action/treemodel/CastOpTreeItem.java | 12 + .../action/treemodel/CharToAsciiTreeItem.java | 12 + .../action/treemodel/CloneSpriteTreeItem.java | 12 + .../action/treemodel/DecrementTreeItem.java | 12 + .../action/treemodel/DefineLocalTreeItem.java | 18 + .../treemodel/DefineRegisterTreeItem.java | 43 + .../action/treemodel/DeleteTreeItem.java | 12 + .../action/treemodel/DirectValueTreeItem.java | 20 +- .../flash/action/treemodel/EachTreeItem.java | 45 - .../action/treemodel/EnumerateTreeItem.java | 5 + .../flash/action/treemodel/EvalTreeItem.java | 13 + .../action/treemodel/ExtendsTreeItem.java | 5 + .../action/treemodel/FSCommand2TreeItem.java | 21 + .../action/treemodel/FSCommandTreeItem.java | 13 + .../action/treemodel/FunctionTreeItem.java | 197 ++ .../action/treemodel/GetMemberTreeItem.java | 12 + .../action/treemodel/GetPropertyTreeItem.java | 13 + .../action/treemodel/GetTimeTreeItem.java | 13 + .../action/treemodel/GetURL2TreeItem.java | 12 + .../action/treemodel/GetURLTreeItem.java | 13 + .../action/treemodel/GetVariableTreeItem.java | 12 + .../action/treemodel/GetVersionTreeItem.java | 14 + .../action/treemodel/GotoFrame2TreeItem.java | 12 + .../action/treemodel/GotoFrameTreeItem.java | 15 +- .../action/treemodel/GotoLabelTreeItem.java | 13 + .../treemodel/ImplementsOpTreeItem.java | 5 + .../action/treemodel/IncrementTreeItem.java | 12 + .../action/treemodel/InitArrayTreeItem.java | 12 + .../action/treemodel/InitObjectTreeItem.java | 19 + .../treemodel/LoadMovieNumTreeItem.java | 20 +- .../action/treemodel/LoadMovieTreeItem.java | 13 + .../treemodel/LoadVariablesNumTreeItem.java | 20 +- .../treemodel/LoadVariablesTreeItem.java | 13 + .../treemodel/MBAsciiToCharTreeItem.java | 12 + .../treemodel/MBCharToAsciiTreeItem.java | 12 + .../treemodel/MBStringExtractTreeItem.java | 12 + .../treemodel/MBStringLengthTreeItem.java | 12 + .../action/treemodel/NewMethodTreeItem.java | 12 + .../action/treemodel/NewObjectTreeItem.java | 12 + .../action/treemodel/NextFrameTreeItem.java | 44 + ...orFrameTreeItem.java => PlayTreeItem.java} | 30 +- .../flash/action/treemodel/PopTreeItem.java | 13 + .../treemodel/PostDecrementTreeItem.java | 58 +- .../treemodel/PostIncrementTreeItem.java | 56 + .../action/treemodel/PrevFrameTreeItem.java | 44 + .../treemodel/PrintAsBitmapNumTreeItem.java | 27 +- .../treemodel/PrintAsBitmapTreeItem.java | 24 +- .../action/treemodel/PrintNumTreeItem.java | 26 +- .../flash/action/treemodel/PrintTreeItem.java | 23 +- .../treemodel/RandomNumberTreeItem.java | 12 + .../treemodel/RemoveSpriteTreeItem.java | 12 + .../action/treemodel/ReturnTreeItem.java | 41 + .../action/treemodel/SetMemberTreeItem.java | 23 + .../action/treemodel/SetPropertyTreeItem.java | 23 + .../action/treemodel/SetTarget2TreeItem.java | 11 + .../action/treemodel/SetTargetTreeItem.java | 12 + .../action/treemodel/SetVariableTreeItem.java | 23 + .../action/treemodel/StartDragTreeItem.java | 22 + .../treemodel/StopAllSoundsTreeItem.java | 44 + ...oidTreeItem.java => StopDragTreeItem.java} | 28 +- ...eActionTreeItem.java => StopTreeItem.java} | 22 +- .../treemodel/StoreRegisterTreeItem.java | 12 + .../action/treemodel/StrictModeTreeItem.java | 5 + .../treemodel/StringExtractTreeItem.java | 12 + .../StringLengthTreeItem.java | 17 +- .../action/treemodel/TargetPathTreeItem.java | 12 + .../flash/action/treemodel/ThrowTreeItem.java | 12 + .../action/treemodel/ToIntegerTreeItem.java | 12 + .../action/treemodel/ToNumberTreeItem.java | 12 + .../action/treemodel/ToStringTreeItem.java | 12 + .../treemodel/ToggleHighQualityTreeItem.java | 44 + .../flash/action/treemodel/TraceTreeItem.java | 12 + .../flash/action/treemodel/TreeItem.java | 22 + .../action/treemodel/TypeOfTreeItem.java | 12 + .../treemodel/UnLoadMovieNumTreeItem.java | 22 +- .../action/treemodel/UnLoadMovieTreeItem.java | 14 + .../action/treemodel/UnsupportedTreeItem.java | 5 + .../treemodel/WaitForFrame2TreeItem.java | 45 - .../treemodel/clauses/ClassTreeItem.java | 23 +- .../treemodel/clauses/ForInTreeItem.java | 66 + .../clauses/IfFrameLoadedTreeItem.java | 13 + .../treemodel/clauses/InterfaceTreeItem.java | 17 + .../treemodel/clauses/TellTargetTreeItem.java | 70 + .../action/treemodel/clauses/TryTreeItem.java | 50 +- .../treemodel/clauses/WithTreeItem.java | 22 + .../treemodel/operations/AddTreeItem.java | 8 + .../treemodel/operations/AndTreeItem.java | 8 + .../treemodel/operations/AsTypeTreeItem.java | 33 - .../treemodel/operations/BitAndTreeItem.java | 8 + .../treemodel/operations/BitNotTreeItem.java | 34 - .../treemodel/operations/BitOrTreeItem.java | 8 + .../treemodel/operations/BitXorTreeItem.java | 8 + .../treemodel/operations/DivideTreeItem.java | 8 + .../treemodel/operations/EqTreeItem.java | 8 + .../treemodel/operations/GeTreeItem.java | 11 +- .../treemodel/operations/GtTreeItem.java | 8 + .../operations/InstanceOfTreeItem.java | 8 + .../action/treemodel/operations/Inverted.java | 28 + .../treemodel/operations/IsTypeTreeItem.java | 33 - .../treemodel/operations/LShiftTreeItem.java | 8 + .../treemodel/operations/LeTreeItem.java | 11 +- .../treemodel/operations/LtTreeItem.java | 8 + .../treemodel/operations/ModuloTreeItem.java | 8 + .../operations/MultiplyTreeItem.java | 8 + .../treemodel/operations/NegTreeItem.java | 34 - .../treemodel/operations/NeqTreeItem.java | 11 +- .../treemodel/operations/OrTreeItem.java | 8 + .../operations/PreDecrementTreeItem.java | 57 + .../operations/PreIncrementTreeItem.java | 57 + .../treemodel/operations/RShiftTreeItem.java | 8 + .../operations/StrictEqTreeItem.java | 8 + .../operations/StrictNeqTreeItem.java | 9 + .../operations/StringAddTreeItem.java | 8 + .../operations/StringEqTreeItem.java | 8 + .../operations/StringLtTreeItem.java | 8 + .../operations/SubtractTreeItem.java | 10 +- .../treemodel/operations/URShiftTreeItem.java | 8 + .../jpexs/decompiler/flash/graph/AndItem.java | 10 + .../decompiler/flash/graph/BinaryOp.java | 34 + .../decompiler/flash/graph/BinaryOpItem.java | 31 +- .../decompiler/flash/graph/BlockItem.java | 48 + .../decompiler/flash/graph/BreakItem.java | 10 + .../flash/graph/CommaExpressionItem.java | 57 + .../decompiler/flash/graph/CommentItem.java | 5 + .../decompiler/flash/graph/ContinueItem.java | 10 + .../decompiler/flash/graph/DoWhileItem.java | 10 + .../decompiler/flash/graph/DuplicateItem.java | 10 + .../graph/{ForTreeItem.java => ForItem.java} | 14 +- .../jpexs/decompiler/flash/graph/Graph.java | 2 +- .../flash/graph/GraphTargetItem.java | 37 + .../jpexs/decompiler/flash/graph/IfItem.java | 10 + .../flash/graph/IntegerValueItem.java | 5 + .../decompiler/flash/graph/MarkItem.java | 5 + .../jpexs/decompiler/flash/graph/NotItem.java | 14 +- .../jpexs/decompiler/flash/graph/OrItem.java | 10 + .../flash/graph/ParenthesisItem.java | 46 + .../decompiler/flash/graph/ScriptEndItem.java | 5 + .../flash/graph/SourceGenerator.java | 54 + .../decompiler/flash/graph/SwitchItem.java | 12 +- .../decompiler/flash/graph/TernarOpItem.java | 10 + .../decompiler/flash/graph/TrueItem.java | 5 + .../jpexs/decompiler/flash/graph/UnaryOp.java | 28 + .../decompiler/flash/graph/UnaryOpItem.java | 17 +- .../flash/graph/UniversalLoopItem.java | 5 + .../decompiler/flash/graph/WhileItem.java | 10 + .../flash/gui/action/ActionPanel.java | 5 +- 175 files changed, 5356 insertions(+), 2183 deletions(-) create mode 100644 trunk/src/com/jpexs/decompiler/flash/action/parser/script/ActionScriptSourceGenerator.java create mode 100644 trunk/src/com/jpexs/decompiler/flash/action/parser/script/LexBufferer.java create mode 100644 trunk/src/com/jpexs/decompiler/flash/action/parser/script/LexListener.java create mode 100644 trunk/src/com/jpexs/decompiler/flash/action/treemodel/DefineRegisterTreeItem.java delete mode 100644 trunk/src/com/jpexs/decompiler/flash/action/treemodel/EachTreeItem.java create mode 100644 trunk/src/com/jpexs/decompiler/flash/action/treemodel/NextFrameTreeItem.java rename trunk/src/com/jpexs/decompiler/flash/action/treemodel/{WaitForFrameTreeItem.java => PlayTreeItem.java} (61%) create mode 100644 trunk/src/com/jpexs/decompiler/flash/action/treemodel/PrevFrameTreeItem.java create mode 100644 trunk/src/com/jpexs/decompiler/flash/action/treemodel/StopAllSoundsTreeItem.java rename trunk/src/com/jpexs/decompiler/flash/action/treemodel/{VoidTreeItem.java => StopDragTreeItem.java} (61%) rename trunk/src/com/jpexs/decompiler/flash/action/treemodel/{SimpleActionTreeItem.java => StopTreeItem.java} (61%) rename trunk/src/com/jpexs/decompiler/flash/action/treemodel/{operations => }/StringLengthTreeItem.java (71%) create mode 100644 trunk/src/com/jpexs/decompiler/flash/action/treemodel/ToggleHighQualityTreeItem.java delete mode 100644 trunk/src/com/jpexs/decompiler/flash/action/treemodel/WaitForFrame2TreeItem.java create mode 100644 trunk/src/com/jpexs/decompiler/flash/action/treemodel/clauses/TellTargetTreeItem.java delete mode 100644 trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/AsTypeTreeItem.java delete mode 100644 trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/BitNotTreeItem.java create mode 100644 trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/Inverted.java delete mode 100644 trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/IsTypeTreeItem.java delete mode 100644 trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/NegTreeItem.java create mode 100644 trunk/src/com/jpexs/decompiler/flash/graph/BinaryOp.java create mode 100644 trunk/src/com/jpexs/decompiler/flash/graph/BlockItem.java create mode 100644 trunk/src/com/jpexs/decompiler/flash/graph/CommaExpressionItem.java rename trunk/src/com/jpexs/decompiler/flash/graph/{ForTreeItem.java => ForItem.java} (84%) create mode 100644 trunk/src/com/jpexs/decompiler/flash/graph/ParenthesisItem.java create mode 100644 trunk/src/com/jpexs/decompiler/flash/graph/SourceGenerator.java create mode 100644 trunk/src/com/jpexs/decompiler/flash/graph/UnaryOp.java diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/treemodel/TreeItem.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/treemodel/TreeItem.java index 316b555e1..5461183f0 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/treemodel/TreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/treemodel/TreeItem.java @@ -109,4 +109,9 @@ public abstract class TreeItem extends GraphTargetItem { return "_loc" + reg + "_"; } } + + @Override + public boolean hasReturnValue() { + throw new UnsupportedOperationException(); //Not supported in AVM2 yet + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/treemodel/clauses/ForEachInTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/treemodel/clauses/ForEachInTreeItem.java index 1f0e72877..cdb9d4dff 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/treemodel/clauses/ForEachInTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/treemodel/clauses/ForEachInTreeItem.java @@ -92,4 +92,9 @@ public class ForEachInTreeItem extends LoopItem implements Block { } return ret; } + + @Override + public boolean hasReturnValue() { + return false; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/treemodel/clauses/ForInTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/treemodel/clauses/ForInTreeItem.java index 2b6013e35..de8899d45 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/treemodel/clauses/ForInTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/treemodel/clauses/ForInTreeItem.java @@ -92,4 +92,9 @@ public class ForInTreeItem extends LoopItem implements Block { } return ret; } + + @Override + public boolean hasReturnValue() { + return false; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/Action.java b/trunk/src/com/jpexs/decompiler/flash/action/Action.java index c26ef633d..5fc05b2c3 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/Action.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/Action.java @@ -298,9 +298,7 @@ public class Action implements GraphSourceItem { * @return Array of bytes */ public byte[] getBytes(int version) { - byte ret[] = new byte[1]; - ret[0] = (byte) actionCode; - return ret; + return surroundWithAction(new byte[0], version); } /** @@ -315,7 +313,9 @@ public class Action implements GraphSourceItem { SWFOutputStream sos2 = new SWFOutputStream(baos2, version); try { sos2.writeUI8(actionCode); - sos2.writeUI16(data.length); + if (actionCode >= 0x80) { + sos2.writeUI16(data.length); + } sos2.write(data); sos2.close(); } catch (IOException e) { @@ -1075,7 +1075,7 @@ public class Action implements GraphSourceItem { for (int i = 0; i < prevCount; i++) { output2.add(output.get(i)); } - output2.add(new ClassTreeItem(className, extendsOp, implementsOp, functions, vars, staticFunctions, staticVars)); + output2.add(new ClassTreeItem(className, extendsOp, implementsOp, null/*FIXME*/, functions, vars, staticFunctions, staticVars)); return output2; } @@ -1143,7 +1143,7 @@ public class Action implements GraphSourceItem { for (int i = 0; i < prevCount; i++) { output2.add(output.get(i)); } - output2.add(new ClassTreeItem(className, extendsOp, implementsOp, functions, vars, staticFunctions, staticVars)); + output2.add(new ClassTreeItem(className, extendsOp, implementsOp, null/*FIXME*/, functions, vars, staticFunctions, staticVars)); return output2; } /*if (parts.get(pos) instanceof PopTreeItem) { @@ -1209,7 +1209,7 @@ public class Action implements GraphSourceItem { for (int i = 0; i < prevCount; i++) { output2.add(output.get(i)); } - output2.add(new ClassTreeItem(className, extendsOp, implementsOp, functions, vars, staticFunctions, staticVars)); + output2.add(new ClassTreeItem(className, extendsOp, implementsOp, null/*FIXME*/, functions, vars, staticFunctions, staticVars)); return output2; } } else { @@ -1345,4 +1345,21 @@ public class Action implements GraphSourceItem { public int getFixBranch() { return fixedBranch; } + + public static GraphTargetItem gettoset(GraphTargetItem get, GraphTargetItem value) { + GraphTargetItem ret = get; + if (ret instanceof GetVariableTreeItem) { + GetVariableTreeItem gv = (GetVariableTreeItem) ret; + ret = new SetVariableTreeItem(null, gv.name, value); + } else if (ret instanceof GetMemberTreeItem) { + GetMemberTreeItem mem = (GetMemberTreeItem) ret; + ret = new SetMemberTreeItem(null, mem.object, mem.memberName, value); + } else if ((ret instanceof DirectValueTreeItem) && ((DirectValueTreeItem) ret).value instanceof RegisterNumber) { + ret = new StoreRegisterTreeItem(null, (RegisterNumber) ((DirectValueTreeItem) ret).value, value, false); + } else if (ret instanceof GetPropertyTreeItem) { + GetPropertyTreeItem gp = (GetPropertyTreeItem) ret; + ret = new SetPropertyTreeItem(null, gp.target, gp.propertyIndex, value); + } + return ret; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/ActionGraph.java b/trunk/src/com/jpexs/decompiler/flash/action/ActionGraph.java index c5499ef82..ede6b5648 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/ActionGraph.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/ActionGraph.java @@ -27,9 +27,12 @@ import com.jpexs.decompiler.flash.action.swf6.ActionStrictEquals; import com.jpexs.decompiler.flash.action.treemodel.DirectValueTreeItem; import com.jpexs.decompiler.flash.action.treemodel.EnumerateTreeItem; import com.jpexs.decompiler.flash.action.treemodel.FunctionTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.SetTarget2TreeItem; +import com.jpexs.decompiler.flash.action.treemodel.SetTargetTreeItem; import com.jpexs.decompiler.flash.action.treemodel.SetTypeTreeItem; import com.jpexs.decompiler.flash.action.treemodel.StoreRegisterTreeItem; import com.jpexs.decompiler.flash.action.treemodel.clauses.ForInTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.clauses.TellTargetTreeItem; 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; @@ -95,8 +98,66 @@ public class ActionGraph extends Graph { list.clear(); list.addAll(ret); } + int targetStart; + int targetEnd; + + boolean again; + do { + again = false; + targetStart = -1; + targetEnd = -1; + GraphTargetItem targetStartItem = null; + GraphTargetItem target = null; + for (int t = 0; t < list.size(); t++) { + GraphTargetItem it = list.get(t); + if (it instanceof SetTargetTreeItem) { + SetTargetTreeItem st = (SetTargetTreeItem) it; + if (st.target.equals("")) { + if (targetStart > -1) { + targetEnd = t; + break; + } + } else { + target = new DirectValueTreeItem(null, 0, st.target, new ArrayList()); + targetStart = t; + targetStartItem = it; + } + } + if (it instanceof SetTarget2TreeItem) { + SetTarget2TreeItem st = (SetTarget2TreeItem) it; + if ((st.target instanceof DirectValueTreeItem) && st.target.getResult().equals("")) { + if (targetStart > -1) { + targetEnd = t; + break; + } + } else { + targetStart = t; + target = st.target; + targetStartItem = it; + } + } + } + if ((targetStart > -1) && (targetEnd > -1)) { + List newlist = new ArrayList<>(); + for (int i = 0; i < targetStart; i++) { + newlist.add(list.get(i)); + } + List tellist = new ArrayList<>(); + for (int i = targetStart + 1; i < targetEnd; i++) { + tellist.add(list.get(i)); + } + newlist.add(new TellTargetTreeItem(targetStartItem.src, target, tellist)); + for (int i = targetEnd + 1; i < list.size(); i++) { + newlist.add(list.get(i)); + } + list.clear(); + list.addAll(newlist); + again = true; + } + } while (again); for (int t = 0; t < list.size(); t++) { GraphTargetItem it = list.get(t); + if (it instanceof WhileItem) { WhileItem wi = (WhileItem) it; if ((!wi.commands.isEmpty()) && (wi.commands.get(0) instanceof SetTypeTreeItem)) { diff --git a/trunk/src/com/jpexs/decompiler/flash/action/parser/script/ActionScriptLexer.java b/trunk/src/com/jpexs/decompiler/flash/action/parser/script/ActionScriptLexer.java index 9fb9b431e..5d1972620 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/parser/script/ActionScriptLexer.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/parser/script/ActionScriptLexer.java @@ -1,4 +1,4 @@ -/* The following code was generated by JFlex 1.4.3 on 13.7.13 19:57 */ +/* The following code was generated by JFlex 1.4.3 on 15.7.13 17:22 */ /* * Copyright (C) 2013 JPEXS @@ -19,11 +19,13 @@ package com.jpexs.decompiler.flash.action.parser.script; import com.jpexs.decompiler.flash.action.parser.ParseException; +import java.util.ArrayList; +import java.util.List; import java.util.Stack; /** * This class is a scanner generated by - * JFlex 1.4.3 on 13.7.13 19:57 from the + * JFlex 1.4.3 on 15.7.13 17:22 from the * specification file * D:/Dokumenty/Programovani/JavaSE/FFDec/trunk/src/com/jpexs/decompiler/flash/action/parser/script/actionscript.flex */ @@ -193,34 +195,36 @@ public final class ActionScriptLexer { + "\1\76\1\77\1\100\1\101\2\102\1\103\1\104\1\105" + "\1\106\1\107\1\110\1\111\6\0\2\3\2\0\1\112" + "\3\0\1\113\1\0\1\114\1\115\1\116\1\117\2\120" - + "\1\57\1\51\1\0\14\6\1\121\1\122\5\6\1\123" + + "\1\57\1\51\1\0\15\6\1\121\1\122\5\6\1\123" + "\1\6\1\124\5\6\1\125\7\6\1\126\2\6\1\127" - + "\6\6\1\130\20\6\1\131\1\6\1\132\2\6\1\133" + + "\7\6\1\130\20\6\1\131\1\6\1\132\2\6\1\133" + "\2\6\1\134\1\102\7\0\1\135\5\0\1\136\1\120" - + "\1\57\4\6\1\137\1\140\1\141\1\6\1\142\6\6" - + "\1\143\7\6\1\144\1\6\1\145\4\6\1\146\20\6" - + "\1\147\6\6\1\150\4\6\1\151\6\6\1\41\1\0" - + "\1\152\12\0\1\120\1\57\1\153\4\6\1\154\1\155" - + "\1\6\1\156\5\6\1\157\5\6\1\160\3\6\1\161" - + "\13\6\1\162\5\6\1\163\5\6\1\164\1\6\1\165" - + "\7\6\10\0\1\120\1\57\1\166\1\6\1\167\3\6" - + "\1\170\2\6\1\171\1\172\7\6\1\173\4\6\1\174" - + "\3\6\1\175\4\6\1\176\6\6\1\177\2\6\1\200" - + "\2\6\1\201\1\202\1\6\2\0\1\113\1\120\1\57" - + "\1\6\1\203\5\6\1\204\13\6\1\205\1\6\1\206" - + "\1\207\5\6\1\210\1\211\5\6\1\41\1\120\1\57" - + "\1\6\1\212\2\6\1\213\1\214\6\6\1\215\5\6" - + "\1\216\5\6\1\217\1\220\2\6\1\221\1\120\1\57" - + "\1\6\1\222\1\6\1\223\1\224\4\6\1\225\2\6" - + "\1\226\1\6\1\227\1\6\1\230\1\231\3\6\1\120" - + "\1\57\2\6\1\232\1\233\1\6\1\234\1\6\1\235" - + "\5\6\1\57\6\6\1\236\1\237\1\240\1\57\6\6" - + "\1\57\1\6\1\241\1\6\1\242\1\6\1\243\1\57" - + "\3\6\1\57\1\244\2\6\1\57\2\6\1\245\1\6" - + "\1\246"; + + "\1\57\4\6\1\137\1\140\1\141\1\6\1\142\1\6" + + "\1\143\5\6\1\144\7\6\1\145\1\6\1\146\4\6" + + "\1\147\21\6\1\150\7\6\1\151\4\6\1\152\7\6" + + "\1\41\1\0\1\153\12\0\1\120\1\57\1\154\4\6" + + "\1\155\1\156\1\6\1\157\5\6\1\160\5\6\1\161" + + "\3\6\1\162\14\6\1\163\5\6\1\164\2\6\1\165" + + "\3\6\1\166\1\6\1\167\10\6\10\0\1\120\1\57" + + "\1\170\1\6\1\171\3\6\1\172\2\6\1\173\1\174" + + "\7\6\1\175\4\6\1\176\4\6\1\177\4\6\1\200" + + "\10\6\1\201\2\6\1\202\3\6\1\203\1\204\1\6" + + "\2\0\1\113\1\120\1\57\1\6\1\205\5\6\1\206" + + "\14\6\1\207\1\6\1\210\1\211\7\6\1\212\1\213" + + "\6\6\1\41\1\120\1\57\1\6\1\214\2\6\1\215" + + "\1\216\6\6\1\217\6\6\1\220\5\6\1\221\1\6" + + "\1\222\1\223\3\6\1\224\1\120\1\57\1\6\1\225" + + "\1\6\1\226\1\227\4\6\1\230\2\6\1\231\2\6" + + "\1\232\1\6\1\233\1\234\5\6\1\120\1\57\2\6" + + "\1\235\1\236\1\6\1\237\1\6\1\240\6\6\1\241" + + "\2\6\1\57\4\6\1\242\4\6\1\243\1\244\1\245" + + "\1\57\6\6\1\246\2\6\1\57\1\6\1\247\1\6" + + "\1\250\2\6\1\251\1\252\1\57\2\6\1\253\3\6" + + "\1\57\1\254\4\6\1\57\2\6\1\255\1\256\1\257" + + "\1\6\1\260"; private static int[] zzUnpackAction() { - int[] result = new int[633]; + int[] result = new int[676]; int offset = 0; offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result); return result; @@ -270,63 +274,68 @@ public final class ActionScriptLexer { + "\0\u2a80\0\u0190\0\u2ad0\0\u2b20\0\u2b70\0\u0190\0\u2bc0\0\u0190" + "\0\u2c10\0\u0190\0\u0190\0\u14f0\0\u2c60\0\u2cb0\0\u2d00\0\u2d00" + "\0\u2d50\0\u2da0\0\u2df0\0\u2e40\0\u2e90\0\u2ee0\0\u2f30\0\u2f80" - + "\0\u2fd0\0\u3020\0\u3070\0\u30c0\0\u0320\0\u0320\0\u3110\0\u3160" - + "\0\u31b0\0\u3200\0\u3250\0\u0320\0\u32a0\0\u32f0\0\u3340\0\u3390" - + "\0\u33e0\0\u3430\0\u3480\0\u0320\0\u34d0\0\u3520\0\u3570\0\u35c0" - + "\0\u3610\0\u3660\0\u36b0\0\u3700\0\u3750\0\u37a0\0\u0320\0\u37f0" - + "\0\u3840\0\u3890\0\u38e0\0\u3930\0\u3980\0\u0320\0\u39d0\0\u3a20" + + "\0\u2fd0\0\u3020\0\u3070\0\u30c0\0\u3110\0\u0320\0\u0320\0\u3160" + + "\0\u31b0\0\u3200\0\u3250\0\u32a0\0\u0320\0\u32f0\0\u3340\0\u3390" + + "\0\u33e0\0\u3430\0\u3480\0\u34d0\0\u0320\0\u3520\0\u3570\0\u35c0" + + "\0\u3610\0\u3660\0\u36b0\0\u3700\0\u3750\0\u37a0\0\u37f0\0\u0320" + + "\0\u3840\0\u3890\0\u38e0\0\u3930\0\u3980\0\u39d0\0\u3a20\0\u0320" + "\0\u3a70\0\u3ac0\0\u3b10\0\u3b60\0\u3bb0\0\u3c00\0\u3c50\0\u3ca0" - + "\0\u3cf0\0\u3d40\0\u3d90\0\u3de0\0\u3e30\0\u3e80\0\u0320\0\u3ed0" - + "\0\u3f20\0\u3f70\0\u3fc0\0\u0320\0\u4010\0\u4060\0\u0190\0\u0190" - + "\0\u40b0\0\u4100\0\u4150\0\u41a0\0\u41f0\0\u4240\0\u4290\0\u0190" - + "\0\u42e0\0\u4330\0\u4380\0\u43d0\0\u4420\0\u0190\0\u4470\0\u44c0" - + "\0\u4510\0\u4560\0\u45b0\0\u4600\0\u0320\0\u0320\0\u0320\0\u4650" - + "\0\u0320\0\u46a0\0\u46f0\0\u4740\0\u4790\0\u47e0\0\u4830\0\u4880" - + "\0\u48d0\0\u4920\0\u4970\0\u49c0\0\u4a10\0\u4a60\0\u4ab0\0\u0320" - + "\0\u4b00\0\u0320\0\u4b50\0\u4ba0\0\u4bf0\0\u4c40\0\u0320\0\u4c90" - + "\0\u4ce0\0\u4d30\0\u4d80\0\u4dd0\0\u4e20\0\u4e70\0\u4ec0\0\u4f10" - + "\0\u4f60\0\u4fb0\0\u5000\0\u5050\0\u50a0\0\u50f0\0\u5140\0\u0320" - + "\0\u5190\0\u51e0\0\u5230\0\u5280\0\u52d0\0\u5320\0\u0320\0\u5370" + + "\0\u3cf0\0\u3d40\0\u3d90\0\u3de0\0\u3e30\0\u3e80\0\u3ed0\0\u3f20" + + "\0\u0320\0\u3f70\0\u3fc0\0\u4010\0\u4060\0\u0320\0\u40b0\0\u4100" + + "\0\u0190\0\u0190\0\u4150\0\u41a0\0\u41f0\0\u4240\0\u4290\0\u42e0" + + "\0\u4330\0\u0190\0\u4380\0\u43d0\0\u4420\0\u4470\0\u44c0\0\u0190" + + "\0\u4510\0\u4560\0\u45b0\0\u4600\0\u4650\0\u46a0\0\u0320\0\u0320" + + "\0\u0320\0\u46f0\0\u0320\0\u4740\0\u0320\0\u4790\0\u47e0\0\u4830" + + "\0\u4880\0\u48d0\0\u4920\0\u4970\0\u49c0\0\u4a10\0\u4a60\0\u4ab0" + + "\0\u4b00\0\u4b50\0\u0320\0\u4ba0\0\u0320\0\u4bf0\0\u4c40\0\u4c90" + + "\0\u4ce0\0\u0320\0\u4d30\0\u4d80\0\u4dd0\0\u4e20\0\u4e70\0\u4ec0" + + "\0\u4f10\0\u4f60\0\u4fb0\0\u5000\0\u5050\0\u50a0\0\u50f0\0\u5140" + + "\0\u5190\0\u51e0\0\u5230\0\u0320\0\u5280\0\u52d0\0\u5320\0\u5370" + "\0\u53c0\0\u5410\0\u5460\0\u0320\0\u54b0\0\u5500\0\u5550\0\u55a0" - + "\0\u55f0\0\u5640\0\u5690\0\u56e0\0\u0190\0\u5730\0\u5780\0\u57d0" - + "\0\u5820\0\u5870\0\u58c0\0\u5910\0\u5960\0\u59b0\0\u5a00\0\u5a50" - + "\0\u5aa0\0\u0320\0\u5af0\0\u5b40\0\u5b90\0\u5be0\0\u0320\0\u0320" - + "\0\u5c30\0\u0320\0\u5c80\0\u5cd0\0\u5d20\0\u5d70\0\u5dc0\0\u0320" + + "\0\u0320\0\u55f0\0\u5640\0\u5690\0\u56e0\0\u5730\0\u5780\0\u57d0" + + "\0\u5820\0\u5870\0\u0190\0\u58c0\0\u5910\0\u5960\0\u59b0\0\u5a00" + + "\0\u5a50\0\u5aa0\0\u5af0\0\u5b40\0\u5b90\0\u5be0\0\u5c30\0\u0320" + + "\0\u5c80\0\u5cd0\0\u5d20\0\u5d70\0\u0320\0\u0320\0\u5dc0\0\u0320" + "\0\u5e10\0\u5e60\0\u5eb0\0\u5f00\0\u5f50\0\u0320\0\u5fa0\0\u5ff0" - + "\0\u6040\0\u0320\0\u6090\0\u60e0\0\u6130\0\u6180\0\u61d0\0\u6220" - + "\0\u6270\0\u62c0\0\u6310\0\u6360\0\u63b0\0\u0320\0\u6400\0\u6450" - + "\0\u64a0\0\u64f0\0\u6540\0\u0320\0\u6590\0\u65e0\0\u6630\0\u6680" - + "\0\u66d0\0\u0320\0\u6720\0\u0320\0\u6770\0\u67c0\0\u6810\0\u6860" - + "\0\u68b0\0\u6900\0\u6950\0\u69a0\0\u69f0\0\u6a40\0\u6a90\0\u6ae0" - + "\0\u6b30\0\u6b80\0\u6bd0\0\u6c20\0\u6c70\0\u0320\0\u6cc0\0\u0320" - + "\0\u6d10\0\u6d60\0\u6db0\0\u0320\0\u6e00\0\u6e50\0\u0320\0\u0320" - + "\0\u6ea0\0\u6ef0\0\u6f40\0\u6f90\0\u6fe0\0\u7030\0\u7080\0\u0320" - + "\0\u70d0\0\u7120\0\u7170\0\u71c0\0\u0320\0\u7210\0\u7260\0\u72b0" - + "\0\u0320\0\u7300\0\u7350\0\u73a0\0\u73f0\0\u0320\0\u7440\0\u7490" - + "\0\u74e0\0\u7530\0\u7580\0\u75d0\0\u0320\0\u7620\0\u7670\0\u0320" - + "\0\u76c0\0\u7710\0\u0320\0\u0320\0\u7760\0\u77b0\0\u7800\0\u5910" - + "\0\u7850\0\u78a0\0\u78f0\0\u0320\0\u7940\0\u7990\0\u79e0\0\u7a30" - + "\0\u7a80\0\u0320\0\u7ad0\0\u7b20\0\u7b70\0\u7bc0\0\u7c10\0\u7c60" - + "\0\u7cb0\0\u7d00\0\u7d50\0\u7da0\0\u7df0\0\u0320\0\u7e40\0\u0320" - + "\0\u0320\0\u7e90\0\u7ee0\0\u7f30\0\u7f80\0\u7fd0\0\u0320\0\u0320" - + "\0\u8020\0\u8070\0\u80c0\0\u8110\0\u8160\0\u6a40\0\u81b0\0\u8200" - + "\0\u8250\0\u0320\0\u82a0\0\u82f0\0\u0320\0\u0320\0\u8340\0\u8390" - + "\0\u83e0\0\u8430\0\u8480\0\u84d0\0\u0320\0\u8520\0\u8570\0\u85c0" - + "\0\u8610\0\u8660\0\u0320\0\u86b0\0\u8700\0\u8750\0\u87a0\0\u87f0" - + "\0\u0320\0\u0320\0\u8840\0\u8890\0\u0320\0\u88e0\0\u8930\0\u8980" - + "\0\u0320\0\u89d0\0\u0320\0\u0320\0\u8a20\0\u8a70\0\u8ac0\0\u8b10" - + "\0\u0320\0\u8b60\0\u8bb0\0\u0320\0\u8c00\0\u0320\0\u8c50\0\u0320" - + "\0\u0320\0\u8ca0\0\u8cf0\0\u8d40\0\u0190\0\u8d90\0\u8de0\0\u8e30" - + "\0\u0320\0\u0320\0\u8e80\0\u0320\0\u8ed0\0\u0320\0\u8f20\0\u8f70" - + "\0\u8fc0\0\u9010\0\u9060\0\u90b0\0\u9100\0\u9150\0\u91a0\0\u91f0" - + "\0\u9240\0\u9290\0\u0320\0\u0320\0\u0320\0\u92e0\0\u9330\0\u9380" - + "\0\u93d0\0\u9420\0\u9470\0\u94c0\0\u9510\0\u9560\0\u0320\0\u95b0" - + "\0\u0320\0\u9600\0\u0320\0\u9650\0\u96a0\0\u96f0\0\u9740\0\u9790" - + "\0\u0320\0\u97e0\0\u9830\0\u14a0\0\u9880\0\u98d0\0\u0320\0\u9920" - + "\0\u0320"; + + "\0\u6040\0\u6090\0\u60e0\0\u0320\0\u6130\0\u6180\0\u61d0\0\u0320" + + "\0\u6220\0\u6270\0\u62c0\0\u6310\0\u6360\0\u63b0\0\u6400\0\u6450" + + "\0\u64a0\0\u64f0\0\u6540\0\u6590\0\u0320\0\u65e0\0\u6630\0\u6680" + + "\0\u66d0\0\u6720\0\u0320\0\u6770\0\u67c0\0\u6810\0\u6860\0\u68b0" + + "\0\u6900\0\u0320\0\u6950\0\u0320\0\u69a0\0\u69f0\0\u6a40\0\u6a90" + + "\0\u6ae0\0\u6b30\0\u6b80\0\u6bd0\0\u6c20\0\u6c70\0\u6cc0\0\u6d10" + + "\0\u6d60\0\u6db0\0\u6e00\0\u6e50\0\u6ea0\0\u6ef0\0\u0320\0\u6f40" + + "\0\u0320\0\u6f90\0\u6fe0\0\u7030\0\u0320\0\u7080\0\u70d0\0\u0320" + + "\0\u0320\0\u7120\0\u7170\0\u71c0\0\u7210\0\u7260\0\u72b0\0\u7300" + + "\0\u0320\0\u7350\0\u73a0\0\u73f0\0\u7440\0\u0320\0\u7490\0\u74e0" + + "\0\u7530\0\u7580\0\u0320\0\u75d0\0\u7620\0\u7670\0\u76c0\0\u0320" + + "\0\u7710\0\u7760\0\u77b0\0\u7800\0\u7850\0\u78a0\0\u78f0\0\u7940" + + "\0\u0320\0\u7990\0\u79e0\0\u0320\0\u7a30\0\u7a80\0\u7ad0\0\u0320" + + "\0\u0320\0\u7b20\0\u7b70\0\u7bc0\0\u5aa0\0\u7c10\0\u7c60\0\u7cb0" + + "\0\u0320\0\u7d00\0\u7d50\0\u7da0\0\u7df0\0\u7e40\0\u0320\0\u7e90" + + "\0\u7ee0\0\u7f30\0\u7f80\0\u7fd0\0\u8020\0\u8070\0\u80c0\0\u8110" + + "\0\u8160\0\u81b0\0\u8200\0\u0320\0\u8250\0\u0320\0\u0320\0\u82a0" + + "\0\u82f0\0\u8340\0\u8390\0\u83e0\0\u8430\0\u8480\0\u0320\0\u0320" + + "\0\u84d0\0\u8520\0\u8570\0\u85c0\0\u8610\0\u8660\0\u6cc0\0\u86b0" + + "\0\u8700\0\u8750\0\u0320\0\u87a0\0\u87f0\0\u0320\0\u0320\0\u8840" + + "\0\u8890\0\u88e0\0\u8930\0\u8980\0\u89d0\0\u0320\0\u8a20\0\u8a70" + + "\0\u8ac0\0\u8b10\0\u8b60\0\u8bb0\0\u0320\0\u8c00\0\u8c50\0\u8ca0" + + "\0\u8cf0\0\u8d40\0\u0320\0\u8d90\0\u0320\0\u0320\0\u8de0\0\u8e30" + + "\0\u8e80\0\u0320\0\u8ed0\0\u8f20\0\u8f70\0\u0320\0\u8fc0\0\u0320" + + "\0\u0320\0\u9010\0\u9060\0\u90b0\0\u9100\0\u0320\0\u9150\0\u91a0" + + "\0\u0320\0\u91f0\0\u9240\0\u9290\0\u92e0\0\u0320\0\u0320\0\u9330" + + "\0\u9380\0\u93d0\0\u9420\0\u9470\0\u0190\0\u94c0\0\u9510\0\u9560" + + "\0\u0320\0\u0320\0\u95b0\0\u0320\0\u9600\0\u0320\0\u9650\0\u96a0" + + "\0\u96f0\0\u9740\0\u9790\0\u97e0\0\u0320\0\u9830\0\u9880\0\u98d0" + + "\0\u9920\0\u9970\0\u99c0\0\u9a10\0\u9a60\0\u9ab0\0\u9b00\0\u9b50" + + "\0\u9ba0\0\u0320\0\u0320\0\u0320\0\u9bf0\0\u9c40\0\u9c90\0\u9ce0" + + "\0\u9d30\0\u9d80\0\u9dd0\0\u0320\0\u9e20\0\u9e70\0\u9ec0\0\u9f10" + + "\0\u0320\0\u9f60\0\u0320\0\u9fb0\0\ua000\0\ua050\0\ua0a0\0\ua0f0" + + "\0\ua140\0\ua190\0\u0320\0\ua1e0\0\ua230\0\ua280\0\ua2d0\0\u0320" + + "\0\ua320\0\ua370\0\ua3c0\0\ua410\0\u14a0\0\ua460\0\ua4b0\0\u0320" + + "\0\u0320\0\u0320\0\ua500\0\u0320"; private static int[] zzUnpackRowMap() { - int[] result = new int[633]; + int[] result = new int[676]; int offset = 0; offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result); return result; @@ -433,436 +442,476 @@ public final class ActionScriptLexer { + "\1\316\37\14\27\0\2\14\7\0\7\14\3\0\3\14" + "\1\317\42\14\27\0\2\14\7\0\7\14\3\0\11\14" + "\1\320\34\14\27\0\2\14\7\0\7\14\3\0\6\14" - + "\1\321\2\14\1\322\34\14\27\0\2\14\7\0\7\14" - + "\3\0\10\14\1\323\35\14\27\0\2\14\7\0\7\14" - + "\3\0\3\14\1\324\42\14\27\0\2\14\7\0\7\14" - + "\3\0\1\14\1\325\44\14\27\0\2\14\7\0\7\14" - + "\3\0\11\14\1\326\34\14\27\0\2\14\7\0\7\14" - + "\3\0\3\14\1\327\3\14\1\330\36\14\27\0\2\14" - + "\7\0\7\14\3\0\1\331\20\14\1\332\24\14\27\0" - + "\2\14\7\0\7\14\3\0\12\14\1\333\33\14\27\0" - + "\2\14\7\0\7\14\3\0\14\14\1\334\31\14\27\0" - + "\2\14\7\0\7\14\3\0\2\14\1\335\43\14\27\0" - + "\2\14\7\0\7\14\3\0\17\14\1\336\5\14\1\337" - + "\20\14\27\0\2\14\7\0\7\14\3\0\23\14\1\340" - + "\22\14\27\0\2\14\7\0\7\14\3\0\16\14\1\341" - + "\27\14\27\0\2\14\7\0\7\14\3\0\3\14\1\342" - + "\7\14\1\343\6\14\1\344\23\14\27\0\2\14\7\0" - + "\7\14\3\0\16\14\1\345\27\14\27\0\2\14\7\0" - + "\7\14\3\0\1\14\1\346\44\14\27\0\2\14\7\0" - + "\7\14\3\0\26\14\1\347\17\14\27\0\2\14\7\0" - + "\7\14\3\0\1\14\1\350\10\14\1\351\33\14\27\0" - + "\2\14\7\0\7\14\3\0\21\14\1\352\24\14\27\0" - + "\2\14\7\0\7\14\3\0\6\14\1\353\2\14\1\354" - + "\34\14\27\0\2\14\7\0\7\14\3\0\32\14\1\355" - + "\13\14\27\0\2\14\7\0\7\14\3\0\21\14\1\356" - + "\24\14\27\0\2\14\7\0\7\14\3\0\2\14\1\357" - + "\43\14\27\0\2\14\7\0\7\14\3\0\14\14\1\360" - + "\31\14\27\0\2\14\7\0\7\14\3\0\15\14\1\361" - + "\1\362\27\14\27\0\2\14\7\0\7\14\3\0\21\14" - + "\1\363\24\14\27\0\2\14\7\0\7\14\3\0\10\14" - + "\1\364\35\14\27\0\2\14\7\0\7\14\3\0\16\14" - + "\1\365\27\14\27\0\2\14\7\0\7\14\3\0\1\14" - + "\1\366\44\14\27\0\2\14\7\0\7\14\3\0\10\14" - + "\1\367\35\14\27\0\2\14\7\0\7\14\3\0\10\14" - + "\1\370\35\14\27\0\2\14\7\0\7\14\3\0\10\14" - + "\1\371\35\14\27\0\2\14\7\0\7\14\3\0\3\14" - + "\1\372\42\14\27\0\2\14\7\0\7\14\3\0\11\14" - + "\1\373\34\14\27\0\2\14\7\0\7\14\3\0\12\14" - + "\1\374\33\14\27\0\2\14\7\0\7\14\3\0\2\14" - + "\1\375\4\14\1\376\2\14\1\377\33\14\27\0\2\14" - + "\7\0\7\14\3\0\5\14\1\u0100\40\14\27\0\2\14" - + "\7\0\7\14\3\0\1\u0101\45\14\27\0\2\14\7\0" - + "\7\14\3\0\3\14\1\u0102\42\14\27\0\2\14\7\0" - + "\7\14\3\0\5\14\1\u0103\1\u0104\1\u0105\6\14\1\u0106" - + "\27\14\27\0\2\14\7\0\7\14\3\0\1\14\1\u0107" - + "\44\14\27\0\2\14\7\0\7\14\3\0\12\14\1\u0108" - + "\33\14\27\0\2\14\7\0\7\14\3\0\11\14\1\u0109" - + "\34\14\27\0\2\14\7\0\7\14\3\0\11\14\1\u010a" - + "\34\14\27\0\2\14\7\0\7\14\3\0\1\14\1\u010b" - + "\44\14\27\0\2\14\7\0\7\14\3\0\44\14\1\u010c" - + "\1\14\27\0\2\14\7\0\7\14\3\0\23\14\1\u010d" - + "\22\14\27\0\2\14\7\0\7\14\3\0\15\14\1\u010e" - + "\30\14\36\0\1\u010f\121\0\1\250\3\0\2\250\112\0" - + "\1\u0110\3\0\2\u0110\101\0\1\u0111\12\0\2\u0111\2\0" - + "\1\u0111\3\0\46\u0111\35\0\1\262\1\263\116\0\1\263" - + "\1\0\1\u0112\107\0\1\u0113\12\0\2\u0113\2\0\1\u0113" - + "\3\0\46\u0113\27\0\1\u0114\1\265\1\u0115\2\0\1\112" - + "\1\u0116\2\0\2\265\2\u0114\2\265\1\u0114\3\0\46\u0114" - + "\23\0\1\267\115\0\5\270\1\u0117\112\270\4\0\1\267" - + "\1\271\120\0\2\273\3\0\1\u0118\3\0\7\273\3\0" - + "\46\273\27\0\2\274\1\u0119\2\0\1\276\1\u011a\1\u011b" - + "\1\0\7\274\3\0\46\274\27\0\1\u011c\12\0\2\u011c" - + "\2\0\1\u011c\3\0\46\u011c\27\0\1\u011d\5\0\1\277" - + "\4\0\2\u011d\2\0\1\u011d\3\0\46\u011d\36\0\1\u011e" - + "\121\0\2\u011f\1\0\4\u011f\3\0\1\u011f\1\0\2\u011f" - + "\1\0\1\u011f\6\0\2\u011f\12\0\1\u011f\1\0\1\u011f" - + "\5\0\2\u011f\36\0\1\123\5\0\1\u0120\1\133\2\0" - + "\2\u0120\1\137\5\0\1\137\103\0\2\307\2\0\2\307" - + "\101\0\2\14\7\0\7\14\3\0\3\14\1\u0121\42\14" - + "\27\0\2\14\7\0\7\14\3\0\13\14\1\u0122\32\14" - + "\27\0\2\14\7\0\7\14\3\0\7\14\1\u0123\36\14" - + "\27\0\2\14\7\0\7\14\3\0\14\14\1\u0124\31\14" - + "\27\0\2\14\7\0\7\14\3\0\20\14\1\u0125\25\14" - + "\27\0\2\14\7\0\7\14\3\0\2\14\1\u0126\43\14" - + "\27\0\2\14\7\0\7\14\3\0\16\14\1\u0127\27\14" - + "\27\0\2\14\7\0\7\14\3\0\2\14\1\u0128\43\14" - + "\27\0\2\14\7\0\7\14\3\0\2\14\1\u0129\43\14" - + "\27\0\2\14\7\0\7\14\3\0\5\14\1\u012a\40\14" - + "\27\0\2\14\7\0\7\14\3\0\6\14\1\u012b\2\14" - + "\1\u012c\34\14\27\0\2\14\7\0\7\14\3\0\6\14" - + "\1\u012d\37\14\27\0\2\14\7\0\7\14\3\0\1\14" - + "\1\u012e\7\14\1\u012f\34\14\27\0\2\14\7\0\7\14" - + "\3\0\21\14\1\u0130\24\14\27\0\2\14\7\0\7\14" - + "\3\0\6\14\1\u0131\37\14\27\0\2\14\7\0\7\14" - + "\3\0\2\14\1\u0132\43\14\27\0\2\14\7\0\7\14" - + "\3\0\11\14\1\u0133\34\14\27\0\2\14\7\0\7\14" - + "\3\0\1\14\1\u0134\44\14\27\0\2\14\7\0\7\14" - + "\3\0\16\14\1\u0135\27\14\27\0\2\14\7\0\7\14" - + "\3\0\11\14\1\u0136\34\14\27\0\2\14\7\0\7\14" - + "\3\0\2\14\1\u0137\43\14\27\0\2\14\7\0\7\14" - + "\3\0\16\14\1\u0138\27\14\27\0\2\14\7\0\7\14" - + "\3\0\5\14\1\u0139\40\14\27\0\2\14\7\0\7\14" - + "\3\0\2\14\1\u013a\43\14\27\0\2\14\7\0\7\14" - + "\3\0\16\14\1\u013b\27\14\27\0\2\14\7\0\7\14" - + "\3\0\26\14\1\u013c\17\14\27\0\2\14\7\0\7\14" - + "\3\0\26\14\1\u013d\17\14\27\0\2\14\7\0\7\14" - + "\3\0\7\14\1\u013e\36\14\27\0\2\14\7\0\7\14" - + "\3\0\6\14\1\u013f\37\14\27\0\2\14\7\0\7\14" - + "\3\0\2\14\1\u0140\43\14\27\0\2\14\7\0\7\14" - + "\3\0\11\14\1\u0141\34\14\27\0\2\14\7\0\7\14" - + "\3\0\2\14\1\u0142\43\14\27\0\2\14\7\0\7\14" - + "\3\0\1\14\1\u0143\44\14\27\0\2\14\7\0\7\14" - + "\3\0\7\14\1\u0144\6\14\1\u0145\27\14\27\0\2\14" - + "\7\0\7\14\3\0\2\14\1\u0146\43\14\27\0\2\14" - + "\7\0\7\14\3\0\3\14\1\u0147\42\14\27\0\2\14" - + "\7\0\7\14\3\0\2\14\1\u0148\43\14\27\0\2\14" - + "\7\0\7\14\3\0\16\14\1\u0149\27\14\27\0\2\14" - + "\7\0\7\14\3\0\3\14\1\u014a\42\14\27\0\2\14" - + "\7\0\7\14\3\0\6\14\1\u014b\37\14\27\0\2\14" - + "\7\0\7\14\3\0\3\14\1\u014c\42\14\27\0\2\14" - + "\7\0\7\14\3\0\5\14\1\u014d\40\14\27\0\2\14" - + "\7\0\7\14\3\0\26\14\1\u014e\17\14\27\0\2\14" - + "\7\0\7\14\3\0\14\14\1\u014f\31\14\27\0\2\14" - + "\7\0\7\14\3\0\20\14\1\u0150\25\14\27\0\2\14" - + "\7\0\7\14\3\0\16\14\1\u0151\27\14\27\0\2\14" - + "\7\0\7\14\3\0\24\14\1\u0152\21\14\27\0\2\14" - + "\7\0\7\14\3\0\11\14\1\u0153\34\14\27\0\2\14" - + "\7\0\7\14\3\0\24\14\1\u0154\21\14\27\0\2\14" - + "\7\0\7\14\3\0\4\14\1\u0155\41\14\27\0\2\14" - + "\7\0\7\14\3\0\16\14\1\u0156\27\14\27\0\2\14" - + "\7\0\7\14\3\0\22\14\1\u0157\23\14\27\0\2\14" - + "\7\0\7\14\3\0\20\14\1\u0158\25\14\27\0\2\14" - + "\7\0\7\14\3\0\13\14\1\u0159\32\14\27\0\2\14" - + "\7\0\7\14\3\0\1\14\1\u015a\44\14\27\0\2\14" - + "\7\0\7\14\3\0\2\14\1\u015b\43\14\27\0\2\14" - + "\7\0\7\14\3\0\14\14\1\u015c\31\14\27\0\2\14" - + "\7\0\7\14\3\0\27\14\1\u015d\3\14\1\u015e\12\14" - + "\27\0\2\14\7\0\7\14\3\0\7\14\1\u015f\36\14" - + "\27\0\2\14\7\0\7\14\3\0\12\14\1\u0160\33\14" - + "\27\0\2\14\7\0\7\14\3\0\1\u0161\45\14\27\0" - + "\2\14\7\0\7\14\3\0\12\14\1\u0162\33\14\27\0" - + "\2\u0111\4\0\1\262\1\263\1\0\7\u0111\3\0\46\u0111" - + "\21\0\1\u0112\2\0\13\u0112\1\u0163\101\u0112\6\0\2\u0113" - + "\1\u0164\2\0\1\u0165\3\0\7\u0113\3\0\46\u0113\27\0" - + "\2\u0114\1\u0166\2\0\1\112\1\u0167\1\u0168\1\0\7\u0114" - + "\3\0\46\u0114\27\0\1\u0169\12\0\2\u0169\2\0\1\u0169" - + "\3\0\46\u0169\27\0\1\u016a\5\0\1\u0116\4\0\2\u016a" - + "\2\0\1\u016a\3\0\46\u016a\21\0\4\270\1\267\1\u0117" - + "\112\270\6\0\1\u016b\12\0\2\u016b\2\0\1\u016b\3\0" - + "\46\u016b\27\0\1\u011d\5\0\1\u011a\1\u011b\3\0\2\u011d" - + "\2\0\1\u011d\3\0\46\u011d\35\0\1\u011b\1\0\1\u016c" - + "\107\0\1\u016d\1\u011c\3\0\1\276\1\277\2\0\2\u011c" - + "\2\u016d\2\u011c\1\u016d\3\0\46\u016d\27\0\2\u011d\1\u016e" - + "\3\0\1\u016f\1\u011b\1\0\7\u011d\3\0\46\u011d\40\0" - + "\2\u0170\1\0\4\u0170\3\0\1\u0170\1\0\2\u0170\1\0" - + "\1\u0170\6\0\2\u0170\12\0\1\u0170\1\0\1\u0170\5\0" - + "\2\u0170\36\0\1\123\5\0\1\u0171\1\133\2\0\2\u0171" + + "\1\321\2\14\1\322\4\14\1\323\27\14\27\0\2\14" + + "\7\0\7\14\3\0\10\14\1\324\35\14\27\0\2\14" + + "\7\0\7\14\3\0\3\14\1\325\42\14\27\0\2\14" + + "\7\0\7\14\3\0\1\14\1\326\44\14\27\0\2\14" + + "\7\0\7\14\3\0\11\14\1\327\34\14\27\0\2\14" + + "\7\0\7\14\3\0\3\14\1\330\3\14\1\331\36\14" + + "\27\0\2\14\7\0\7\14\3\0\1\332\20\14\1\333" + + "\24\14\27\0\2\14\7\0\7\14\3\0\12\14\1\334" + + "\33\14\27\0\2\14\7\0\7\14\3\0\14\14\1\335" + + "\31\14\27\0\2\14\7\0\7\14\3\0\2\14\1\336" + + "\43\14\27\0\2\14\7\0\7\14\3\0\17\14\1\337" + + "\5\14\1\340\20\14\27\0\2\14\7\0\7\14\3\0" + + "\23\14\1\341\22\14\27\0\2\14\7\0\7\14\3\0" + + "\16\14\1\342\27\14\27\0\2\14\7\0\7\14\3\0" + + "\3\14\1\343\7\14\1\344\6\14\1\345\23\14\27\0" + + "\2\14\7\0\7\14\3\0\16\14\1\346\27\14\27\0" + + "\2\14\7\0\7\14\3\0\1\14\1\347\44\14\27\0" + + "\2\14\7\0\7\14\3\0\26\14\1\350\17\14\27\0" + + "\2\14\7\0\7\14\3\0\1\14\1\351\10\14\1\352" + + "\33\14\27\0\2\14\7\0\7\14\3\0\21\14\1\353" + + "\24\14\27\0\2\14\7\0\7\14\3\0\6\14\1\354" + + "\2\14\1\355\34\14\27\0\2\14\7\0\7\14\3\0" + + "\32\14\1\356\13\14\27\0\2\14\7\0\7\14\3\0" + + "\21\14\1\357\24\14\27\0\2\14\7\0\7\14\3\0" + + "\2\14\1\360\43\14\27\0\2\14\7\0\7\14\3\0" + + "\14\14\1\361\1\14\1\362\27\14\27\0\2\14\7\0" + + "\7\14\3\0\15\14\1\363\1\364\27\14\27\0\2\14" + + "\7\0\7\14\3\0\21\14\1\365\24\14\27\0\2\14" + + "\7\0\7\14\3\0\10\14\1\366\35\14\27\0\2\14" + + "\7\0\7\14\3\0\16\14\1\367\27\14\27\0\2\14" + + "\7\0\7\14\3\0\1\14\1\370\44\14\27\0\2\14" + + "\7\0\7\14\3\0\10\14\1\371\35\14\27\0\2\14" + + "\7\0\7\14\3\0\10\14\1\372\35\14\27\0\2\14" + + "\7\0\7\14\3\0\10\14\1\373\35\14\27\0\2\14" + + "\7\0\7\14\3\0\3\14\1\374\42\14\27\0\2\14" + + "\7\0\7\14\3\0\11\14\1\375\34\14\27\0\2\14" + + "\7\0\7\14\3\0\12\14\1\376\33\14\27\0\2\14" + + "\7\0\7\14\3\0\2\14\1\377\4\14\1\u0100\2\14" + + "\1\u0101\33\14\27\0\2\14\7\0\7\14\3\0\5\14" + + "\1\u0102\40\14\27\0\2\14\7\0\7\14\3\0\1\u0103" + + "\45\14\27\0\2\14\7\0\7\14\3\0\3\14\1\u0104" + + "\42\14\27\0\2\14\7\0\7\14\3\0\5\14\1\u0105" + + "\1\u0106\1\u0107\6\14\1\u0108\27\14\27\0\2\14\7\0" + + "\7\14\3\0\1\14\1\u0109\44\14\27\0\2\14\7\0" + + "\7\14\3\0\12\14\1\u010a\33\14\27\0\2\14\7\0" + + "\7\14\3\0\11\14\1\u010b\34\14\27\0\2\14\7\0" + + "\7\14\3\0\11\14\1\u010c\34\14\27\0\2\14\7\0" + + "\7\14\3\0\1\14\1\u010d\44\14\27\0\2\14\7\0" + + "\7\14\3\0\44\14\1\u010e\1\14\27\0\2\14\7\0" + + "\7\14\3\0\23\14\1\u010f\22\14\27\0\2\14\7\0" + + "\7\14\3\0\15\14\1\u0110\30\14\36\0\1\u0111\121\0" + + "\1\250\3\0\2\250\112\0\1\u0112\3\0\2\u0112\101\0" + + "\1\u0113\12\0\2\u0113\2\0\1\u0113\3\0\46\u0113\35\0" + + "\1\262\1\263\116\0\1\263\1\0\1\u0114\107\0\1\u0115" + + "\12\0\2\u0115\2\0\1\u0115\3\0\46\u0115\27\0\1\u0116" + + "\1\265\1\u0117\2\0\1\112\1\u0118\2\0\2\265\2\u0116" + + "\2\265\1\u0116\3\0\46\u0116\23\0\1\267\115\0\5\270" + + "\1\u0119\112\270\4\0\1\267\1\271\120\0\2\273\3\0" + + "\1\u011a\3\0\7\273\3\0\46\273\27\0\2\274\1\u011b" + + "\2\0\1\276\1\u011c\1\u011d\1\0\7\274\3\0\46\274" + + "\27\0\1\u011e\12\0\2\u011e\2\0\1\u011e\3\0\46\u011e" + + "\27\0\1\u011f\5\0\1\277\4\0\2\u011f\2\0\1\u011f" + + "\3\0\46\u011f\36\0\1\u0120\121\0\2\u0121\1\0\4\u0121" + + "\3\0\1\u0121\1\0\2\u0121\1\0\1\u0121\6\0\2\u0121" + + "\12\0\1\u0121\1\0\1\u0121\5\0\2\u0121\36\0\1\123" + + "\5\0\1\u0122\1\133\2\0\2\u0122\1\137\5\0\1\137" + + "\103\0\2\307\2\0\2\307\101\0\2\14\7\0\7\14" + + "\3\0\3\14\1\u0123\42\14\27\0\2\14\7\0\7\14" + + "\3\0\13\14\1\u0124\32\14\27\0\2\14\7\0\7\14" + + "\3\0\7\14\1\u0125\36\14\27\0\2\14\7\0\7\14" + + "\3\0\14\14\1\u0126\31\14\27\0\2\14\7\0\7\14" + + "\3\0\20\14\1\u0127\25\14\27\0\2\14\7\0\7\14" + + "\3\0\2\14\1\u0128\43\14\27\0\2\14\7\0\7\14" + + "\3\0\16\14\1\u0129\27\14\27\0\2\14\7\0\7\14" + + "\3\0\2\14\1\u012a\43\14\27\0\2\14\7\0\7\14" + + "\3\0\2\14\1\u012b\43\14\27\0\2\14\7\0\7\14" + + "\3\0\5\14\1\u012c\40\14\27\0\2\14\7\0\7\14" + + "\3\0\16\14\1\u012d\27\14\27\0\2\14\7\0\7\14" + + "\3\0\6\14\1\u012e\2\14\1\u012f\34\14\27\0\2\14" + + "\7\0\7\14\3\0\6\14\1\u0130\37\14\27\0\2\14" + + "\7\0\7\14\3\0\1\14\1\u0131\7\14\1\u0132\34\14" + + "\27\0\2\14\7\0\7\14\3\0\21\14\1\u0133\24\14" + + "\27\0\2\14\7\0\7\14\3\0\6\14\1\u0134\37\14" + + "\27\0\2\14\7\0\7\14\3\0\2\14\1\u0135\43\14" + + "\27\0\2\14\7\0\7\14\3\0\11\14\1\u0136\34\14" + + "\27\0\2\14\7\0\7\14\3\0\1\14\1\u0137\44\14" + + "\27\0\2\14\7\0\7\14\3\0\16\14\1\u0138\27\14" + + "\27\0\2\14\7\0\7\14\3\0\11\14\1\u0139\34\14" + + "\27\0\2\14\7\0\7\14\3\0\2\14\1\u013a\43\14" + + "\27\0\2\14\7\0\7\14\3\0\16\14\1\u013b\27\14" + + "\27\0\2\14\7\0\7\14\3\0\5\14\1\u013c\40\14" + + "\27\0\2\14\7\0\7\14\3\0\2\14\1\u013d\43\14" + + "\27\0\2\14\7\0\7\14\3\0\16\14\1\u013e\27\14" + + "\27\0\2\14\7\0\7\14\3\0\26\14\1\u013f\17\14" + + "\27\0\2\14\7\0\7\14\3\0\26\14\1\u0140\17\14" + + "\27\0\2\14\7\0\7\14\3\0\7\14\1\u0141\36\14" + + "\27\0\2\14\7\0\7\14\3\0\6\14\1\u0142\37\14" + + "\27\0\2\14\7\0\7\14\3\0\2\14\1\u0143\43\14" + + "\27\0\2\14\7\0\7\14\3\0\11\14\1\u0144\34\14" + + "\27\0\2\14\7\0\7\14\3\0\2\14\1\u0145\43\14" + + "\27\0\2\14\7\0\7\14\3\0\1\14\1\u0146\44\14" + + "\27\0\2\14\7\0\7\14\3\0\7\14\1\u0147\6\14" + + "\1\u0148\27\14\27\0\2\14\7\0\7\14\3\0\2\14" + + "\1\u0149\43\14\27\0\2\14\7\0\7\14\3\0\7\14" + + "\1\u014a\36\14\27\0\2\14\7\0\7\14\3\0\3\14" + + "\1\u014b\42\14\27\0\2\14\7\0\7\14\3\0\2\14" + + "\1\u014c\43\14\27\0\2\14\7\0\7\14\3\0\16\14" + + "\1\u014d\27\14\27\0\2\14\7\0\7\14\3\0\3\14" + + "\1\u014e\42\14\27\0\2\14\7\0\7\14\3\0\6\14" + + "\1\u014f\37\14\27\0\2\14\7\0\7\14\3\0\3\14" + + "\1\u0150\42\14\27\0\2\14\7\0\7\14\3\0\5\14" + + "\1\u0151\40\14\27\0\2\14\7\0\7\14\3\0\26\14" + + "\1\u0152\17\14\27\0\2\14\7\0\7\14\3\0\14\14" + + "\1\u0153\31\14\27\0\2\14\7\0\7\14\3\0\20\14" + + "\1\u0154\25\14\27\0\2\14\7\0\7\14\3\0\16\14" + + "\1\u0155\27\14\27\0\2\14\7\0\7\14\3\0\24\14" + + "\1\u0156\21\14\27\0\2\14\7\0\7\14\3\0\11\14" + + "\1\u0157\34\14\27\0\2\14\7\0\7\14\3\0\10\14" + + "\1\u0158\13\14\1\u0159\21\14\27\0\2\14\7\0\7\14" + + "\3\0\4\14\1\u015a\41\14\27\0\2\14\7\0\7\14" + + "\3\0\16\14\1\u015b\27\14\27\0\2\14\7\0\7\14" + + "\3\0\22\14\1\u015c\23\14\27\0\2\14\7\0\7\14" + + "\3\0\20\14\1\u015d\25\14\27\0\2\14\7\0\7\14" + + "\3\0\13\14\1\u015e\32\14\27\0\2\14\7\0\7\14" + + "\3\0\1\14\1\u015f\44\14\27\0\2\14\7\0\7\14" + + "\3\0\2\14\1\u0160\43\14\27\0\2\14\7\0\7\14" + + "\3\0\14\14\1\u0161\31\14\27\0\2\14\7\0\7\14" + + "\3\0\27\14\1\u0162\3\14\1\u0163\6\14\1\u0164\3\14" + + "\27\0\2\14\7\0\7\14\3\0\7\14\1\u0165\36\14" + + "\27\0\2\14\7\0\7\14\3\0\12\14\1\u0166\33\14" + + "\27\0\2\14\7\0\7\14\3\0\1\u0167\45\14\27\0" + + "\2\14\7\0\7\14\3\0\12\14\1\u0168\33\14\27\0" + + "\2\u0113\4\0\1\262\1\263\1\0\7\u0113\3\0\46\u0113" + + "\21\0\1\u0114\2\0\13\u0114\1\u0169\101\u0114\6\0\2\u0115" + + "\1\u016a\2\0\1\u016b\3\0\7\u0115\3\0\46\u0115\27\0" + + "\2\u0116\1\u016c\2\0\1\112\1\u016d\1\u016e\1\0\7\u0116" + + "\3\0\46\u0116\27\0\1\u016f\12\0\2\u016f\2\0\1\u016f" + + "\3\0\46\u016f\27\0\1\u0170\5\0\1\u0118\4\0\2\u0170" + + "\2\0\1\u0170\3\0\46\u0170\21\0\4\270\1\267\1\u0119" + + "\112\270\6\0\1\u0171\12\0\2\u0171\2\0\1\u0171\3\0" + + "\46\u0171\27\0\1\u011f\5\0\1\u011c\1\u011d\3\0\2\u011f" + + "\2\0\1\u011f\3\0\46\u011f\35\0\1\u011d\1\0\1\u0172" + + "\107\0\1\u0173\1\u011e\3\0\1\276\1\277\2\0\2\u011e" + + "\2\u0173\2\u011e\1\u0173\3\0\46\u0173\27\0\2\u011f\1\u0174" + + "\3\0\1\u0175\1\u011d\1\0\7\u011f\3\0\46\u011f\40\0" + + "\2\u0176\1\0\4\u0176\3\0\1\u0176\1\0\2\u0176\1\0" + + "\1\u0176\6\0\2\u0176\12\0\1\u0176\1\0\1\u0176\5\0" + + "\2\u0176\36\0\1\123\5\0\1\u0177\1\133\2\0\2\u0177" + "\1\137\5\0\1\137\72\0\2\14\7\0\7\14\3\0" - + "\4\14\1\u0172\41\14\27\0\2\14\7\0\7\14\3\0" - + "\1\14\1\u0173\44\14\27\0\2\14\7\0\7\14\3\0" - + "\24\14\1\u0174\21\14\27\0\2\14\7\0\7\14\3\0" - + "\7\14\1\u0175\36\14\27\0\2\14\7\0\7\14\3\0" - + "\10\14\1\u0176\35\14\27\0\2\14\7\0\7\14\3\0" - + "\20\14\1\u0177\25\14\27\0\2\14\7\0\7\14\3\0" - + "\11\14\1\u0178\34\14\27\0\2\14\7\0\7\14\3\0" - + "\12\14\1\u0179\33\14\27\0\2\14\7\0\7\14\3\0" - + "\6\14\1\u017a\37\14\27\0\2\14\7\0\7\14\3\0" - + "\11\14\1\u017b\34\14\27\0\2\14\7\0\7\14\3\0" - + "\12\14\1\u017c\33\14\27\0\2\14\7\0\7\14\3\0" - + "\30\14\1\u017d\10\14\1\u017e\4\14\27\0\2\14\7\0" - + "\7\14\3\0\11\14\1\u017f\34\14\27\0\2\14\7\0" - + "\7\14\3\0\1\14\1\u0180\44\14\27\0\2\14\7\0" - + "\7\14\3\0\5\14\1\u0181\40\14\27\0\2\14\7\0" - + "\7\14\3\0\1\14\1\u0182\44\14\27\0\2\14\7\0" - + "\7\14\3\0\12\14\1\u0183\33\14\27\0\2\14\7\0" - + "\7\14\3\0\32\14\1\u0184\13\14\27\0\2\14\7\0" - + "\7\14\3\0\6\14\1\u0185\37\14\27\0\2\14\7\0" - + "\7\14\3\0\2\14\1\u0186\43\14\27\0\2\14\7\0" - + "\7\14\3\0\33\14\1\u0187\12\14\27\0\2\14\7\0" - + "\7\14\3\0\2\14\1\u0188\43\14\27\0\2\14\7\0" - + "\7\14\3\0\16\14\1\u0189\27\14\27\0\2\14\7\0" - + "\7\14\3\0\17\14\1\u018a\26\14\27\0\2\14\7\0" - + "\7\14\3\0\7\14\1\u018b\36\14\27\0\2\14\7\0" - + "\7\14\3\0\3\14\1\u018c\42\14\27\0\2\14\7\0" - + "\7\14\3\0\1\14\1\u018d\44\14\27\0\2\14\7\0" - + "\7\14\3\0\3\14\1\u018e\42\14\27\0\2\14\7\0" - + "\7\14\3\0\1\14\1\u018f\44\14\27\0\2\14\7\0" - + "\7\14\3\0\2\14\1\u0190\43\14\27\0\2\14\7\0" - + "\7\14\3\0\15\14\1\u0191\30\14\27\0\2\14\7\0" - + "\7\14\3\0\13\14\1\u0192\32\14\27\0\2\14\7\0" - + "\7\14\3\0\11\14\1\u0193\34\14\27\0\2\14\7\0" - + "\7\14\3\0\12\14\1\u0194\33\14\27\0\2\14\7\0" - + "\7\14\3\0\23\14\1\u0195\22\14\27\0\2\14\7\0" + + "\4\14\1\u0178\41\14\27\0\2\14\7\0\7\14\3\0" + + "\1\14\1\u0179\44\14\27\0\2\14\7\0\7\14\3\0" + + "\24\14\1\u017a\21\14\27\0\2\14\7\0\7\14\3\0" + + "\7\14\1\u017b\36\14\27\0\2\14\7\0\7\14\3\0" + + "\10\14\1\u017c\35\14\27\0\2\14\7\0\7\14\3\0" + + "\20\14\1\u017d\25\14\27\0\2\14\7\0\7\14\3\0" + + "\11\14\1\u017e\34\14\27\0\2\14\7\0\7\14\3\0" + + "\12\14\1\u017f\33\14\27\0\2\14\7\0\7\14\3\0" + + "\6\14\1\u0180\37\14\27\0\2\14\7\0\7\14\3\0" + + "\11\14\1\u0181\34\14\27\0\2\14\7\0\7\14\3\0" + + "\12\14\1\u0182\33\14\27\0\2\14\7\0\7\14\3\0" + + "\30\14\1\u0183\10\14\1\u0184\4\14\27\0\2\14\7\0" + + "\7\14\3\0\11\14\1\u0185\34\14\27\0\2\14\7\0" + + "\7\14\3\0\1\14\1\u0186\44\14\27\0\2\14\7\0" + + "\7\14\3\0\5\14\1\u0187\40\14\27\0\2\14\7\0" + + "\7\14\3\0\1\14\1\u0188\44\14\27\0\2\14\7\0" + + "\7\14\3\0\12\14\1\u0189\33\14\27\0\2\14\7\0" + + "\7\14\3\0\32\14\1\u018a\13\14\27\0\2\14\7\0" + + "\7\14\3\0\6\14\1\u018b\37\14\27\0\2\14\7\0" + + "\7\14\3\0\2\14\1\u018c\43\14\27\0\2\14\7\0" + + "\7\14\3\0\33\14\1\u018d\12\14\27\0\2\14\7\0" + + "\7\14\3\0\2\14\1\u018e\43\14\27\0\2\14\7\0" + + "\7\14\3\0\16\14\1\u018f\27\14\27\0\2\14\7\0" + + "\7\14\3\0\17\14\1\u0190\26\14\27\0\2\14\7\0" + + "\7\14\3\0\7\14\1\u0191\36\14\27\0\2\14\7\0" + + "\7\14\3\0\3\14\1\u0192\42\14\27\0\2\14\7\0" + + "\7\14\3\0\1\14\1\u0193\44\14\27\0\2\14\7\0" + + "\7\14\3\0\3\14\1\u0194\42\14\27\0\2\14\7\0" + + "\7\14\3\0\1\14\1\u0195\44\14\27\0\2\14\7\0" + "\7\14\3\0\2\14\1\u0196\43\14\27\0\2\14\7\0" - + "\7\14\3\0\16\14\1\u0197\27\14\27\0\2\14\7\0" - + "\7\14\3\0\11\14\1\u0198\34\14\27\0\2\14\7\0" - + "\7\14\3\0\11\14\1\u0199\34\14\27\0\2\14\7\0" - + "\7\14\3\0\37\14\1\u019a\2\14\1\u019b\3\14\27\0" - + "\2\14\7\0\7\14\3\0\2\14\1\u019c\43\14\27\0" - + "\2\14\7\0\7\14\3\0\32\14\1\u019d\13\14\27\0" - + "\2\14\7\0\7\14\3\0\2\14\1\u019e\43\14\27\0" - + "\2\14\7\0\7\14\3\0\3\14\1\u019f\42\14\27\0" - + "\2\14\7\0\7\14\3\0\3\14\1\u01a0\42\14\27\0" - + "\2\14\7\0\7\14\3\0\12\14\1\u01a1\33\14\27\0" - + "\2\14\7\0\7\14\3\0\1\14\1\u01a2\44\14\27\0" - + "\2\14\7\0\7\14\3\0\1\u01a3\45\14\27\0\2\14" - + "\7\0\7\14\3\0\14\14\1\u01a4\31\14\27\0\2\14" - + "\7\0\7\14\3\0\10\14\1\u01a5\35\14\27\0\2\14" - + "\7\0\7\14\3\0\1\14\1\u01a6\44\14\27\0\2\14" - + "\7\0\7\14\3\0\12\14\1\u01a7\33\14\27\0\2\14" - + "\7\0\7\14\3\0\30\14\1\u01a8\15\14\27\0\2\14" - + "\7\0\7\14\3\0\10\14\1\u01a9\35\14\27\0\2\14" - + "\7\0\7\14\3\0\2\14\1\u01aa\43\14\27\0\2\14" - + "\7\0\7\14\3\0\10\14\1\u01ab\35\14\21\0\1\u0112" - + "\2\0\11\u0112\1\u0163\1\u0112\1\u0163\101\u0112\6\0\1\u01ac" - + "\12\0\2\u01ac\2\0\1\u01ac\3\0\46\u01ac\27\0\1\u01ad" - + "\12\0\2\u01ad\2\0\1\u01ad\3\0\46\u01ad\27\0\1\u016a" - + "\5\0\1\u0167\1\u0168\3\0\2\u016a\2\0\1\u016a\3\0" - + "\46\u016a\35\0\1\u0168\1\0\1\u01ae\107\0\1\u01af\1\u0169" - + "\3\0\1\112\1\u0116\2\0\2\u0169\2\u01af\2\u0169\1\u01af" - + "\3\0\46\u01af\27\0\2\u016a\1\u01b0\3\0\1\u01b1\1\u0168" - + "\1\0\7\u016a\3\0\46\u016a\27\0\1\u016d\1\u016b\3\0" - + "\1\276\1\u011a\1\u011b\1\0\2\u016b\2\u016d\2\u016b\1\u016d" - + "\3\0\46\u016d\21\0\1\u016c\2\0\13\u016c\1\u01b2\101\u016c" - + "\6\0\2\u016d\1\u016e\2\0\1\276\1\u011a\1\u011b\1\0" - + "\7\u016d\3\0\46\u016d\27\0\1\u01b3\12\0\2\u01b3\2\0" - + "\1\u01b3\3\0\46\u01b3\35\0\1\u016f\1\u011b\121\0\2\u01b4" - + "\1\0\4\u01b4\3\0\1\u01b4\1\0\2\u01b4\1\0\1\u01b4" - + "\6\0\2\u01b4\12\0\1\u01b4\1\0\1\u01b4\5\0\2\u01b4" - + "\36\0\1\123\5\0\1\u01b5\1\133\2\0\2\u01b5\1\137" + + "\7\14\3\0\15\14\1\u0197\30\14\27\0\2\14\7\0" + + "\7\14\3\0\3\14\1\u0198\42\14\27\0\2\14\7\0" + + "\7\14\3\0\13\14\1\u0199\32\14\27\0\2\14\7\0" + + "\7\14\3\0\11\14\1\u019a\34\14\27\0\2\14\7\0" + + "\7\14\3\0\12\14\1\u019b\33\14\27\0\2\14\7\0" + + "\7\14\3\0\23\14\1\u019c\22\14\27\0\2\14\7\0" + + "\7\14\3\0\2\14\1\u019d\43\14\27\0\2\14\7\0" + + "\7\14\3\0\16\14\1\u019e\27\14\27\0\2\14\7\0" + + "\7\14\3\0\11\14\1\u019f\34\14\27\0\2\14\7\0" + + "\7\14\3\0\11\14\1\u01a0\34\14\27\0\2\14\7\0" + + "\7\14\3\0\37\14\1\u01a1\2\14\1\u01a2\3\14\27\0" + + "\2\14\7\0\7\14\3\0\2\14\1\u01a3\43\14\27\0" + + "\2\14\7\0\7\14\3\0\32\14\1\u01a4\13\14\27\0" + + "\2\14\7\0\7\14\3\0\2\14\1\u01a5\43\14\27\0" + + "\2\14\7\0\7\14\3\0\11\14\1\u01a6\34\14\27\0" + + "\2\14\7\0\7\14\3\0\3\14\1\u01a7\42\14\27\0" + + "\2\14\7\0\7\14\3\0\3\14\1\u01a8\42\14\27\0" + + "\2\14\7\0\7\14\3\0\12\14\1\u01a9\33\14\27\0" + + "\2\14\7\0\7\14\3\0\1\14\1\u01aa\44\14\27\0" + + "\2\14\7\0\7\14\3\0\1\u01ab\45\14\27\0\2\14" + + "\7\0\7\14\3\0\14\14\1\u01ac\31\14\27\0\2\14" + + "\7\0\7\14\3\0\10\14\1\u01ad\35\14\27\0\2\14" + + "\7\0\7\14\3\0\1\14\1\u01ae\44\14\27\0\2\14" + + "\7\0\7\14\3\0\12\14\1\u01af\33\14\27\0\2\14" + + "\7\0\7\14\3\0\2\14\1\u01b0\43\14\27\0\2\14" + + "\7\0\7\14\3\0\30\14\1\u01b1\15\14\27\0\2\14" + + "\7\0\7\14\3\0\10\14\1\u01b2\35\14\27\0\2\14" + + "\7\0\7\14\3\0\2\14\1\u01b3\43\14\27\0\2\14" + + "\7\0\7\14\3\0\10\14\1\u01b4\35\14\21\0\1\u0114" + + "\2\0\11\u0114\1\u0169\1\u0114\1\u0169\101\u0114\6\0\1\u01b5" + + "\12\0\2\u01b5\2\0\1\u01b5\3\0\46\u01b5\27\0\1\u01b6" + + "\12\0\2\u01b6\2\0\1\u01b6\3\0\46\u01b6\27\0\1\u0170" + + "\5\0\1\u016d\1\u016e\3\0\2\u0170\2\0\1\u0170\3\0" + + "\46\u0170\35\0\1\u016e\1\0\1\u01b7\107\0\1\u01b8\1\u016f" + + "\3\0\1\112\1\u0118\2\0\2\u016f\2\u01b8\2\u016f\1\u01b8" + + "\3\0\46\u01b8\27\0\2\u0170\1\u01b9\3\0\1\u01ba\1\u016e" + + "\1\0\7\u0170\3\0\46\u0170\27\0\1\u0173\1\u0171\3\0" + + "\1\276\1\u011c\1\u011d\1\0\2\u0171\2\u0173\2\u0171\1\u0173" + + "\3\0\46\u0173\21\0\1\u0172\2\0\13\u0172\1\u01bb\101\u0172" + + "\6\0\2\u0173\1\u0174\2\0\1\276\1\u011c\1\u011d\1\0" + + "\7\u0173\3\0\46\u0173\27\0\1\u01bc\12\0\2\u01bc\2\0" + + "\1\u01bc\3\0\46\u01bc\35\0\1\u0175\1\u011d\121\0\2\u01bd" + + "\1\0\4\u01bd\3\0\1\u01bd\1\0\2\u01bd\1\0\1\u01bd" + + "\6\0\2\u01bd\12\0\1\u01bd\1\0\1\u01bd\5\0\2\u01bd" + + "\36\0\1\123\5\0\1\u01be\1\133\2\0\2\u01be\1\137" + "\5\0\1\137\72\0\2\14\7\0\7\14\3\0\10\14" - + "\1\u01b6\35\14\27\0\2\14\7\0\7\14\3\0\2\14" - + "\1\u01b7\43\14\27\0\2\14\7\0\7\14\3\0\23\14" - + "\1\u01b8\22\14\27\0\2\14\7\0\7\14\3\0\14\14" - + "\1\u01b9\31\14\27\0\2\14\7\0\7\14\3\0\10\14" - + "\1\u01ba\35\14\27\0\2\14\7\0\7\14\3\0\41\14" - + "\1\u01bb\4\14\27\0\2\14\7\0\7\14\3\0\5\14" - + "\1\u01bc\40\14\27\0\2\14\7\0\7\14\3\0\16\14" - + "\1\u01bd\27\14\27\0\2\14\7\0\7\14\3\0\1\14" - + "\1\u01be\44\14\27\0\2\14\7\0\7\14\3\0\1\14" - + "\1\u01bf\44\14\27\0\2\14\7\0\7\14\3\0\20\14" - + "\1\u01c0\25\14\27\0\2\14\7\0\7\14\3\0\12\14" - + "\1\u01c1\33\14\27\0\2\14\7\0\7\14\3\0\10\14" - + "\1\u01c2\35\14\27\0\2\14\7\0\7\14\3\0\1\14" - + "\1\u01c3\44\14\27\0\2\14\7\0\7\14\3\0\21\14" - + "\1\u01c4\24\14\27\0\2\14\7\0\7\14\3\0\3\14" - + "\1\u01c5\42\14\27\0\2\14\7\0\7\14\3\0\11\14" - + "\1\u01c6\34\14\27\0\2\14\7\0\7\14\3\0\2\14" - + "\1\u01c7\43\14\27\0\2\14\7\0\7\14\3\0\15\14" - + "\1\u01c8\30\14\27\0\2\14\7\0\7\14\3\0\10\14" - + "\1\u01c9\35\14\27\0\2\14\7\0\7\14\3\0\10\14" - + "\1\u01ca\4\14\1\u01cb\30\14\27\0\2\14\7\0\7\14" - + "\3\0\23\14\1\u01cc\22\14\27\0\2\14\7\0\7\14" - + "\3\0\11\14\1\u01cd\34\14\27\0\2\14\7\0\7\14" - + "\3\0\23\14\1\u01ce\22\14\27\0\2\14\7\0\7\14" - + "\3\0\12\14\1\u01cf\33\14\27\0\2\14\7\0\7\14" - + "\3\0\16\14\1\u01d0\27\14\27\0\2\14\7\0\7\14" - + "\3\0\2\14\1\u01d1\43\14\27\0\2\14\7\0\7\14" - + "\3\0\5\14\1\u01d2\40\14\27\0\2\14\7\0\7\14" - + "\3\0\12\14\1\u01d3\33\14\27\0\2\14\7\0\7\14" - + "\3\0\16\14\1\u01d4\27\14\27\0\2\14\7\0\7\14" - + "\3\0\12\14\1\u01d5\33\14\27\0\2\14\7\0\7\14" - + "\3\0\20\14\1\u01d6\25\14\27\0\2\14\7\0\7\14" - + "\3\0\7\14\1\u01d7\36\14\27\0\2\14\7\0\7\14" - + "\3\0\3\14\1\u01d8\42\14\27\0\2\14\7\0\7\14" - + "\3\0\1\14\1\u01d9\44\14\27\0\2\14\7\0\7\14" - + "\3\0\5\14\1\u01da\40\14\27\0\2\14\7\0\7\14" - + "\3\0\11\14\1\u01db\34\14\27\0\2\14\7\0\7\14" - + "\3\0\26\14\1\u01dc\17\14\27\0\2\14\7\0\7\14" - + "\3\0\5\14\1\u01dd\40\14\27\0\2\14\7\0\7\14" - + "\3\0\6\14\1\u01de\37\14\27\0\2\14\7\0\7\14" - + "\3\0\26\14\1\u01df\17\14\27\0\2\14\7\0\7\14" - + "\3\0\16\14\1\u01e0\27\14\27\0\2\14\7\0\7\14" - + "\3\0\23\14\1\u01e1\22\14\27\0\2\14\7\0\7\14" - + "\3\0\10\14\1\u01e2\35\14\27\0\2\14\7\0\7\14" - + "\3\0\26\14\1\u01e3\17\14\27\0\2\14\7\0\7\14" - + "\3\0\1\14\1\u01e4\44\14\27\0\2\14\7\0\7\14" - + "\3\0\12\14\1\u01e5\33\14\27\0\2\u01ac\3\0\1\u0165" - + "\3\0\7\u01ac\3\0\46\u01ac\27\0\1\u01af\1\u01ad\3\0" - + "\1\112\1\u0167\1\u0168\1\0\2\u01ad\2\u01af\2\u01ad\1\u01af" - + "\3\0\46\u01af\21\0\1\u01ae\2\0\13\u01ae\1\u01e6\101\u01ae" - + "\6\0\2\u01af\1\u01b0\2\0\1\112\1\u0167\1\u0168\1\0" - + "\7\u01af\3\0\46\u01af\27\0\1\u01e7\12\0\2\u01e7\2\0" - + "\1\u01e7\3\0\46\u01e7\35\0\1\u01b1\1\u0168\102\0\1\u016c" - + "\2\0\10\u016c\1\u01e8\1\u01b2\1\u016c\1\u01b2\101\u016c\6\0" - + "\2\u01b3\4\0\1\u016f\1\u011b\1\0\7\u01b3\3\0\46\u01b3" - + "\40\0\2\u01e9\1\0\4\u01e9\3\0\1\u01e9\1\0\2\u01e9" - + "\1\0\1\u01e9\6\0\2\u01e9\12\0\1\u01e9\1\0\1\u01e9" - + "\5\0\2\u01e9\36\0\1\123\5\0\1\u01ea\1\133\2\0" - + "\2\u01ea\1\137\5\0\1\137\72\0\2\14\7\0\7\14" - + "\3\0\37\14\1\u01eb\6\14\27\0\2\14\7\0\7\14" - + "\3\0\6\14\1\u01ec\37\14\27\0\2\14\7\0\7\14" - + "\3\0\13\14\1\u01ed\32\14\27\0\2\14\7\0\7\14" - + "\3\0\1\14\1\u01ee\44\14\27\0\2\14\7\0\7\14" - + "\3\0\16\14\1\u01ef\27\14\27\0\2\14\7\0\7\14" - + "\3\0\3\14\1\u01f0\42\14\27\0\2\14\7\0\7\14" - + "\3\0\14\14\1\u01f1\31\14\27\0\2\14\7\0\7\14" - + "\3\0\2\14\1\u01f2\43\14\27\0\2\14\7\0\7\14" - + "\3\0\3\14\1\u01f3\42\14\27\0\2\14\7\0\7\14" - + "\3\0\3\14\1\u01f4\42\14\27\0\2\14\7\0\7\14" - + "\3\0\1\14\1\u01f5\44\14\27\0\2\14\7\0\7\14" - + "\3\0\43\14\1\u01f6\2\14\27\0\2\14\7\0\7\14" - + "\3\0\34\14\1\u01f7\11\14\27\0\2\14\7\0\7\14" - + "\3\0\5\14\1\u01f8\40\14\27\0\2\14\7\0\7\14" - + "\3\0\3\14\1\u01f9\42\14\27\0\2\14\7\0\7\14" - + "\3\0\3\14\1\u01fa\42\14\27\0\2\14\7\0\7\14" - + "\3\0\2\14\1\u01fb\43\14\27\0\2\14\7\0\7\14" - + "\3\0\2\14\1\u01fc\43\14\27\0\2\14\7\0\7\14" - + "\3\0\10\14\1\u01fd\35\14\27\0\2\14\7\0\7\14" - + "\3\0\11\14\1\u01fe\34\14\27\0\2\14\7\0\7\14" - + "\3\0\3\14\1\u01ff\42\14\27\0\2\14\7\0\7\14" - + "\3\0\5\14\1\u0200\40\14\27\0\2\14\7\0\7\14" - + "\3\0\22\14\1\u0201\23\14\27\0\2\14\7\0\7\14" - + "\3\0\7\14\1\u0202\36\14\27\0\2\14\7\0\7\14" - + "\3\0\24\14\1\u0203\21\14\27\0\2\14\7\0\7\14" - + "\3\0\1\14\1\u0204\44\14\27\0\2\14\7\0\7\14" - + "\3\0\3\14\1\u0205\42\14\27\0\2\14\7\0\7\14" - + "\3\0\11\14\1\u0206\34\14\27\0\2\14\7\0\7\14" - + "\3\0\2\14\1\u0207\43\14\27\0\2\14\7\0\7\14" - + "\3\0\2\14\1\u0208\43\14\27\0\2\14\7\0\7\14" - + "\3\0\11\14\1\u0209\34\14\27\0\2\14\7\0\7\14" - + "\3\0\11\14\1\u020a\34\14\27\0\2\14\7\0\7\14" - + "\3\0\2\14\1\u020b\43\14\27\0\2\14\7\0\7\14" - + "\3\0\14\14\1\u020c\31\14\27\0\2\14\7\0\7\14" - + "\3\0\11\14\1\u020d\34\14\21\0\1\u01ae\2\0\10\u01ae" - + "\1\u020e\1\u01e6\1\u01ae\1\u01e6\101\u01ae\6\0\2\u01e7\4\0" - + "\1\u01b1\1\u0168\1\0\7\u01e7\3\0\46\u01e7\40\0\2\u020f" - + "\1\0\4\u020f\3\0\1\u020f\1\0\2\u020f\1\0\1\u020f" - + "\6\0\2\u020f\12\0\1\u020f\1\0\1\u020f\5\0\2\u020f" - + "\36\0\1\123\5\0\1\u0210\1\133\2\0\2\u0210\1\137" - + "\5\0\1\137\72\0\2\14\7\0\7\14\3\0\7\14" - + "\1\u0211\36\14\27\0\2\14\7\0\7\14\3\0\2\14" - + "\1\u0212\43\14\27\0\2\14\7\0\7\14\3\0\3\14" - + "\1\u0213\42\14\27\0\2\14\7\0\7\14\3\0\31\14" - + "\1\u0214\14\14\27\0\2\14\7\0\7\14\3\0\26\14" - + "\1\u0215\17\14\27\0\2\14\7\0\7\14\3\0\2\14" - + "\1\u0216\43\14\27\0\2\14\7\0\7\14\3\0\23\14" - + "\1\u0217\22\14\27\0\2\14\7\0\7\14\3\0\5\14" - + "\1\u0218\40\14\27\0\2\14\7\0\7\14\3\0\26\14" - + "\1\u0219\17\14\27\0\2\14\7\0\7\14\3\0\3\14" - + "\1\u021a\42\14\27\0\2\14\7\0\7\14\3\0\12\14" - + "\1\u021b\33\14\27\0\2\14\7\0\7\14\3\0\2\14" - + "\1\u021c\43\14\27\0\2\14\7\0\7\14\3\0\16\14" - + "\1\u021d\27\14\27\0\2\14\7\0\7\14\3\0\5\14" - + "\1\u021e\40\14\27\0\2\14\7\0\7\14\3\0\36\14" - + "\1\u021f\7\14\27\0\2\14\7\0\7\14\3\0\10\14" - + "\1\u0220\35\14\27\0\2\14\7\0\7\14\3\0\2\14" - + "\1\u0221\43\14\27\0\2\14\7\0\7\14\3\0\11\14" - + "\1\u0222\34\14\27\0\2\14\7\0\7\14\3\0\10\14" - + "\1\u0223\35\14\27\0\2\14\7\0\7\14\3\0\12\14" - + "\1\u0224\33\14\27\0\2\14\7\0\7\14\3\0\12\14" - + "\1\u0225\33\14\27\0\2\14\7\0\7\14\3\0\23\14" - + "\1\u0226\22\14\27\0\2\14\7\0\7\14\3\0\2\14" - + "\1\u0227\43\14\27\0\2\14\7\0\7\14\3\0\1\14" - + "\1\u0228\44\14\27\0\2\14\7\0\7\14\3\0\20\14" - + "\1\u0229\25\14\27\0\2\14\7\0\7\14\3\0\1\14" - + "\1\u022a\44\14\27\0\2\14\7\0\7\14\3\0\31\14" - + "\1\u022b\11\14\1\u022c\2\14\27\0\2\14\7\0\7\14" - + "\3\0\22\14\1\u022d\23\14\40\0\2\u022e\1\0\4\u022e" - + "\3\0\1\u022e\1\0\2\u022e\1\0\1\u022e\6\0\2\u022e" - + "\12\0\1\u022e\1\0\1\u022e\5\0\2\u022e\36\0\1\123" - + "\5\0\1\u022f\1\133\2\0\2\u022f\1\137\5\0\1\137" - + "\72\0\2\14\7\0\7\14\3\0\24\14\1\u0230\21\14" - + "\27\0\2\14\7\0\7\14\3\0\26\14\1\u0231\17\14" - + "\27\0\2\14\7\0\7\14\3\0\7\14\1\u0232\36\14" - + "\27\0\2\14\7\0\7\14\3\0\2\14\1\u0233\43\14" - + "\27\0\2\14\7\0\7\14\3\0\2\14\1\u0234\43\14" - + "\27\0\2\14\7\0\7\14\3\0\2\14\1\u0235\43\14" - + "\27\0\2\14\7\0\7\14\3\0\11\14\1\u0236\34\14" - + "\27\0\2\14\7\0\7\14\3\0\26\14\1\u0237\17\14" - + "\27\0\2\14\7\0\7\14\3\0\7\14\1\u0238\36\14" - + "\27\0\2\14\7\0\7\14\3\0\2\14\1\u0239\43\14" - + "\27\0\2\14\7\0\7\14\3\0\7\14\1\u023a\36\14" - + "\27\0\2\14\7\0\7\14\3\0\11\14\1\u023b\34\14" - + "\27\0\2\14\7\0\7\14\3\0\14\14\1\u023c\31\14" - + "\27\0\2\14\7\0\7\14\3\0\2\14\1\u023d\43\14" - + "\27\0\2\14\7\0\7\14\3\0\2\14\1\u023e\43\14" - + "\27\0\2\14\7\0\7\14\3\0\3\14\1\u023f\42\14" - + "\27\0\2\14\7\0\7\14\3\0\2\14\1\u0240\43\14" - + "\27\0\2\14\7\0\7\14\3\0\14\14\1\u0241\31\14" - + "\27\0\2\14\7\0\7\14\3\0\12\14\1\u0242\33\14" - + "\27\0\2\14\7\0\7\14\3\0\11\14\1\u0243\34\14" - + "\27\0\2\14\7\0\7\14\3\0\16\14\1\u0244\27\14" - + "\40\0\2\u0245\1\0\4\u0245\3\0\1\u0245\1\0\2\u0245" - + "\1\0\1\u0245\6\0\2\u0245\12\0\1\u0245\1\0\1\u0245" - + "\5\0\2\u0245\36\0\1\123\5\0\1\u0246\1\133\2\0" - + "\2\u0246\1\137\5\0\1\137\72\0\2\14\7\0\7\14" - + "\3\0\12\14\1\u0247\33\14\27\0\2\14\7\0\7\14" - + "\3\0\13\14\1\u0248\32\14\27\0\2\14\7\0\7\14" - + "\3\0\11\14\1\u0249\34\14\27\0\2\14\7\0\7\14" - + "\3\0\20\14\1\u024a\25\14\27\0\2\14\7\0\7\14" - + "\3\0\20\14\1\u024b\25\14\27\0\2\14\7\0\7\14" - + "\3\0\15\14\1\u024c\30\14\27\0\2\14\7\0\7\14" - + "\3\0\3\14\1\u024d\42\14\27\0\2\14\7\0\7\14" - + "\3\0\6\14\1\u024e\37\14\27\0\2\14\7\0\7\14" - + "\3\0\37\14\1\u024f\6\14\27\0\2\14\7\0\7\14" - + "\3\0\1\u0250\45\14\27\0\2\14\7\0\7\14\3\0" - + "\10\14\1\u0251\35\14\27\0\2\14\7\0\7\14\3\0" - + "\7\14\1\u0252\36\14\27\0\2\14\7\0\7\14\3\0" - + "\3\14\1\u0253\42\14\32\0\1\123\5\0\1\u0254\1\133" - + "\2\0\2\u0254\1\137\5\0\1\137\72\0\2\14\7\0" - + "\7\14\3\0\2\14\1\u0255\43\14\27\0\2\14\7\0" - + "\7\14\3\0\10\14\1\u0256\35\14\27\0\2\14\7\0" - + "\7\14\3\0\35\14\1\u0257\10\14\27\0\2\14\7\0" - + "\7\14\3\0\14\14\1\u0258\31\14\27\0\2\14\7\0" - + "\7\14\3\0\7\14\1\u0259\36\14\27\0\2\14\7\0" - + "\7\14\3\0\16\14\1\u025a\27\14\27\0\2\14\7\0" - + "\7\14\3\0\26\14\1\u025b\17\14\27\0\2\14\7\0" - + "\7\14\3\0\21\14\1\u025c\24\14\27\0\2\14\7\0" - + "\7\14\3\0\22\14\1\u025d\23\14\32\0\1\123\5\0" - + "\1\u025e\1\133\2\0\2\u025e\1\137\5\0\1\137\72\0" - + "\2\14\7\0\7\14\3\0\40\14\1\u025f\5\14\27\0" - + "\2\14\7\0\7\14\3\0\14\14\1\u0260\31\14\27\0" - + "\2\14\7\0\7\14\3\0\13\14\1\u0261\32\14\27\0" - + "\2\14\7\0\7\14\3\0\2\14\1\u0262\43\14\27\0" - + "\2\14\7\0\7\14\3\0\24\14\1\u0263\21\14\27\0" - + "\2\14\7\0\7\14\3\0\2\14\1\u0264\43\14\32\0" - + "\1\123\5\0\1\u0265\1\133\2\0\2\u0265\1\137\5\0" - + "\1\137\72\0\2\14\7\0\7\14\3\0\16\14\1\u0266" - + "\27\14\27\0\2\14\7\0\7\14\3\0\6\14\1\u0267" - + "\37\14\27\0\2\14\7\0\7\14\3\0\3\14\1\u0268" - + "\42\14\27\0\2\14\7\0\7\14\3\0\14\14\1\u0269" - + "\31\14\27\0\2\14\7\0\7\14\3\0\12\14\1\u026a" - + "\33\14\27\0\2\14\7\0\7\14\3\0\6\14\1\u026b" - + "\37\14\32\0\1\123\5\0\1\u026c\1\133\2\0\2\u026c" + + "\1\u01bf\35\14\27\0\2\14\7\0\7\14\3\0\2\14" + + "\1\u01c0\43\14\27\0\2\14\7\0\7\14\3\0\23\14" + + "\1\u01c1\22\14\27\0\2\14\7\0\7\14\3\0\14\14" + + "\1\u01c2\31\14\27\0\2\14\7\0\7\14\3\0\10\14" + + "\1\u01c3\35\14\27\0\2\14\7\0\7\14\3\0\41\14" + + "\1\u01c4\4\14\27\0\2\14\7\0\7\14\3\0\5\14" + + "\1\u01c5\40\14\27\0\2\14\7\0\7\14\3\0\16\14" + + "\1\u01c6\27\14\27\0\2\14\7\0\7\14\3\0\1\14" + + "\1\u01c7\44\14\27\0\2\14\7\0\7\14\3\0\1\14" + + "\1\u01c8\44\14\27\0\2\14\7\0\7\14\3\0\20\14" + + "\1\u01c9\25\14\27\0\2\14\7\0\7\14\3\0\12\14" + + "\1\u01ca\33\14\27\0\2\14\7\0\7\14\3\0\10\14" + + "\1\u01cb\35\14\27\0\2\14\7\0\7\14\3\0\1\14" + + "\1\u01cc\44\14\27\0\2\14\7\0\7\14\3\0\21\14" + + "\1\u01cd\24\14\27\0\2\14\7\0\7\14\3\0\3\14" + + "\1\u01ce\42\14\27\0\2\14\7\0\7\14\3\0\11\14" + + "\1\u01cf\34\14\27\0\2\14\7\0\7\14\3\0\2\14" + + "\1\u01d0\43\14\27\0\2\14\7\0\7\14\3\0\15\14" + + "\1\u01d1\30\14\27\0\2\14\7\0\7\14\3\0\10\14" + + "\1\u01d2\35\14\27\0\2\14\7\0\7\14\3\0\10\14" + + "\1\u01d3\4\14\1\u01d4\30\14\27\0\2\14\7\0\7\14" + + "\3\0\23\14\1\u01d5\22\14\27\0\2\14\7\0\7\14" + + "\3\0\11\14\1\u01d6\34\14\27\0\2\14\7\0\7\14" + + "\3\0\23\14\1\u01d7\22\14\27\0\2\14\7\0\7\14" + + "\3\0\12\14\1\u01d8\33\14\27\0\2\14\7\0\7\14" + + "\3\0\14\14\1\u01d9\31\14\27\0\2\14\7\0\7\14" + + "\3\0\16\14\1\u01da\27\14\27\0\2\14\7\0\7\14" + + "\3\0\2\14\1\u01db\43\14\27\0\2\14\7\0\7\14" + + "\3\0\5\14\1\u01dc\40\14\27\0\2\14\7\0\7\14" + + "\3\0\12\14\1\u01dd\33\14\27\0\2\14\7\0\7\14" + + "\3\0\16\14\1\u01de\27\14\27\0\2\14\7\0\7\14" + + "\3\0\12\14\1\u01df\33\14\27\0\2\14\7\0\7\14" + + "\3\0\20\14\1\u01e0\25\14\27\0\2\14\7\0\7\14" + + "\3\0\7\14\1\u01e1\36\14\27\0\2\14\7\0\7\14" + + "\3\0\3\14\1\u01e2\42\14\27\0\2\14\7\0\7\14" + + "\3\0\1\14\1\u01e3\44\14\27\0\2\14\7\0\7\14" + + "\3\0\5\14\1\u01e4\40\14\27\0\2\14\7\0\7\14" + + "\3\0\30\14\1\u01e5\13\14\1\u01e6\1\14\27\0\2\14" + + "\7\0\7\14\3\0\11\14\1\u01e7\34\14\27\0\2\14" + + "\7\0\7\14\3\0\26\14\1\u01e8\17\14\27\0\2\14" + + "\7\0\7\14\3\0\5\14\1\u01e9\40\14\27\0\2\14" + + "\7\0\7\14\3\0\6\14\1\u01ea\37\14\27\0\2\14" + + "\7\0\7\14\3\0\26\14\1\u01eb\17\14\27\0\2\14" + + "\7\0\7\14\3\0\16\14\1\u01ec\27\14\27\0\2\14" + + "\7\0\7\14\3\0\23\14\1\u01ed\22\14\27\0\2\14" + + "\7\0\7\14\3\0\1\14\1\u01ee\44\14\27\0\2\14" + + "\7\0\7\14\3\0\10\14\1\u01ef\35\14\27\0\2\14" + + "\7\0\7\14\3\0\26\14\1\u01f0\17\14\27\0\2\14" + + "\7\0\7\14\3\0\1\14\1\u01f1\44\14\27\0\2\14" + + "\7\0\7\14\3\0\12\14\1\u01f2\33\14\27\0\2\u01b5" + + "\3\0\1\u016b\3\0\7\u01b5\3\0\46\u01b5\27\0\1\u01b8" + + "\1\u01b6\3\0\1\112\1\u016d\1\u016e\1\0\2\u01b6\2\u01b8" + + "\2\u01b6\1\u01b8\3\0\46\u01b8\21\0\1\u01b7\2\0\13\u01b7" + + "\1\u01f3\101\u01b7\6\0\2\u01b8\1\u01b9\2\0\1\112\1\u016d" + + "\1\u016e\1\0\7\u01b8\3\0\46\u01b8\27\0\1\u01f4\12\0" + + "\2\u01f4\2\0\1\u01f4\3\0\46\u01f4\35\0\1\u01ba\1\u016e" + + "\102\0\1\u0172\2\0\10\u0172\1\u01f5\1\u01bb\1\u0172\1\u01bb" + + "\101\u0172\6\0\2\u01bc\4\0\1\u0175\1\u011d\1\0\7\u01bc" + + "\3\0\46\u01bc\40\0\2\u01f6\1\0\4\u01f6\3\0\1\u01f6" + + "\1\0\2\u01f6\1\0\1\u01f6\6\0\2\u01f6\12\0\1\u01f6" + + "\1\0\1\u01f6\5\0\2\u01f6\36\0\1\123\5\0\1\u01f7" + + "\1\133\2\0\2\u01f7\1\137\5\0\1\137\72\0\2\14" + + "\7\0\7\14\3\0\37\14\1\u01f8\6\14\27\0\2\14" + + "\7\0\7\14\3\0\6\14\1\u01f9\37\14\27\0\2\14" + + "\7\0\7\14\3\0\13\14\1\u01fa\32\14\27\0\2\14" + + "\7\0\7\14\3\0\1\14\1\u01fb\44\14\27\0\2\14" + + "\7\0\7\14\3\0\16\14\1\u01fc\27\14\27\0\2\14" + + "\7\0\7\14\3\0\3\14\1\u01fd\42\14\27\0\2\14" + + "\7\0\7\14\3\0\14\14\1\u01fe\31\14\27\0\2\14" + + "\7\0\7\14\3\0\2\14\1\u01ff\43\14\27\0\2\14" + + "\7\0\7\14\3\0\3\14\1\u0200\42\14\27\0\2\14" + + "\7\0\7\14\3\0\3\14\1\u0201\42\14\27\0\2\14" + + "\7\0\7\14\3\0\1\14\1\u0202\44\14\27\0\2\14" + + "\7\0\7\14\3\0\43\14\1\u0203\2\14\27\0\2\14" + + "\7\0\7\14\3\0\34\14\1\u0204\11\14\27\0\2\14" + + "\7\0\7\14\3\0\5\14\1\u0205\40\14\27\0\2\14" + + "\7\0\7\14\3\0\3\14\1\u0206\42\14\27\0\2\14" + + "\7\0\7\14\3\0\3\14\1\u0207\42\14\27\0\2\14" + + "\7\0\7\14\3\0\2\14\1\u0208\43\14\27\0\2\14" + + "\7\0\7\14\3\0\2\14\1\u0209\43\14\27\0\2\14" + + "\7\0\7\14\3\0\10\14\1\u020a\35\14\27\0\2\14" + + "\7\0\7\14\3\0\37\14\1\u020b\6\14\27\0\2\14" + + "\7\0\7\14\3\0\11\14\1\u020c\34\14\27\0\2\14" + + "\7\0\7\14\3\0\3\14\1\u020d\42\14\27\0\2\14" + + "\7\0\7\14\3\0\5\14\1\u020e\40\14\27\0\2\14" + + "\7\0\7\14\3\0\22\14\1\u020f\23\14\27\0\2\14" + + "\7\0\7\14\3\0\7\14\1\u0210\36\14\27\0\2\14" + + "\7\0\7\14\3\0\24\14\1\u0211\21\14\27\0\2\14" + + "\7\0\7\14\3\0\1\14\1\u0212\44\14\27\0\2\14" + + "\7\0\7\14\3\0\3\14\1\u0213\42\14\27\0\2\14" + + "\7\0\7\14\3\0\11\14\1\u0214\34\14\27\0\2\14" + + "\7\0\7\14\3\0\6\14\1\u0215\37\14\27\0\2\14" + + "\7\0\7\14\3\0\13\14\1\u0216\32\14\27\0\2\14" + + "\7\0\7\14\3\0\2\14\1\u0217\43\14\27\0\2\14" + + "\7\0\7\14\3\0\2\14\1\u0218\43\14\27\0\2\14" + + "\7\0\7\14\3\0\11\14\1\u0219\34\14\27\0\2\14" + + "\7\0\7\14\3\0\11\14\1\u021a\34\14\27\0\2\14" + + "\7\0\7\14\3\0\2\14\1\u021b\43\14\27\0\2\14" + + "\7\0\7\14\3\0\6\14\1\u021c\37\14\27\0\2\14" + + "\7\0\7\14\3\0\14\14\1\u021d\31\14\27\0\2\14" + + "\7\0\7\14\3\0\11\14\1\u021e\34\14\21\0\1\u01b7" + + "\2\0\10\u01b7\1\u021f\1\u01f3\1\u01b7\1\u01f3\101\u01b7\6\0" + + "\2\u01f4\4\0\1\u01ba\1\u016e\1\0\7\u01f4\3\0\46\u01f4" + + "\40\0\2\u0220\1\0\4\u0220\3\0\1\u0220\1\0\2\u0220" + + "\1\0\1\u0220\6\0\2\u0220\12\0\1\u0220\1\0\1\u0220" + + "\5\0\2\u0220\36\0\1\123\5\0\1\u0221\1\133\2\0" + + "\2\u0221\1\137\5\0\1\137\72\0\2\14\7\0\7\14" + + "\3\0\7\14\1\u0222\36\14\27\0\2\14\7\0\7\14" + + "\3\0\2\14\1\u0223\43\14\27\0\2\14\7\0\7\14" + + "\3\0\3\14\1\u0224\42\14\27\0\2\14\7\0\7\14" + + "\3\0\31\14\1\u0225\14\14\27\0\2\14\7\0\7\14" + + "\3\0\26\14\1\u0226\17\14\27\0\2\14\7\0\7\14" + + "\3\0\2\14\1\u0227\43\14\27\0\2\14\7\0\7\14" + + "\3\0\23\14\1\u0228\22\14\27\0\2\14\7\0\7\14" + + "\3\0\5\14\1\u0229\40\14\27\0\2\14\7\0\7\14" + + "\3\0\26\14\1\u022a\17\14\27\0\2\14\7\0\7\14" + + "\3\0\3\14\1\u022b\42\14\27\0\2\14\7\0\7\14" + + "\3\0\12\14\1\u022c\33\14\27\0\2\14\7\0\7\14" + + "\3\0\2\14\1\u022d\43\14\27\0\2\14\7\0\7\14" + + "\3\0\16\14\1\u022e\27\14\27\0\2\14\7\0\7\14" + + "\3\0\5\14\1\u022f\40\14\27\0\2\14\7\0\7\14" + + "\3\0\36\14\1\u0230\7\14\27\0\2\14\7\0\7\14" + + "\3\0\10\14\1\u0231\35\14\27\0\2\14\7\0\7\14" + + "\3\0\2\14\1\u0232\43\14\27\0\2\14\7\0\7\14" + + "\3\0\7\14\1\u0233\36\14\27\0\2\14\7\0\7\14" + + "\3\0\11\14\1\u0234\34\14\27\0\2\14\7\0\7\14" + + "\3\0\10\14\1\u0235\35\14\27\0\2\14\7\0\7\14" + + "\3\0\12\14\1\u0236\33\14\27\0\2\14\7\0\7\14" + + "\3\0\12\14\1\u0237\33\14\27\0\2\14\7\0\7\14" + + "\3\0\23\14\1\u0238\22\14\27\0\2\14\7\0\7\14" + + "\3\0\2\14\1\u0239\43\14\27\0\2\14\7\0\3\14" + + "\1\u023a\3\14\3\0\46\14\27\0\2\14\7\0\7\14" + + "\3\0\23\14\1\u023b\22\14\27\0\2\14\7\0\7\14" + + "\3\0\1\14\1\u023c\44\14\27\0\2\14\7\0\7\14" + + "\3\0\20\14\1\u023d\25\14\27\0\2\14\7\0\7\14" + + "\3\0\1\14\1\u023e\44\14\27\0\2\14\7\0\7\14" + + "\3\0\12\14\1\u023f\33\14\27\0\2\14\7\0\7\14" + + "\3\0\31\14\1\u0240\11\14\1\u0241\2\14\27\0\2\14" + + "\7\0\7\14\3\0\22\14\1\u0242\23\14\40\0\2\u0243" + + "\1\0\4\u0243\3\0\1\u0243\1\0\2\u0243\1\0\1\u0243" + + "\6\0\2\u0243\12\0\1\u0243\1\0\1\u0243\5\0\2\u0243" + + "\36\0\1\123\5\0\1\u0244\1\133\2\0\2\u0244\1\137" + + "\5\0\1\137\72\0\2\14\7\0\7\14\3\0\24\14" + + "\1\u0245\21\14\27\0\2\14\7\0\7\14\3\0\26\14" + + "\1\u0246\17\14\27\0\2\14\7\0\7\14\3\0\7\14" + + "\1\u0247\36\14\27\0\2\14\7\0\7\14\3\0\2\14" + + "\1\u0248\43\14\27\0\2\14\7\0\7\14\3\0\2\14" + + "\1\u0249\43\14\27\0\2\14\7\0\7\14\3\0\2\14" + + "\1\u024a\43\14\27\0\2\14\7\0\7\14\3\0\11\14" + + "\1\u024b\34\14\27\0\2\14\7\0\7\14\3\0\26\14" + + "\1\u024c\17\14\27\0\2\14\7\0\7\14\3\0\7\14" + + "\1\u024d\36\14\27\0\2\14\7\0\7\14\3\0\2\14" + + "\1\u024e\43\14\27\0\2\14\7\0\7\14\3\0\7\14" + + "\1\u024f\36\14\27\0\2\14\7\0\7\14\3\0\11\14" + + "\1\u0250\34\14\27\0\2\14\7\0\7\14\3\0\14\14" + + "\1\u0251\31\14\27\0\2\14\7\0\7\14\3\0\24\14" + + "\1\u0252\21\14\27\0\2\14\7\0\7\14\3\0\2\14" + + "\1\u0253\43\14\27\0\2\14\7\0\7\14\3\0\2\14" + + "\1\u0254\43\14\27\0\2\14\7\0\7\14\3\0\3\14" + + "\1\u0255\42\14\27\0\2\14\7\0\7\14\3\0\2\14" + + "\1\u0256\43\14\27\0\2\14\7\0\7\14\3\0\14\14" + + "\1\u0257\31\14\27\0\2\14\7\0\7\14\3\0\12\14" + + "\1\u0258\33\14\27\0\2\14\7\0\7\14\3\0\12\14" + + "\1\u0259\33\14\27\0\2\14\7\0\7\14\3\0\7\14" + + "\1\u025a\36\14\27\0\2\14\7\0\7\14\3\0\11\14" + + "\1\u025b\34\14\27\0\2\14\7\0\7\14\3\0\16\14" + + "\1\u025c\27\14\40\0\2\u025d\1\0\4\u025d\3\0\1\u025d" + + "\1\0\2\u025d\1\0\1\u025d\6\0\2\u025d\12\0\1\u025d" + + "\1\0\1\u025d\5\0\2\u025d\36\0\1\123\5\0\1\u025e" + + "\1\133\2\0\2\u025e\1\137\5\0\1\137\72\0\2\14" + + "\7\0\7\14\3\0\12\14\1\u025f\33\14\27\0\2\14" + + "\7\0\7\14\3\0\13\14\1\u0260\32\14\27\0\2\14" + + "\7\0\7\14\3\0\11\14\1\u0261\34\14\27\0\2\14" + + "\7\0\7\14\3\0\20\14\1\u0262\25\14\27\0\2\14" + + "\7\0\7\14\3\0\20\14\1\u0263\25\14\27\0\2\14" + + "\7\0\7\14\3\0\15\14\1\u0264\30\14\27\0\2\14" + + "\7\0\7\14\3\0\3\14\1\u0265\42\14\27\0\2\14" + + "\7\0\7\14\3\0\6\14\1\u0266\37\14\27\0\2\14" + + "\7\0\7\14\3\0\12\14\1\u0267\33\14\27\0\2\14" + + "\7\0\7\14\3\0\37\14\1\u0268\6\14\27\0\2\14" + + "\7\0\7\14\3\0\44\14\1\u0269\1\14\27\0\2\14" + + "\7\0\7\14\3\0\1\u026a\45\14\27\0\2\14\7\0" + + "\7\14\3\0\11\14\1\u026b\34\14\27\0\2\14\7\0" + + "\7\14\3\0\10\14\1\u026c\35\14\27\0\2\14\7\0" + + "\7\14\3\0\10\14\1\u026d\35\14\27\0\2\14\7\0" + + "\7\14\3\0\7\14\1\u026e\36\14\27\0\2\14\7\0" + + "\7\14\3\0\3\14\1\u026f\42\14\32\0\1\123\5\0" + + "\1\u0270\1\133\2\0\2\u0270\1\137\5\0\1\137\72\0" + + "\2\14\7\0\7\14\3\0\2\14\1\u0271\43\14\27\0" + + "\2\14\7\0\7\14\3\0\10\14\1\u0272\35\14\27\0" + + "\2\14\7\0\7\14\3\0\35\14\1\u0273\10\14\27\0" + + "\2\14\7\0\7\14\3\0\14\14\1\u0274\31\14\27\0" + + "\2\14\7\0\7\14\3\0\2\14\1\u0275\43\14\27\0" + + "\2\14\7\0\7\14\3\0\7\14\1\u0276\36\14\27\0" + + "\2\14\7\0\7\14\3\0\13\14\1\u0277\32\14\27\0" + + "\2\14\7\0\7\14\3\0\16\14\1\u0278\27\14\27\0" + + "\2\14\7\0\7\14\3\0\23\14\1\u0279\22\14\27\0" + + "\2\14\7\0\7\14\3\0\26\14\1\u027a\17\14\27\0" + + "\2\14\7\0\7\14\3\0\21\14\1\u027b\24\14\27\0" + + "\2\14\7\0\7\14\3\0\22\14\1\u027c\23\14\32\0" + + "\1\123\5\0\1\u027d\1\133\2\0\2\u027d\1\137\5\0" + + "\1\137\72\0\2\14\7\0\7\14\3\0\40\14\1\u027e" + + "\5\14\27\0\2\14\7\0\7\14\3\0\14\14\1\u027f" + + "\31\14\27\0\2\14\7\0\7\14\3\0\13\14\1\u0280" + + "\32\14\27\0\2\14\7\0\7\14\3\0\2\14\1\u0281" + + "\43\14\27\0\2\14\7\0\7\14\3\0\44\14\1\u0282" + + "\1\14\27\0\2\14\7\0\7\14\3\0\24\14\1\u0283" + + "\21\14\27\0\2\14\7\0\7\14\3\0\23\14\1\u0284" + + "\22\14\27\0\2\14\7\0\7\14\3\0\2\14\1\u0285" + + "\43\14\27\0\2\14\7\0\7\14\3\0\3\14\1\u0286" + + "\42\14\32\0\1\123\5\0\1\u0287\1\133\2\0\2\u0287" + "\1\137\5\0\1\137\72\0\2\14\7\0\7\14\3\0" - + "\12\14\1\u026d\33\14\27\0\2\14\7\0\7\14\3\0" - + "\16\14\1\u026e\27\14\27\0\2\14\7\0\7\14\3\0" - + "\2\14\1\u026f\43\14\32\0\1\123\5\0\1\u0270\1\133" - + "\2\0\2\u0270\1\137\5\0\1\137\72\0\2\14\7\0" - + "\7\14\3\0\21\14\1\u0271\24\14\27\0\2\14\7\0" - + "\7\14\3\0\12\14\1\u0272\33\14\27\0\2\14\7\0" - + "\7\14\3\0\40\14\1\u0273\5\14\32\0\1\123\5\0" - + "\1\u0274\1\133\2\0\2\u0274\1\137\5\0\1\137\72\0" - + "\2\14\7\0\7\14\3\0\11\14\1\u0275\34\14\27\0" - + "\2\14\7\0\7\14\3\0\16\14\1\u0276\27\14\27\0" - + "\2\14\7\0\7\14\3\0\22\14\1\u0277\23\14\27\0" - + "\2\14\7\0\7\14\3\0\12\14\1\u0278\33\14\27\0" - + "\2\14\7\0\7\14\3\0\21\14\1\u0279\24\14\21\0"; + + "\16\14\1\u0288\27\14\27\0\2\14\7\0\7\14\3\0" + + "\6\14\1\u0289\37\14\27\0\2\14\7\0\7\14\3\0" + + "\3\14\1\u028a\42\14\27\0\2\14\7\0\7\14\3\0" + + "\14\14\1\u028b\31\14\27\0\2\14\7\0\7\14\3\0" + + "\13\14\1\u028c\32\14\27\0\2\14\7\0\7\14\3\0" + + "\12\14\1\u028d\33\14\27\0\2\14\7\0\7\14\3\0" + + "\6\14\1\u028e\37\14\27\0\2\14\7\0\7\14\3\0" + + "\21\14\1\u028f\24\14\32\0\1\123\5\0\1\u0290\1\133" + + "\2\0\2\u0290\1\137\5\0\1\137\72\0\2\14\7\0" + + "\7\14\3\0\12\14\1\u0291\33\14\27\0\2\14\7\0" + + "\7\14\3\0\16\14\1\u0292\27\14\27\0\2\14\7\0" + + "\7\14\3\0\23\14\1\u0293\22\14\27\0\2\14\7\0" + + "\7\14\3\0\2\14\1\u0294\43\14\27\0\2\14\7\0" + + "\7\14\3\0\44\14\1\u0295\1\14\27\0\2\14\7\0" + + "\7\14\3\0\44\14\1\u0296\1\14\32\0\1\123\5\0" + + "\1\u0297\1\133\2\0\2\u0297\1\137\5\0\1\137\72\0" + + "\2\14\7\0\7\14\3\0\21\14\1\u0298\24\14\27\0" + + "\2\14\7\0\7\14\3\0\12\14\1\u0299\33\14\27\0" + + "\2\14\7\0\7\14\3\0\40\14\1\u029a\5\14\27\0" + + "\2\14\7\0\7\14\3\0\13\14\1\u029b\32\14\27\0" + + "\2\14\7\0\7\14\3\0\13\14\1\u029c\32\14\32\0" + + "\1\123\5\0\1\u029d\1\133\2\0\2\u029d\1\137\5\0" + + "\1\137\72\0\2\14\7\0\7\14\3\0\11\14\1\u029e" + + "\34\14\27\0\2\14\7\0\7\14\3\0\16\14\1\u029f" + + "\27\14\27\0\2\14\7\0\7\14\3\0\23\14\1\u02a0" + + "\22\14\27\0\2\14\7\0\7\14\3\0\23\14\1\u02a1" + + "\22\14\27\0\2\14\7\0\7\14\3\0\22\14\1\u02a2" + + "\23\14\27\0\2\14\7\0\7\14\3\0\12\14\1\u02a3" + + "\33\14\27\0\2\14\7\0\7\14\3\0\21\14\1\u02a4" + + "\24\14\21\0"; private static int[] zzUnpackTrans() { - int[] result = new int[39280]; + int[] result = new int[42320]; int offset = 0; offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result); return result; @@ -905,12 +954,12 @@ public final class ActionScriptLexer { + "\3\11\2\0\1\1\1\0\1\1\1\11\1\1\1\11" + "\3\1\1\0\2\1\1\0\2\11\73\1\12\11\2\1" + "\7\11\6\0\1\1\1\11\2\0\1\11\3\0\1\11" - + "\1\0\1\11\1\1\2\11\4\1\1\0\106\1\2\11" - + "\7\0\1\11\5\0\1\11\105\1\1\0\1\11\12\0" - + "\74\1\10\0\62\1\2\0\135\1\1\11\64\1"; + + "\1\0\1\11\1\1\2\11\4\1\1\0\110\1\2\11" + + "\7\0\1\11\5\0\1\11\111\1\1\0\1\11\12\0" + + "\77\1\10\0\66\1\2\0\150\1\1\11\107\1"; private static int[] zzUnpackAttribute() { - int[] result = new int[633]; + int[] result = new int[676]; int offset = 0; offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result); return result; @@ -1001,18 +1050,44 @@ public final class ActionScriptLexer { public int yyline() { return yyline + 1; } + private List listeners = new ArrayList<>(); + + public void addListener(LexListener listener) { + listeners.add(listener); + } + + public void removeListener(LexListener listener) { + listeners.remove(listener); + } + + public void informListenersLex(ParsedSymbol s) { + for (LexListener l : listeners) { + l.onLex(s); + } + } + + public void informListenersPushBack(ParsedSymbol s) { + for (LexListener l : listeners) { + l.onPushBack(s); + } + } public void pushback(ParsedSymbol symb) { pushedBack.push(symb); last = null; + informListenersPushBack(symb); } ParsedSymbol last; public ParsedSymbol lex() throws java.io.IOException, ParseException { + ParsedSymbol ret = null; if (!pushedBack.isEmpty()) { - return last = pushedBack.pop(); + ret = last = pushedBack.pop(); + } else { + ret = last = yylex(); } - return last = yylex(); + informListenersLex(ret); + return ret; } /** @@ -1310,27 +1385,27 @@ public final class ActionScriptLexer { case 4: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.DIVIDE, yytext()); } - case 167: + case 177: break; - case 129: { + case 131: { return new ParsedSymbol(SymbolGroup.GLOBALFUNC, SymbolType.STRING_OP, yytext()); } - case 168: + case 178: break; - case 142: { + case 144: { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.FUNCTION, yytext()); } - case 169: + case 179: break; case 30: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.XOR, yytext()); } - case 170: + case 180: break; - case 138: { + case 140: { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.CONTINUE, yytext()); } - case 171: + case 181: break; case 75: { string.setLength(0); @@ -1343,294 +1418,304 @@ public final class ActionScriptLexer { xmlTagName = s; string.append(yytext()); } - case 172: + case 182: break; case 59: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.OR, yytext()); } - case 173: + case 183: break; - case 135: { + case 137: { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.FINALLY, yytext()); } - case 174: + case 184: break; case 94: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_USHIFT_RIGHT, yytext()); } - case 175: + case 185: break; case 33: { string.append(yytext()); } - case 176: + case 186: break; case 61: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.INCREMENT, yytext()); } - case 177: + case 187: break; case 74: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.REST, yytext()); } - case 178: + case 188: break; case 16: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.PARENT_OPEN, yytext()); } - case 179: + case 189: break; - case 158: { + case 163: { return new ParsedSymbol(SymbolGroup.GLOBALFUNC, SymbolType.MBSUBSTRING, yytext()); } - case 180: + case 190: break; - case 123: { + case 125: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.TYPEOF, yytext()); } - case 181: + case 191: break; case 17: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.PARENT_CLOSE, yytext()); } - case 182: + case 192: break; case 95: { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.EACH, yytext()); } - case 183: + case 193: break; case 10: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.GREATER_THAN, yytext()); } - case 184: + case 194: break; case 9: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.LOWER_THAN, yytext()); } - case 185: + case 195: break; - case 160: { + case 165: { return new ParsedSymbol(SymbolGroup.GLOBALFUNC, SymbolType.GOTOANDPLAY, yytext()); } - case 186: + case 196: break; case 56: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_BITAND, yytext()); } - case 187: + case 197: break; case 98: { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.CASE, yytext()); } - case 188: + case 198: break; - case 125: { + case 127: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.DELETE, yytext()); } - case 189: + case 199: break; case 38: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_DIVIDE, yytext()); } - case 190: + case 200: break; case 12: { string.setLength(0); yybegin(STRING); } - case 191: + case 201: break; - case 127: { - return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.PUBLIC, yytext()); - } - case 192: - break; - case 143: { + case 146: { return new ParsedSymbol(SymbolGroup.GLOBALFUNC, SymbolType.MBLENGTH, yytext()); } - case 193: + case 202: + break; + case 129: { + return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.PUBLIC, yytext()); + } + case 203: break; case 34: { yybegin(YYINITIAL); yyline++; } - case 194: + case 204: + break; + case 166: { + return new ParsedSymbol(SymbolGroup.GLOBALFUNC, SymbolType.LOADMOVIENUM, yytext()); + } + case 205: break; case 77: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.USHIFT_RIGHT, yytext()); } - case 195: + case 206: break; - case 155: { + case 158: { return new ParsedSymbol(SymbolGroup.GLOBALFUNC, SymbolType.TARGETPATH, yytext()); } - case 196: + case 207: break; case 81: { return new ParsedSymbol(SymbolGroup.GLOBALFUNC, SymbolType.CHR, yytext()); } - case 197: + case 208: break; - case 154: { + case 157: { return new ParsedSymbol(SymbolGroup.GLOBALFUNC, SymbolType.TELLTARGET, yytext()); } - case 198: + case 209: break; case 50: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.AS, yytext()); } - case 199: + case 210: break; - case 119: { + case 121: { return new ParsedSymbol(SymbolGroup.GLOBALFUNC, SymbolType.RANDOM, yytext()); } - case 200: + case 211: break; - case 165: { + case 175: { return new ParsedSymbol(SymbolGroup.GLOBALFUNC, SymbolType.TOGGLEHIGHQUALITY, yytext()); } - case 201: + case 212: break; case 8: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.DOT, yytext()); } - case 202: + case 213: break; - case 126: { + case 128: { return new ParsedSymbol(SymbolGroup.GLOBALFUNC, SymbolType.LENGTH, yytext()); } - case 203: + case 214: break; case 5: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.MULTIPLY, yytext()); } - case 204: + case 215: break; - case 136: { + case 138: { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.PRIVATE, yytext()); } - case 205: + case 216: break; - case 159: { + case 164: { return new ParsedSymbol(SymbolGroup.GLOBALFUNC, SymbolType.GOTOANDSTOP, yytext()); } - case 206: + case 217: break; case 49: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.DECREMENT, yytext()); } - case 207: + case 218: break; - case 133: { + case 135: { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.DEFAULT, yytext()); } - case 208: + case 219: break; - case 149: { + case 152: { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.INTERFACE, yytext()); } - case 209: + case 220: break; case 93: { String t = yytext(); return new ParsedSymbol(SymbolGroup.TYPENAME, SymbolType.TYPENAME, t.substring(2, t.length() - 1)); } - case 210: + case 221: break; case 57: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.AND, yytext()); } - case 211: + case 222: break; case 97: { return new ParsedSymbol(SymbolGroup.GLOBALFUNC, SymbolType.EVAL, yytext()); } - case 212: + case 223: break; case 88: { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.FOR, yytext()); } - case 213: + case 224: break; - case 113: { + case 170: { + return new ParsedSymbol(SymbolGroup.GLOBALFUNC, SymbolType.PRINTASBITMAP, yytext()); + } + case 225: + break; + case 114: { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.THROW, yytext()); } - case 214: + case 226: break; case 64: { throw new ParseException("Illegal escape sequence \"" + yytext() + "\"", yyline + 1); } - case 215: + case 227: break; - case 107: { + case 108: { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.BREAK, yytext()); } - case 216: + case 228: break; - case 105: { + case 106: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.VOID, yytext()); } - case 217: + case 229: break; case 25: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.NEGATE, yytext()); } - case 218: + case 230: break; case 44: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.SHIFT_RIGHT, yytext()); } - case 219: + case 231: break; - case 102: { + case 103: { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.THIS, yytext()); } - case 220: + case 232: break; case 76: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_SHIFT_LEFT, yytext()); } - case 221: + case 233: break; - case 124: { + case 126: { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.IMPORT, yytext()); } - case 222: + case 234: break; case 92: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.STRICT_NOT_EQUAL, yytext()); } - case 223: + case 235: break; case 18: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.CURLY_OPEN, yytext()); } - case 224: + case 236: break; - case 141: { + case 143: { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.INTERNAL, yytext()); } - case 225: + case 237: break; case 35: { yybegin(YYINITIAL); // length also includes the trailing quote return new ParsedSymbol(SymbolGroup.STRING, SymbolType.STRING, string.toString()); } - case 226: + case 238: break; - case 111: { + case 112: { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.SUPER, yytext()); } - case 227: + case 239: break; case 86: { return new ParsedSymbol(SymbolGroup.GLOBALFUNC, SymbolType.INT, yytext()); } - case 228: + case 240: break; - case 106: { + case 107: { string.append(yytext()); String endtagname = yytext(); endtagname = endtagname.substring(2, endtagname.length() - 1); @@ -1639,525 +1724,565 @@ public final class ActionScriptLexer { return new ParsedSymbol(SymbolGroup.XML, SymbolType.XML, string.toString()); } } - case 229: + case 241: break; case 45: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.GREATER_EQUAL, yytext()); } - case 230: + case 242: break; - case 132: { + case 134: { return new ParsedSymbol(SymbolGroup.GLOBALCONST, SymbolType.NEWLINE, yytext()); } - case 231: + case 243: break; case 70: { string.append('\r'); } - case 232: + case 244: break; - case 139: { + case 141: { return new ParsedSymbol(SymbolGroup.GLOBALFUNC, SymbolType.STOPDRAG, yytext()); } - case 233: + case 245: break; case 3: { /*ignore*/ } - case 234: + case 246: break; case 28: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.BITOR, yytext()); } - case 235: + case 247: break; - case 156: { + case 159: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.INSTANCEOF, yytext()); } - case 236: + case 248: break; case 31: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.MODULO, yytext()); } - case 237: + case 249: break; - case 114: { + case 115: { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.FALSE, yytext()); } - case 238: + case 250: break; - case 140: { + case 142: { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.OVERRIDE, yytext()); } - case 239: + case 251: break; case 90: { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.GET, yytext()); } - case 240: + case 252: break; - case 153: { + case 156: { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.PROTECTED, yytext()); } - case 241: + case 253: break; - case 162: { + case 168: { return new ParsedSymbol(SymbolGroup.GLOBALFUNC, SymbolType.IFFRAMELOADED, yytext()); } - case 242: + case 254: break; case 58: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_BITOR, yytext()); } - case 243: + case 255: break; case 37: { yybegin(XML); string.append(yytext()); } - case 244: + case 256: break; case 96: { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.ELSE, yytext()); } - case 245: + case 257: break; case 36: { string.append(yytext()); yyline++; } - case 246: + case 258: break; case 71: { string.append('\n'); } - case 247: + case 259: break; - case 117: { + case 119: { return new ParsedSymbol(SymbolGroup.GLOBALFUNC, SymbolType.MBORD, yytext()); } - case 248: + case 260: break; - case 137: { + case 139: { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.PACKAGE, yytext()); } - case 249: + case 261: break; - case 157: { + case 160: { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.IMPLEMENTS, yytext()); } - case 250: + case 262: break; - case 164: { + case 172: { return new ParsedSymbol(SymbolGroup.GLOBALFUNC, SymbolType.REMOVEMOVIECLIP, yytext()); } - case 251: + case 263: break; case 26: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.TERNAR, yytext()); } - case 252: + case 264: + break; + case 162: { + return new ParsedSymbol(SymbolGroup.GLOBALFUNC, SymbolType.UNLOADMOVIE, yytext()); + } + case 265: break; case 68: { string.append('\''); } - case 253: + case 266: break; case 24: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.NOT, yytext()); } - case 254: + case 267: break; case 79: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.STRICT_EQUALS, yytext()); } - case 255: + case 268: break; - case 151: { + case 154: { return new ParsedSymbol(SymbolGroup.GLOBALFUNC, SymbolType.LOADMOVIE, yytext()); } - case 256: + case 269: break; - case 120: { + case 122: { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.STATIC, yytext()); } - case 257: + case 270: break; case 39: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_MULTIPLY, yytext()); } - case 258: + case 271: break; case 6: { return new ParsedSymbol(SymbolGroup.IDENTIFIER, SymbolType.IDENTIFIER, yytext()); } - case 259: + case 272: + break; + case 145: { + return new ParsedSymbol(SymbolGroup.GLOBALFUNC, SymbolType.PRINTNUM, yytext()); + } + case 273: break; case 23: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.COMMA, yytext()); } - case 260: + case 274: break; case 43: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.LOWER_EQUAL, yytext()); } - case 261: + case 275: break; case 63: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_MODULO, yytext()); } - case 262: + case 276: break; case 78: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_SHIFT_RIGHT, yytext()); } - case 263: + case 277: break; case 67: { string.append('\\'); } - case 264: + case 278: break; case 66: { char val = (char) Integer.parseInt(yytext().substring(1), 8); string.append(val); } - case 265: + case 279: break; case 54: { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.DO, yytext()); } - case 266: + case 280: break; case 47: { return new ParsedSymbol(SymbolGroup.INTEGER, SymbolType.INTEGER, new Long(Long.parseLong(yytext(), 8))); } - case 267: + case 281: break; - case 100: { + case 101: { return new ParsedSymbol(SymbolGroup.GLOBALCONST, SymbolType.NULL, yytext()); } - case 268: + case 282: + break; + case 171: { + return new ParsedSymbol(SymbolGroup.GLOBALFUNC, SymbolType.UNLOADMOVIENUM, yytext()); + } + case 283: break; case 53: { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.IF, yytext()); } - case 269: + case 284: break; - case 115: { + case 116: { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.WHILE, yytext()); } - case 270: + case 285: break; case 19: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.CURLY_CLOSE, yytext()); } - case 271: + case 286: break; - case 147: { + case 150: { return new ParsedSymbol(SymbolGroup.GLOBALFUNC, SymbolType.NEXTFRAME, yytext()); } - case 272: + case 287: break; case 80: { return new ParsedSymbol(SymbolGroup.INTEGER, SymbolType.INTEGER, new Long(Long.parseLong(yytext().substring(2), 16))); } - case 273: + case 288: break; case 82: { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.SET, yytext()); } - case 274: + case 289: break; case 22: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.SEMICOLON, yytext()); } - case 275: + case 290: break; - case 146: { + case 149: { return new ParsedSymbol(SymbolGroup.GLOBALFUNC, SymbolType.STARTDRAG, yytext()); } - case 276: + case 291: break; case 40: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.NAMESPACE_OP, yytext()); } - case 277: + case 292: break; case 62: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_XOR, yytext()); } - case 278: + case 293: break; case 29: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.PLUS, yytext()); } - case 279: + case 294: break; case 84: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.NEW, yytext()); } - case 280: + case 295: break; case 60: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_PLUS, yytext()); } - case 281: + case 296: break; - case 110: { + case 111: { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.CLASS, yytext()); } - case 282: + case 297: break; case 51: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.IS, yytext()); } - case 283: + case 298: break; - case 109: { + case 110: { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.CONST, yytext()); } - case 284: + case 299: break; - case 150: { + case 153: { return new ParsedSymbol(SymbolGroup.GLOBALCONST, SymbolType.UNDEFINED, yytext()); } - case 285: + case 300: break; - case 148: { + case 151: { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.NAMESPACE, yytext()); } - case 286: + case 301: break; - case 122: { + case 117: { + return new ParsedSymbol(SymbolGroup.GLOBALFUNC, SymbolType.PRINT, yytext()); + } + case 302: + break; + case 124: { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.SWITCH, yytext()); } - case 287: + case 303: break; case 13: { return new ParsedSymbol(SymbolGroup.INTEGER, SymbolType.INTEGER, new Long(Long.parseLong((yytext())))); } - case 288: + case 304: break; - case 112: { + case 113: { return new ParsedSymbol(SymbolGroup.GLOBALFUNC, SymbolType.TRACE, yytext()); } - case 289: + case 305: break; - case 103: { + case 104: { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.WITH, yytext()); } - case 290: + case 306: break; - case 145: { + case 148: { return new ParsedSymbol(SymbolGroup.GLOBALCONST, SymbolType.INFINITY, yytext()); } - case 291: + case 307: break; - case 101: { + case 102: { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.TRUE, yytext()); } - case 292: + case 308: break; case 32: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ATTRIBUTE, yytext()); } - case 293: + case 309: break; case 20: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.BRACKET_OPEN, yytext()); } - case 294: + case 310: break; - case 163: { + case 169: { return new ParsedSymbol(SymbolGroup.GLOBALFUNC, SymbolType.LOADVARIABLES, yytext()); } - case 295: + case 311: break; - case 144: { + case 174: { + return new ParsedSymbol(SymbolGroup.GLOBALFUNC, SymbolType.PRINTASBITMAPNUM, yytext()); + } + case 312: + break; + case 147: { return new ParsedSymbol(SymbolGroup.GLOBALFUNC, SymbolType.GETTIMER, yytext()); } - case 296: + case 313: break; case 52: { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.IN, yytext()); } - case 297: + case 314: break; case 55: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.NOT_EQUAL, yytext()); } - case 298: + case 315: break; case 2: { yyline++; } - case 299: + case 316: break; case 14: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.MINUS, yytext()); } - case 300: + case 317: + break; + case 161: { + return new ParsedSymbol(SymbolGroup.GLOBALFUNC, SymbolType.GETVERSION, yytext()); + } + case 318: break; case 73: { string.append('\f'); } - case 301: + case 319: break; case 87: { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.USE, yytext()); } - case 302: + case 320: break; - case 134: { + case 136: { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.DYNAMIC, yytext()); } - case 303: + case 321: break; - case 166: { + case 176: { return new ParsedSymbol(SymbolGroup.GLOBALFUNC, SymbolType.DUPLICATEMOVIECLIP, yytext()); } - case 304: + case 322: break; - case 104: { + case 105: { return new ParsedSymbol(SymbolGroup.GLOBALFUNC, SymbolType.PLAY, yytext()); } - case 305: + case 323: break; case 83: { return new ParsedSymbol(SymbolGroup.GLOBALFUNC, SymbolType.ORD, yytext()); } - case 306: + case 324: break; case 72: { string.append('\t'); } - case 307: + case 325: break; case 48: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_MINUS, yytext()); } - case 308: + case 326: break; - case 118: { + case 120: { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.RETURN, yytext()); } - case 309: + case 327: break; - case 128: { + case 130: { return new ParsedSymbol(SymbolGroup.GLOBALFUNC, SymbolType.GETURL, yytext()); } - case 310: + case 328: break; - case 131: { + case 133: { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.EXTENDS, yytext()); } - case 311: + case 329: break; - case 116: { + case 118: { return new ParsedSymbol(SymbolGroup.GLOBALFUNC, SymbolType.MBCHR, yytext()); } - case 312: + case 330: break; case 15: { string.setLength(0); yybegin(CHARLITERAL); } - case 313: + case 331: break; case 42: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.SHIFT_LEFT, yytext()); } - case 314: + case 332: break; case 7: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.COLON, yytext()); } - case 315: + case 333: + break; + case 99: { + return new ParsedSymbol(SymbolGroup.GLOBALFUNC, SymbolType.CALL, yytext()); + } + case 334: break; case 89: { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.VAR, yytext()); } - case 316: + case 335: + break; + case 173: { + return new ParsedSymbol(SymbolGroup.GLOBALFUNC, SymbolType.LOADVARIABLESNUM, yytext()); + } + case 336: break; case 69: { string.append('\b'); } - case 317: + case 337: break; - case 99: { + case 100: { return new ParsedSymbol(SymbolGroup.GLOBALFUNC, SymbolType.STOP, yytext()); } - case 318: + case 338: break; - case 152: { + case 155: { return new ParsedSymbol(SymbolGroup.GLOBALFUNC, SymbolType.PREVFRAME, yytext()); } - case 319: + case 339: break; case 11: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN, yytext()); } - case 320: + case 340: break; case 46: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.EQUALS, yytext()); } - case 321: + case 341: break; case 85: { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.TRY, yytext()); } - case 322: + case 342: break; case 65: { string.append('\"'); } - case 323: + case 343: break; - case 108: { + case 109: { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.CATCH, yytext()); } - case 324: + case 344: break; - case 161: { + case 167: { return new ParsedSymbol(SymbolGroup.GLOBALFUNC, SymbolType.STOPALLSOUNDS, yytext()); } - case 325: + case 345: break; case 41: { return new ParsedSymbol(SymbolGroup.DOUBLE, SymbolType.DOUBLE, new Double(Double.parseDouble((yytext())))); } - case 326: + case 346: break; case 91: { return new ParsedSymbol(SymbolGroup.GLOBALCONST, SymbolType.NAN, yytext()); } - case 327: + case 347: break; - case 130: { + case 132: { return new ParsedSymbol(SymbolGroup.GLOBALFUNC, SymbolType.NUMBER_OP, yytext()); } - case 328: + case 348: break; case 21: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.BRACKET_CLOSE, yytext()); } - case 329: + case 349: break; - case 121: { + case 123: { return new ParsedSymbol(SymbolGroup.GLOBALFUNC, SymbolType.SUBSTR, yytext()); } - case 330: + case 350: break; case 27: { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.BITAND, yytext()); } - case 331: + case 351: break; case 1: { } - case 332: + case 352: break; default: if (zzInput == YYEOF && zzStartRead == zzCurrentPos) { diff --git a/trunk/src/com/jpexs/decompiler/flash/action/parser/script/ActionScriptParser.java b/trunk/src/com/jpexs/decompiler/flash/action/parser/script/ActionScriptParser.java index 407db83b1..9e378d240 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/parser/script/ActionScriptParser.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/parser/script/ActionScriptParser.java @@ -16,31 +16,117 @@ */ package com.jpexs.decompiler.flash.action.parser.script; -import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.action.Action; import com.jpexs.decompiler.flash.action.parser.ParseException; -import static com.jpexs.decompiler.flash.action.parser.script.SymbolType.DELETE; -import com.jpexs.decompiler.flash.action.swf3.ActionNextFrame; -import com.jpexs.decompiler.flash.action.swf3.ActionPlay; -import com.jpexs.decompiler.flash.action.swf3.ActionPrevFrame; -import com.jpexs.decompiler.flash.action.swf3.ActionStop; -import com.jpexs.decompiler.flash.action.swf3.ActionStopSounds; -import com.jpexs.decompiler.flash.action.swf3.ActionToggleQuality; import com.jpexs.decompiler.flash.action.swf4.*; import com.jpexs.decompiler.flash.action.swf5.*; -import com.jpexs.decompiler.flash.action.swf6.ActionEnumerate2; -import com.jpexs.decompiler.flash.action.swf6.ActionGreater; -import com.jpexs.decompiler.flash.action.swf6.ActionInstanceOf; -import com.jpexs.decompiler.flash.action.swf6.ActionStrictEquals; -import com.jpexs.decompiler.flash.action.swf7.ActionDefineFunction2; -import com.jpexs.decompiler.flash.action.swf7.ActionExtends; -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.AsciiToCharTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.CallFunctionTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.CallMethodTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.CallTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.CharToAsciiTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.CloneSpriteTreeItem; import com.jpexs.decompiler.flash.action.treemodel.ConstantPool; +import com.jpexs.decompiler.flash.action.treemodel.DefineLocalTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.DefineRegisterTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.DeleteTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.DirectValueTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.EvalTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.FunctionTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.GetMemberTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.GetTimeTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.GetURL2TreeItem; +import com.jpexs.decompiler.flash.action.treemodel.GetVariableTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.GetVersionTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.GotoFrame2TreeItem; +import com.jpexs.decompiler.flash.action.treemodel.InitArrayTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.InitObjectTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.LoadMovieNumTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.LoadMovieTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.LoadVariablesNumTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.LoadVariablesTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.MBAsciiToCharTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.MBCharToAsciiTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.MBStringExtractTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.MBStringLengthTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.NewMethodTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.NewObjectTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.NextFrameTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.PlayTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.PostDecrementTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.PostIncrementTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.PrevFrameTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.PrintAsBitmapNumTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.PrintAsBitmapTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.PrintNumTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.PrintTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.RandomNumberTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.RemoveSpriteTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.ReturnTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.SetMemberTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.SetVariableTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.StartDragTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.StopAllSoundsTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.StopDragTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.StopTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.StoreRegisterTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.StringExtractTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.StringLengthTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.ThrowTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.ToIntegerTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.ToNumberTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.ToStringTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.ToggleHighQualityTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.TraceTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.TypeOfTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.UnLoadMovieNumTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.UnLoadMovieTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.clauses.ClassTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.clauses.ForInTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.clauses.IfFrameLoadedTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.clauses.InterfaceTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.clauses.TellTargetTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.clauses.TryTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.clauses.WithTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.operations.AddTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.operations.BitAndTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.operations.BitOrTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.operations.BitXorTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.operations.DivideTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.operations.EqTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.operations.GeTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.operations.GtTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.operations.InstanceOfTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.operations.LeTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.operations.LtTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.operations.ModuloTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.operations.MultiplyTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.operations.NeqTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.operations.PreDecrementTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.operations.PreIncrementTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.operations.StrictEqTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.operations.StrictNeqTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.operations.SubtractTreeItem; import com.jpexs.decompiler.flash.ecma.Null; import com.jpexs.decompiler.flash.ecma.Undefined; +import com.jpexs.decompiler.flash.graph.AndItem; +import com.jpexs.decompiler.flash.graph.BinaryOp; +import com.jpexs.decompiler.flash.graph.BlockItem; +import com.jpexs.decompiler.flash.graph.BreakItem; +import com.jpexs.decompiler.flash.graph.CommaExpressionItem; +import com.jpexs.decompiler.flash.graph.ContinueItem; +import com.jpexs.decompiler.flash.graph.DoWhileItem; +import com.jpexs.decompiler.flash.graph.ForItem; import com.jpexs.decompiler.flash.graph.GraphSourceItem; +import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.IfItem; +import com.jpexs.decompiler.flash.graph.NotItem; +import com.jpexs.decompiler.flash.graph.OrItem; +import com.jpexs.decompiler.flash.graph.ParenthesisItem; +import com.jpexs.decompiler.flash.graph.SwitchItem; +import com.jpexs.decompiler.flash.graph.TernarOpItem; +import com.jpexs.decompiler.flash.graph.WhileItem; +import com.jpexs.decompiler.flash.helpers.collections.MyEntry; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStreamReader; @@ -48,7 +134,6 @@ import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; -import java.util.TreeSet; import java.util.logging.Level; import java.util.logging.Logger; @@ -72,14 +157,14 @@ public class ActionScriptParser { return "" + uniqLast; } - private List commands(HashMap registerVars, boolean inFunction, boolean inMethod, int forinlevel) throws IOException, ParseException { - List ret = new ArrayList<>(); + private List commands(HashMap registerVars, boolean inFunction, boolean inMethod, int forinlevel) throws IOException, ParseException { + List ret = new ArrayList<>(); if (debugMode) { System.out.println("commands:"); } - List cmd = new ArrayList<>(); - while ((cmd = command(registerVars, inFunction, inMethod, forinlevel)) != null) { - ret.addAll(cmd); + GraphTargetItem cmd = null; + while ((cmd = command(registerVars, inFunction, inMethod, forinlevel, true)) != null) { + ret.add(cmd); } if (debugMode) { System.out.println("/commands"); @@ -87,134 +172,76 @@ public class ActionScriptParser { return ret; } - private void fixLoop(List code, int breakOffset) { - fixLoop(code, breakOffset, Integer.MAX_VALUE); - } - - private Object fixZero(Object o) { - if (o instanceof Long) { - if (o.equals(new Long(0))) { - return new Double(0); - } - } - return o; - } - - private void fixLoop(List code, int breakOffset, int continueOffset) { - int pos = 0; - for (Action a : code) { - pos += a.getBytes(SWF.DEFAULT_VERSION).length; - if (a instanceof ActionJump) { - ActionJump aj = (ActionJump) a; - if (aj.isContinue && (continueOffset != Integer.MAX_VALUE)) { - aj.setJumpOffset(-pos + continueOffset); - aj.isContinue = false; - } - if (aj.isBreak) { - aj.setJumpOffset(-pos + breakOffset); - aj.isBreak = false; - } - } - } - } - - private List nonempty(List list) { + private List nonempty(List list) { if (list == null) { return new ArrayList<>(); } return list; } - private List typeToActions(List type, List value) throws IOException, ParseException { - List ret = new ArrayList<>(); - if (type.isEmpty()) { - return ret; - } - ret.add(pushConst(type.get(0))); - if (type.size() == 1 && (value != null)) { - ret.addAll(value); - ret.add(new ActionSetVariable()); - } else { - ret.add(new ActionGetVariable()); - } - for (int i = 1; i < type.size(); i++) { - ret.add(pushConst(type.get(i))); - if ((i == type.size() - 1) && (value != null)) { - ret.addAll(value); - ret.add(new ActionSetMember()); - } else { - ret.add(new ActionGetMember()); - } - } - return ret; - } - - private List type() throws IOException, ParseException { - List ret = new ArrayList<>(); + private GraphTargetItem type() throws IOException, ParseException { + GraphTargetItem ret = null; ParsedSymbol s = lex(); expected(s, lexer.yyline(), SymbolType.IDENTIFIER); - ret.add(s.value.toString()); + ret = new GetVariableTreeItem(null, pushConst(s.value.toString())); s = lex(); while (s.type == SymbolType.DOT) { s = lex(); expected(s, lexer.yyline(), SymbolType.IDENTIFIER); - ret.add(s.value.toString()); + ret = new GetMemberTreeItem(null, ret, pushConst(s.value.toString())); s = lex(); } lexer.pushback(s); return ret; } - private void memberOrCall(List newcmds, HashMap registerVars, boolean inFunction, boolean inMethod) throws IOException, ParseException { + private GraphTargetItem memberOrCall(GraphTargetItem newcmds, HashMap registerVars, boolean inFunction, boolean inMethod) throws IOException, ParseException { ParsedSymbol s = lex(); + GraphTargetItem ret = newcmds; while (s.isType(SymbolType.DOT, SymbolType.BRACKET_OPEN, SymbolType.PARENT_OPEN)) { switch (s.type) { case DOT: case BRACKET_OPEN: lexer.pushback(s); - newcmds.addAll(member(registerVars, inFunction, inMethod)); + ret = member(ret, registerVars, inFunction, inMethod); break; case PARENT_OPEN: - if (newcmds.get(newcmds.size() - 1) instanceof ActionGetMember) { - newcmds.remove(newcmds.size() - 1); - newcmds.addAll(0, call(registerVars, inFunction, inMethod)); - newcmds.add(new ActionCallMethod()); - } else if (newcmds.get(newcmds.size() - 1) instanceof ActionGetVariable) { - newcmds.remove(newcmds.size() - 1); - newcmds.addAll(0, call(registerVars, inFunction, inMethod)); - newcmds.add(new ActionCallFunction()); + if (ret instanceof GetMemberTreeItem) { + GetMemberTreeItem mem = (GetMemberTreeItem) ret; + ret = new CallMethodTreeItem(null, mem.object, mem.memberName, call(registerVars, inFunction, inMethod)); + } else if (ret instanceof GetVariableTreeItem) { + GetVariableTreeItem var = (GetVariableTreeItem) ret; + ret = new CallFunctionTreeItem(null, var.name, call(registerVars, inFunction, inMethod)); } else { - newcmds.addAll(0, call(registerVars, inFunction, inMethod)); - newcmds.add(new ActionCallFunction()); + ret = new CallFunctionTreeItem(null, ret, call(registerVars, inFunction, inMethod)); } break; } s = lex(); } lexer.pushback(s); + return ret; } - private List member(HashMap registerVars, boolean inFunction, boolean inMethod) throws IOException, ParseException { - List ret = new ArrayList<>(); + private GraphTargetItem member(GraphTargetItem obj, HashMap registerVars, boolean inFunction, boolean inMethod) throws IOException, ParseException { + GraphTargetItem ret = obj; ParsedSymbol s = lex(); while (s.isType(SymbolType.DOT, SymbolType.BRACKET_OPEN)) { if (s.type == SymbolType.BRACKET_OPEN) { - ret.addAll(expression(registerVars, inFunction, inMethod, true)); + ret = new GetMemberTreeItem(null, ret, expression(registerVars, inFunction, inMethod, true)); expectedType(SymbolType.BRACKET_CLOSE); - ret.add(new ActionGetMember()); s = lex(); continue; } s = lex(); expected(s, lexer.yyline(), SymbolType.IDENTIFIER, SymbolType.THIS, SymbolType.SUPER, SymbolGroup.GLOBALFUNC, SymbolGroup.GLOBALCONST); //TODO: Handle properties (?) - if (false) {//Action.propertyNamesList.contains(s.value.toString())) { - ret.add(new ActionPush((Long) (long) (int) Action.propertyNamesList.indexOf(s.value.toString()))); - ret.add(new ActionGetProperty()); + if (false) {//GraphTargetItem.propertyNamesList.contains(s.value.toString())) { + //ret.add(new ActionPush((Long) (long) (int) GraphTargetItem.propertyNamesList.indexOf(s.value.toString()))); + //ret.add(new ActionGetProperty()); } else { - ret.add(pushConst(s.value.toString())); - ret.add(new ActionGetMember()); + ret = new GetMemberTreeItem(null, ret, pushConst(s.value.toString())); } s = lex(); } @@ -222,30 +249,27 @@ public class ActionScriptParser { return ret; } - private List variable(HashMap registerVars, boolean inFunction, boolean inMethod) throws IOException, ParseException { - List ret = new ArrayList<>(); + private GraphTargetItem variable(HashMap registerVars, boolean inFunction, boolean inMethod) throws IOException, ParseException { + GraphTargetItem ret = null; ParsedSymbol s = lex(); expected(s, lexer.yyline(), SymbolType.IDENTIFIER, SymbolType.THIS, SymbolType.SUPER); if (registerVars.containsKey(s.value.toString())) { - ret.add(new ActionPush(new RegisterNumber(registerVars.get(s.value.toString())))); + ret = new DirectValueTreeItem(null, 0, new RegisterNumber(registerVars.get(s.value.toString())), new ArrayList()); } else { if (inMethod) { - ret.add(new ActionPush(new RegisterNumber(REGISTER_THIS))); + ret = new DirectValueTreeItem(null, 0, new RegisterNumber(REGISTER_THIS), new ArrayList()); //TODO: Handle properties (?) - if (false) { //Action.propertyNamesList.contains(s.value.toString())) { - ret.add(new ActionPush((Long) (long) (int) Action.propertyNamesList.indexOf(s.value.toString()))); - ret.add(new ActionGetProperty()); + if (false) { //GraphTargetItem.propertyNamesList.contains(s.value.toString())) { + //ret.add(new ActionPush((Long) (long) (int) GraphTargetItem.propertyNamesList.indexOf(s.value.toString()))); + //ret.add(new ActionGetProperty()); } else { - ret.add(pushConst(s.value.toString())); - ret.add(new ActionGetMember()); + ret = new GetMemberTreeItem(null, ret, pushConst(s.value.toString())); } - } else { - ret.add(pushConst(s.value.toString())); - ret.add(new ActionGetVariable()); + ret = new GetVariableTreeItem(null, pushConst(s.value.toString())); } } - ret.addAll(member(registerVars, inFunction, inMethod)); + ret = (member(ret, registerVars, inFunction, inMethod)); return ret; } @@ -287,26 +311,23 @@ public class ActionScriptParser { return ret; } - private List call(HashMap registerVars, boolean inFunction, boolean inMethod) throws IOException, ParseException { - List ret = new ArrayList<>(); + private List call(HashMap registerVars, boolean inFunction, boolean inMethod) throws IOException, ParseException { + List ret = new ArrayList<>(); //expected(SymbolType.PARENT_OPEN); //MUST BE HANDLED BY CALLER - int cnt = 0; ParsedSymbol s = lex(); while (s.type != SymbolType.PARENT_CLOSE) { if (s.type != SymbolType.COMMA) { lexer.pushback(s); } - cnt++; - ret.addAll(0, expression(registerVars, inFunction, inMethod, true)); + ret.add(expression(registerVars, inFunction, inMethod, true)); s = lex(); expected(s, lexer.yyline(), SymbolType.COMMA, SymbolType.PARENT_CLOSE); } - ret.add(new ActionPush(fixZero(new Long(cnt)))); return ret; } - private List function(boolean withBody, String functionName, boolean isMethod) throws IOException, ParseException { - List ret = new ArrayList<>(); + private FunctionTreeItem function(boolean withBody, String functionName, boolean isMethod) throws IOException, ParseException { + GraphTargetItem ret = null; ParsedSymbol s = null; expectedType(SymbolType.PARENT_OPEN); s = lex(); @@ -329,9 +350,6 @@ public class ActionScriptParser { expected(s, lexer.yyline(), SymbolType.COMMA, SymbolType.PARENT_CLOSE); } } - - - List paramRegs = new ArrayList<>(); HashMap registerVars = new HashMap<>(); registerVars.put("_parent", REGISTER_PARENT); registerVars.put("_root", REGISTER_ROOT); @@ -342,221 +360,64 @@ public class ActionScriptParser { for (int i = 0; i < paramNames.size(); i++) { registerVars.put(paramNames.get(i), (7 + i)); //(paramNames.size() - i))); } - boolean preloadParentFlag = false; - boolean preloadRootFlag = false; - boolean preloadSuperFlag = false; - boolean preloadArgumentsFlag = false; - boolean preloadThisFlag = false; - boolean preloadGlobalFlag = false; - - boolean suppressParentFlag = false; - boolean suppressArgumentsFlag = false; - boolean suppressThisFlag = false; - TreeSet usedRegisters = new TreeSet<>(); + List body = null; if (withBody) { - expectedType(SymbolType.CURLY_OPEN); - List body = commands(registerVars, true, isMethod, 0); - for (Action a : body) { - if (a instanceof ActionStoreRegister) { - usedRegisters.add(((ActionStoreRegister) a).registerNumber); - } - if (a instanceof ActionPush) { - ActionPush ap = (ActionPush) a; - for (Object o : ap.values) { - if (o instanceof RegisterNumber) { - usedRegisters.add(((RegisterNumber) o).number); - } - } - } - } - if (usedRegisters.contains(REGISTER_PARENT)) { - preloadParentFlag = true; - } else { - suppressParentFlag = true; - } - if (usedRegisters.contains(REGISTER_ROOT)) { - preloadRootFlag = true; - } - if (usedRegisters.contains(REGISTER_SUPER)) { - preloadSuperFlag = true; - } - if (usedRegisters.contains(REGISTER_ARGUMENTS)) { - preloadArgumentsFlag = true; - } else { - suppressArgumentsFlag = true; - } - if (usedRegisters.contains(REGISTER_THIS)) { - preloadThisFlag = true; - } else { - suppressThisFlag = true; - } - if (usedRegisters.contains(REGISTER_GLOBAL)) { - preloadGlobalFlag = true; - } - - int newpos = 1; - HashMap registerMap = new HashMap<>(); - if (preloadThisFlag) { - registerMap.put(REGISTER_THIS, newpos); - newpos++; - } - if (preloadArgumentsFlag) { - registerMap.put(REGISTER_ARGUMENTS, newpos); - newpos++; - } - if (preloadSuperFlag) { - registerMap.put(REGISTER_SUPER, newpos); - newpos++; - } - if (preloadRootFlag) { - registerMap.put(REGISTER_ROOT, newpos); - newpos++; - } - if (preloadParentFlag) { - registerMap.put(REGISTER_PARENT, newpos); - newpos++; - } - if (preloadGlobalFlag) { - registerMap.put(REGISTER_GLOBAL, newpos); - newpos++; - } - if (newpos < 1) { - newpos = 1; - } - for (int i = 0; i < 256; i++) { - if (usedRegisters.contains(7 + i)) { - registerMap.put(7 + i, newpos); - if (i < paramNames.size()) { - paramRegs.add(0, newpos); - } - newpos++; - } else { - if (i < paramNames.size()) { - paramRegs.add(0, 0); - } - } - } - - TreeSet usedRegisters2 = new TreeSet<>(); - for (int i : usedRegisters) { - if (registerMap.get(i) == null) { - usedRegisters2.add(i); - } else { - usedRegisters2.add(registerMap.get(i)); - } - } - usedRegisters = usedRegisters2; - - for (Action a : body) { - if (a instanceof ActionStoreRegister) { - if (registerMap.containsKey(((ActionStoreRegister) a).registerNumber)) { - ((ActionStoreRegister) a).registerNumber = registerMap.get(((ActionStoreRegister) a).registerNumber); - } - } - if (a instanceof ActionPush) { - ActionPush ap = (ActionPush) a; - for (Object o : ap.values) { - if (o instanceof RegisterNumber) { - if (registerMap.containsKey(((RegisterNumber) o).number)) { - ((RegisterNumber) o).number = registerMap.get(((RegisterNumber) o).number); - } - } - } - } - } + body = commands(registerVars, true, isMethod, 0); expectedType(SymbolType.CURLY_CLOSE); - ret.addAll(body); - } else { - for (int i = 0; i < paramNames.size(); i++) { - paramRegs.add(1 + i); - } } - int len = Action.actionsToBytes(ret, false, SWF.DEFAULT_VERSION).length; - if ((!preloadParentFlag) - && (!preloadRootFlag) - && (!preloadSuperFlag) - && (!preloadArgumentsFlag) - && (!preloadThisFlag) - && (!preloadGlobalFlag) - && (suppressArgumentsFlag) - && (suppressThisFlag) - && (suppressParentFlag) - && usedRegisters.isEmpty()) { - ret.add(0, new ActionDefineFunction(functionName, paramNames, len, SWF.DEFAULT_VERSION)); - } else { - ret.add(0, new ActionDefineFunction2(functionName, - preloadParentFlag, - preloadRootFlag, - suppressParentFlag, - preloadSuperFlag, - suppressArgumentsFlag, - preloadArgumentsFlag, - suppressThisFlag, - preloadThisFlag, - preloadGlobalFlag, - usedRegisters.isEmpty() ? 0 : (usedRegisters.last() + 1), len, SWF.DEFAULT_VERSION, paramNames, paramRegs)); - } - return ret; + + return new FunctionTreeItem(null, functionName, paramNames, body, constantPool, -1); } - private List gettoset(List get, List value) { - List ret = new ArrayList<>(); - ret.addAll(get); - if (!ret.isEmpty()) { - Action a = ret.get(ret.size() - 1); - if (a instanceof ActionGetVariable) { - ret.remove(ret.size() - 1); - ret.addAll(value); - ret.add(new ActionSetVariable()); - } else if (a instanceof ActionGetMember) { - ret.remove(ret.size() - 1); - ret.addAll(value); - ret.add(new ActionSetMember()); - } else if ((a instanceof ActionPush) && ((ActionPush) a).values.get(0) instanceof RegisterNumber) { - ret.remove(ret.size() - 1); - ret.addAll(value); - ret.add(new ActionStoreRegister(((RegisterNumber) ((ActionPush) a).values.get(0)).number)); - ret.add(new ActionPop()); - } else if (a instanceof ActionGetProperty) { - ret.remove(ret.size() - 1); - ret.addAll(value); - ret.add(new ActionSetProperty()); - } - } - return ret; - } + private GraphTargetItem traits(boolean isInterface, GraphTargetItem nameStr, GraphTargetItem extendsStr, List implementsStr) throws IOException, ParseException { - private List traits(boolean isInterface, List nameStr, List extendsStr, List> implementsStr) throws IOException, ParseException { + GraphTargetItem ret = null; + /*for (int i = 0; i < nameStr.size() - 1; i++) { + List notBody = new ArrayList<>(); + List globalClassTypeStr = new ArrayList<>(); + globalClassTypeStr.add("_global"); + for (int j = 0; j <= i; j++) { + globalClassTypeStr.add(nameStr.get(j)); + } - List ret = new ArrayList<>(); - for (int i = 0; i < nameStr.size() - 1; i++) { - List notBody = new ArrayList<>(); - List globalClassTypeStr = new ArrayList<>(); - globalClassTypeStr.add("_global"); - for (int j = 0; j <= i; j++) { - globalClassTypeStr.add(nameStr.get(j)); - } - - List val = new ArrayList<>(); - val.add(new ActionPush((Long) 0L)); - val.add(pushConst("Object")); - val.add(new ActionNewObject()); - notBody.addAll(typeToActions(globalClassTypeStr, val)); - ret.addAll(typeToActions(globalClassTypeStr, null)); - ret.add(new ActionNot()); - ret.add(new ActionNot()); - ret.add(new ActionIf(Action.actionsToBytes(notBody, false, SWF.DEFAULT_VERSION).length)); - ret.addAll(notBody); - } - List ifbody = new ArrayList<>(); - List globalClassTypeStr = new ArrayList<>(); - globalClassTypeStr.add("_global"); - globalClassTypeStr.addAll(nameStr); + List val = new ArrayList<>(); + val.add(new ActionPush((Long) 0L)); + val.add(pushConst("Object")); + val.add(new ActionNewObject()); + notBody.addAll(typeToActions(globalClassTypeStr, val)); + ret.addAll(typeToActions(globalClassTypeStr, null)); + ret.add(new ActionNot()); + ret.add(new ActionNot()); + ret.add(new ActionIf(GraphTargetItem.actionsToBytes(notBody, false, SWF.DEFAULT_VERSION).length)); + ret.addAll(notBody); + } + List ifbody = new ArrayList<>(); + List globalClassTypeStr = new ArrayList<>(); + globalClassTypeStr.add("_global"); + globalClassTypeStr.addAll(nameStr);*/ ParsedSymbol s = null; - List constr = new ArrayList<>(); + FunctionTreeItem constr = null; + List staticFunctions = new ArrayList<>(); + List> staticVars = new ArrayList<>(); + List functions = new ArrayList<>(); + List> vars = new ArrayList<>(); + + String classNameStr = ""; + if (nameStr instanceof GetMemberTreeItem) { + GetMemberTreeItem mem = (GetMemberTreeItem) nameStr; + if (mem.memberName instanceof DirectValueTreeItem) { + classNameStr = ((DirectValueTreeItem) mem.memberName).toStringNoQuotes(new ConstantPool(constantPool)); + } + } else if (nameStr instanceof GetVariableTreeItem) { + GetVariableTreeItem var = (GetVariableTreeItem) nameStr; + if (var.name instanceof DirectValueTreeItem) { + classNameStr = ((DirectValueTreeItem) var.name).toStringNoQuotes(new ConstantPool(constantPool)); + } + } + looptrait: while (true) { s = lex(); @@ -572,18 +433,19 @@ public class ActionScriptParser { s = lex(); expected(s, lexer.yyline(), SymbolType.IDENTIFIER); String fname = s.value.toString(); - if (fname.equals(nameStr.get(nameStr.size() - 1))) { //constructor - constr = new ArrayList<>(); - constr.addAll(function(!isInterface, "", true)); - constr.add(new ActionStoreRegister(1)); - constr = (typeToActions(globalClassTypeStr, constr)); - + if (fname.equals(classNameStr)) { //constructor + constr = (function(!isInterface, "", true)); } else { if (!isInterface) { - ifbody.add(new ActionPush(new RegisterNumber(isStatic ? 1 : 2))); - ifbody.add(pushConst(fname)); - ifbody.addAll(function(!isInterface, "", true)); - ifbody.add(new ActionSetMember()); + if (isStatic) { + FunctionTreeItem ft = function(!isInterface, "", true); + ft.calculatedFunctionName = pushConst(fname); + staticFunctions.add(ft); + } else { + FunctionTreeItem ft = function(!isInterface, "", true); + ft.calculatedFunctionName = pushConst(fname); + functions.add(ft); + } } } break; @@ -597,10 +459,11 @@ public class ActionScriptParser { s = lex(); } if (s.type == SymbolType.ASSIGN) { - ifbody.add(new ActionPush(new RegisterNumber(isStatic ? 1 : 2))); - ifbody.add(pushConst(ident)); - ifbody.addAll(expression(new HashMap(), false, false, true)); - ifbody.add(new ActionSetMember()); + if (isStatic) { + staticVars.add(new MyEntry(pushConst(ident), expression(new HashMap(), false, false, true))); + } else { + vars.add(new MyEntry(pushConst(ident), expression(new HashMap(), false, false, true))); + } s = lex(); } if (s.type != SymbolType.SEMICOLON) { @@ -614,179 +477,123 @@ public class ActionScriptParser { } } - if (!isInterface) { - ifbody.add(new ActionPush((Long) 1L)); - ifbody.add(new ActionPush(new Null())); - ifbody.addAll(typeToActions(globalClassTypeStr, null)); - ifbody.add(pushConst("prototype")); - ifbody.add(new ActionGetMember()); - ifbody.add(new ActionPush((Long) 3L)); - ifbody.add(pushConst("ASSetPropFlags")); - ifbody.add(new ActionCallFunction()); + if (isInterface) { + return new InterfaceTreeItem(nameStr, implementsStr); + } else { + return new ClassTreeItem(nameStr, extendsStr, implementsStr, constr, functions, vars, staticFunctions, staticVars); } - - if (constr.isEmpty()) { - List val = new ArrayList<>(); - val.add(new ActionDefineFunction("", new ArrayList(), 0, SWF.DEFAULT_VERSION)); - if (!isInterface) { - val.add(new ActionStoreRegister(1)); - } - constr.addAll(typeToActions(globalClassTypeStr, val)); - } - if (!extendsStr.isEmpty()) { - constr.addAll(typeToActions(globalClassTypeStr, null)); - constr.addAll(typeToActions(extendsStr, null)); - constr.add(new ActionExtends()); - } - if (!isInterface) { - constr.add(new ActionPush(new RegisterNumber(1))); - constr.add(pushConst("prototype")); - constr.add(new ActionGetMember()); - constr.add(new ActionStoreRegister(2)); - constr.add(new ActionPop()); - } - - if (!implementsStr.isEmpty()) { - for (List imp : implementsStr) { - List globImp = new ArrayList<>(); - globImp.add("_global"); - globImp.addAll(imp); - constr.addAll(typeToActions(globImp, null)); - } - constr.add(new ActionPush(new Long(implementsStr.size()))); - constr.addAll(typeToActions(globalClassTypeStr, null)); - constr.add(new ActionImplementsOp()); - } - ifbody.addAll(0, constr); - - ret.addAll(typeToActions(globalClassTypeStr, null)); - ret.add(new ActionNot()); - ret.add(new ActionNot()); - ret.add(new ActionIf(Action.actionsToBytes(ifbody, false, SWF.DEFAULT_VERSION).length)); - ret.addAll(ifbody); - ret.add(new ActionPop()); - return ret; } - private List expressionCommands(ParsedSymbol s, HashMap registerVars, boolean inFunction, boolean inMethod, int forinlevel) throws IOException, ParseException { - List ret = new ArrayList<>(); + private GraphTargetItem expressionCommands(ParsedSymbol s, HashMap registerVars, boolean inFunction, boolean inMethod, int forinlevel) throws IOException, ParseException { + GraphTargetItem ret = null; switch (s.type) { + case GETVERSION: + expectedType(SymbolType.PARENT_OPEN); + ret = new GetVersionTreeItem(null); + expectedType(SymbolType.PARENT_CLOSE); + break; case MBORD: expectedType(SymbolType.PARENT_OPEN); - ret.addAll(expression(registerVars, inFunction, inMethod, true)); + ret = new MBCharToAsciiTreeItem(null, expression(registerVars, inFunction, inMethod, true)); expectedType(SymbolType.PARENT_CLOSE); - ret.add(new ActionMBCharToAscii()); break; case MBCHR: expectedType(SymbolType.PARENT_OPEN); - ret.addAll(expression(registerVars, inFunction, inMethod, true)); + ret = new MBAsciiToCharTreeItem(null, expression(registerVars, inFunction, inMethod, true)); expectedType(SymbolType.PARENT_CLOSE); - ret.add(new ActionMBAsciiToChar()); break; case MBLENGTH: expectedType(SymbolType.PARENT_OPEN); - ret.addAll(expression(registerVars, inFunction, inMethod, true)); + ret = new MBStringLengthTreeItem(null, expression(registerVars, inFunction, inMethod, true)); expectedType(SymbolType.PARENT_CLOSE); - ret.add(new ActionMBStringLength()); break; case MBSUBSTRING: expectedType(SymbolType.PARENT_OPEN); - ret.addAll(expression(registerVars, inFunction, inMethod, true)); + GraphTargetItem val1 = (expression(registerVars, inFunction, inMethod, true)); expectedType(SymbolType.COMMA); - ret.addAll(expression(registerVars, inFunction, inMethod, true)); + GraphTargetItem index1 = (expression(registerVars, inFunction, inMethod, true)); expectedType(SymbolType.COMMA); - ret.addAll(expression(registerVars, inFunction, inMethod, true)); + GraphTargetItem len1 = (expression(registerVars, inFunction, inMethod, true)); expectedType(SymbolType.PARENT_CLOSE); - ret.add(new ActionMBStringExtract()); + ret = new MBStringExtractTreeItem(null, val1, index1, len1); break; case SUBSTR: expectedType(SymbolType.PARENT_OPEN); - ret.addAll(expression(registerVars, inFunction, inMethod, true)); + GraphTargetItem val2 = (expression(registerVars, inFunction, inMethod, true)); expectedType(SymbolType.COMMA); - ret.addAll(expression(registerVars, inFunction, inMethod, true)); + GraphTargetItem index2 = (expression(registerVars, inFunction, inMethod, true)); expectedType(SymbolType.COMMA); - ret.addAll(expression(registerVars, inFunction, inMethod, true)); + GraphTargetItem len2 = (expression(registerVars, inFunction, inMethod, true)); expectedType(SymbolType.PARENT_CLOSE); - ret.add(new ActionStringExtract()); + ret = new StringExtractTreeItem(null, val2, index2, len2); break; case LENGTH: expectedType(SymbolType.PARENT_OPEN); - ret.addAll(expression(registerVars, inFunction, inMethod, true)); + ret = new StringLengthTreeItem(null, expression(registerVars, inFunction, inMethod, true)); expectedType(SymbolType.PARENT_CLOSE); - ret.add(new ActionStringLength()); break; case RANDOM: expectedType(SymbolType.PARENT_OPEN); - ret.addAll(expression(registerVars, inFunction, inMethod, true)); + ret = new RandomNumberTreeItem(null, expression(registerVars, inFunction, inMethod, true)); expectedType(SymbolType.PARENT_CLOSE); - ret.add(new ActionRandomNumber()); break; case INT: expectedType(SymbolType.PARENT_OPEN); - ret.addAll(expression(registerVars, inFunction, inMethod, true)); + ret = new ToIntegerTreeItem(null, expression(registerVars, inFunction, inMethod, true)); expectedType(SymbolType.PARENT_CLOSE); - ret.add(new ActionToInteger()); break; - case TARGETPATH: - expectedType(SymbolType.PARENT_OPEN); - ret.addAll(expression(registerVars, inFunction, inMethod, true)); - expectedType(SymbolType.PARENT_CLOSE); - ret.add(new ActionTargetPath()); - break; + /*case TARGETPATH: + expectedType(SymbolType.PARENT_OPEN); + ret.addAll(expression(registerVars, inFunction, inMethod, true)); + expectedType(SymbolType.PARENT_CLOSE); + ret.add(new ActionTargetPath()); + break;*/ case NUMBER_OP: s = lex(); if (s.type == SymbolType.DOT) { - ret.add(pushConst((String) s.value)); - ret.add(new ActionGetVariable()); - memberOrCall(ret, registerVars, inFunction, inMethod); + ret = memberOrCall(new GetVariableTreeItem(null, new DirectValueTreeItem(null, 0, s.value, new ArrayList())), registerVars, inFunction, inMethod); } else { expected(s, lexer.yyline(), SymbolType.PARENT_OPEN); - ret.addAll(expression(registerVars, inFunction, inMethod, true)); + ret = new ToNumberTreeItem(null, expression(registerVars, inFunction, inMethod, true)); expectedType(SymbolType.PARENT_CLOSE); - ret.add(new ActionToNumber()); } break; case STRING_OP: s = lex(); if (s.type == SymbolType.DOT) { - ret.add(pushConst((String) s.value)); - ret.add(new ActionGetVariable()); - memberOrCall(ret, registerVars, inFunction, inMethod); + ret = memberOrCall(new GetVariableTreeItem(null, new DirectValueTreeItem(null, 0, s.value, new ArrayList())), registerVars, inFunction, inMethod); } else { expected(s, lexer.yyline(), SymbolType.PARENT_OPEN); - ret.addAll(expression(registerVars, inFunction, inMethod, true)); + ret = new ToStringTreeItem(null, expression(registerVars, inFunction, inMethod, true)); expectedType(SymbolType.PARENT_CLOSE); - ret.add(new ActionToString()); - memberOrCall(ret, registerVars, inFunction, inMethod); + ret = memberOrCall(ret, registerVars, inFunction, inMethod); } break; case ORD: expectedType(SymbolType.PARENT_OPEN); - ret.addAll(expression(registerVars, inFunction, inMethod, true)); + ret = new CharToAsciiTreeItem(null, expression(registerVars, inFunction, inMethod, true)); expectedType(SymbolType.PARENT_CLOSE); - ret.add(new ActionCharToAscii()); break; case CHR: expectedType(SymbolType.PARENT_OPEN); - ret.addAll(expression(registerVars, inFunction, inMethod, true)); + ret = new AsciiToCharTreeItem(null, expression(registerVars, inFunction, inMethod, true)); expectedType(SymbolType.PARENT_CLOSE); - ret.add(new ActionAsciiToChar()); break; case DUPLICATEMOVIECLIP: expectedType(SymbolType.PARENT_OPEN); - ret.addAll(expression(registerVars, inFunction, inMethod, true)); + GraphTargetItem src3 = (expression(registerVars, inFunction, inMethod, true)); expectedType(SymbolType.COMMA); - ret.addAll(expression(registerVars, inFunction, inMethod, true)); + GraphTargetItem tar3 = (expression(registerVars, inFunction, inMethod, true)); expectedType(SymbolType.COMMA); - ret.addAll(expression(registerVars, inFunction, inMethod, true)); + GraphTargetItem dep3 = (expression(registerVars, inFunction, inMethod, true)); expectedType(SymbolType.PARENT_CLOSE); - ret.add(new ActionCloneSprite()); + ret = new CloneSpriteTreeItem(null, src3, tar3, dep3); break; case GETTIMER: expectedType(SymbolType.PARENT_OPEN); expectedType(SymbolType.PARENT_CLOSE); - ret.add(new ActionGetTime()); + ret = new GetTimeTreeItem(null); break; default: return null; @@ -794,8 +601,10 @@ public class ActionScriptParser { return ret; } - private List command(HashMap registerVars, boolean inFunction, boolean inMethod, int forinlevel) throws IOException, ParseException { - List ret = new ArrayList<>(); + private GraphTargetItem command(HashMap registerVars, boolean inFunction, boolean inMethod, int forinlevel, boolean mustBeCommand) throws IOException, ParseException { + LexBufferer buf = new LexBufferer(); + lexer.addListener(buf); + GraphTargetItem ret = null; if (debugMode) { System.out.println("command:"); } @@ -804,65 +613,62 @@ public class ActionScriptParser { return null; } switch (s.type) { + case CALL: + expectedType(SymbolType.PARENT_OPEN); + ret = new CallTreeItem(null, (expression(registerVars, inFunction, inMethod, true))); + expectedType(SymbolType.PARENT_CLOSE); + break; case LENGTH: expectedType(SymbolType.PARENT_OPEN); - ret.addAll(expression(registerVars, inFunction, inMethod, true)); + ret = new StringLengthTreeItem(null, (expression(registerVars, inFunction, inMethod, true))); expectedType(SymbolType.PARENT_CLOSE); - ret.add(new ActionStringLength()); break; case MBLENGTH: expectedType(SymbolType.PARENT_OPEN); - ret.addAll(expression(registerVars, inFunction, inMethod, true)); + ret = new MBStringLengthTreeItem(null, (expression(registerVars, inFunction, inMethod, true))); expectedType(SymbolType.PARENT_CLOSE); - ret.add(new ActionMBStringLength()); break; case SET: expectedType(SymbolType.PARENT_OPEN); - ret.addAll(expression(registerVars, inFunction, inMethod, true)); + GraphTargetItem name1 = (expression(registerVars, inFunction, inMethod, true)); expectedType(SymbolType.COMMA); - ret.addAll(expression(registerVars, inFunction, inMethod, true)); + GraphTargetItem value1 = (expression(registerVars, inFunction, inMethod, true)); expectedType(SymbolType.PARENT_CLOSE); - ret.add(new ActionSetVariable()); + ret = new SetVariableTreeItem(null, name1, value1); break; case WITH: expectedType(SymbolType.PARENT_OPEN); - ret.addAll(variable(registerVars, inFunction, inMethod)); + GraphTargetItem wvar = (variable(registerVars, inFunction, inMethod)); expectedType(SymbolType.PARENT_CLOSE); expectedType(SymbolType.CURLY_OPEN); - - List wcmd = commands(registerVars, inFunction, inMethod, forinlevel); + List wcmd = commands(registerVars, inFunction, inMethod, forinlevel); expectedType(SymbolType.CURLY_CLOSE); - int wlen = Action.actionsToBytes(wcmd, false, SWF.DEFAULT_VERSION).length; - ret.add(new ActionWith(wlen)); - ret.addAll(wcmd); + ret = new WithTreeItem(null, wvar, wcmd); break; case DELETE: - ret.addAll(variable(registerVars, inFunction, inMethod)); - if (ret.get(ret.size() - 1) instanceof ActionGetMember) { - ret.remove(ret.size() - 1); + GraphTargetItem varDel = variable(registerVars, inFunction, inMethod); + if (varDel instanceof GetMemberTreeItem) { + GetMemberTreeItem gm = (GetMemberTreeItem) varDel; + ret = new DeleteTreeItem(null, gm.object, gm.memberName); + } else { + throw new ParseException("Not a property", lexer.yyline()); } - ret.add(new ActionDelete()); break; case TRACE: expectedType(SymbolType.PARENT_OPEN); - ret.addAll(expression(registerVars, inFunction, inMethod, true)); - ret.add(new ActionTrace()); - expectedType(SymbolType.PARENT_CLOSE); - break; - case GETVERSION: - expectedType(SymbolType.PARENT_OPEN); - ret.add(pushConst("/:$version")); - ret.add(new ActionGetVariable()); + ret = new TraceTreeItem(null, (expression(registerVars, inFunction, inMethod, true))); expectedType(SymbolType.PARENT_CLOSE); break; + case GETURL: expectedType(SymbolType.PARENT_OPEN); - ret.addAll(expression(registerVars, inFunction, inMethod, true)); + GraphTargetItem url = (expression(registerVars, inFunction, inMethod, true)); s = lex(); expected(s, lexer.yyline(), SymbolType.PARENT_CLOSE, SymbolType.COMMA); int getuMethod = 1; + GraphTargetItem target = null; if (s.type == SymbolType.COMMA) { - ret.addAll(expression(registerVars, inFunction, inMethod, true)); + target = (expression(registerVars, inFunction, inMethod, true)); s = lex(); if (s.type == SymbolType.COMMA) { s = lex(); @@ -879,73 +685,121 @@ public class ActionScriptParser { } } else { lexer.pushback(s); - ret.add(pushConst("")); + target = new DirectValueTreeItem(null, 0, "", new ArrayList()); } - ret.add(new ActionGetURL2(getuMethod, false, false)); expectedType(SymbolType.PARENT_CLOSE); + ret = new GetURL2TreeItem(null, url, target, getuMethod); break; case GOTOANDSTOP: expectedType(SymbolType.PARENT_OPEN); - List gtsFrame = expression(registerVars, inFunction, inMethod, true); + GraphTargetItem gtsFrame = expression(registerVars, inFunction, inMethod, true); s = lex(); - if (s.type == SymbolType.COMMA) { + if (s.type == SymbolType.COMMA) { //Handle scene? s = lex(); gtsFrame = expression(registerVars, inFunction, inMethod, true); } else { lexer.pushback(s); } - ret.addAll(gtsFrame); - ret.add(new ActionGotoFrame2(false, false, (int) (long) (Long) s.value)); + ret = new GotoFrame2TreeItem(null, gtsFrame, false, false, 0); expectedType(SymbolType.PARENT_CLOSE); break; case NEXTFRAME: expectedType(SymbolType.PARENT_OPEN); expectedType(SymbolType.PARENT_CLOSE); - ret.add(new ActionNextFrame()); + ret = new NextFrameTreeItem(null); break; case PLAY: expectedType(SymbolType.PARENT_OPEN); expectedType(SymbolType.PARENT_CLOSE); - ret.add(new ActionPlay()); + ret = new PlayTreeItem(null); break; case PREVFRAME: expectedType(SymbolType.PARENT_OPEN); expectedType(SymbolType.PARENT_CLOSE); - ret.add(new ActionPrevFrame()); + ret = new PrevFrameTreeItem(null); break; case TELLTARGET: expectedType(SymbolType.PARENT_OPEN); - ret.addAll(expression(registerVars, inFunction, inMethod, true)); + GraphTargetItem tellTarget = expression(registerVars, inFunction, inMethod, true); expectedType(SymbolType.PARENT_CLOSE); - ret.add(new ActionSetTarget2()); + expectedType(SymbolType.CURLY_OPEN); + List tellcmds = commands(registerVars, inFunction, inMethod, forinlevel); + expectedType(SymbolType.CURLY_CLOSE); + ret = new TellTargetTreeItem(null, tellTarget, tellcmds); break; case STOP: expectedType(SymbolType.PARENT_OPEN); expectedType(SymbolType.PARENT_CLOSE); - ret.add(new ActionStop()); + ret = new StopTreeItem(null); break; case STOPALLSOUNDS: expectedType(SymbolType.PARENT_OPEN); expectedType(SymbolType.PARENT_CLOSE); - ret.add(new ActionStopSounds()); + ret = new StopAllSoundsTreeItem(null); break; case TOGGLEHIGHQUALITY: expectedType(SymbolType.PARENT_OPEN); expectedType(SymbolType.PARENT_CLOSE); - ret.add(new ActionToggleQuality()); + ret = new ToggleHighQualityTreeItem(null); break; case STOPDRAG: expectedType(SymbolType.PARENT_OPEN); expectedType(SymbolType.PARENT_CLOSE); - ret.add(new ActionEndDrag()); + ret = new StopDragTreeItem(null); break; - case LOADVARIABLES: + case UNLOADMOVIE: + case UNLOADMOVIENUM: + SymbolType unloadType = s.type; expectedType(SymbolType.PARENT_OPEN); - ret.addAll(expression(registerVars, inFunction, inMethod, true)); + GraphTargetItem unTargetOrNum = expression(registerVars, inFunction, inMethod, true); + expectedType(SymbolType.PARENT_CLOSE); + if (unloadType == SymbolType.UNLOADMOVIE) { + ret = new UnLoadMovieTreeItem(null, unTargetOrNum); + } + if (unloadType == SymbolType.UNLOADMOVIENUM) { + ret = new UnLoadMovieNumTreeItem(null, unTargetOrNum); + } + break; + case PRINT: + case PRINTASBITMAP: + case PRINTASBITMAPNUM: + case PRINTNUM: + SymbolType printType = s.type; + expectedType(SymbolType.PARENT_OPEN); + GraphTargetItem printTarget = (expression(registerVars, inFunction, inMethod, true)); expectedType(SymbolType.COMMA); - ret.addAll(expression(registerVars, inFunction, inMethod, true)); + GraphTargetItem printBBox = (expression(registerVars, inFunction, inMethod, true)); + expectedType(SymbolType.PARENT_CLOSE); + + switch (printType) { + case PRINT: + ret = new PrintTreeItem(null, printTarget, printBBox); + break; + case PRINTNUM: + ret = new PrintNumTreeItem(null, printTarget, printBBox); + break; + case PRINTASBITMAP: + ret = new PrintAsBitmapTreeItem(null, printTarget, printBBox); + break; + case PRINTASBITMAPNUM: + ret = new PrintAsBitmapNumTreeItem(null, printTarget, printBBox); + break; + } + break; + case LOADVARIABLES: + case LOADMOVIE: + case LOADVARIABLESNUM: + case LOADMOVIENUM: + SymbolType loadType = s.type; + expectedType(SymbolType.PARENT_OPEN); + GraphTargetItem url2 = (expression(registerVars, inFunction, inMethod, true)); + expectedType(SymbolType.COMMA); + GraphTargetItem targetOrNum = (expression(registerVars, inFunction, inMethod, true)); + + + s = lex(); expected(s, lexer.yyline(), SymbolType.PARENT_CLOSE, SymbolType.COMMA); int lvmethod = 1; @@ -963,163 +817,157 @@ public class ActionScriptParser { lexer.pushback(s); } expectedType(SymbolType.PARENT_CLOSE); - ret.add(new ActionGetURL2(lvmethod, false, true)); - break; - case LOADMOVIE: - expectedType(SymbolType.PARENT_OPEN); - ret.addAll(expression(registerVars, inFunction, inMethod, true)); - s = lex(); - expected(s, lexer.yyline(), SymbolType.PARENT_CLOSE, SymbolType.COMMA); - int method = 1; - if (s.type == SymbolType.COMMA) { - s = lex(); - expected(s, lexer.yyline(), SymbolType.STRING); - if (s.value.equals("POST")) { - method = 2; - } else if (s.value.equals("GET")) { - method = 1; - } else { - throw new ParseException("Invalid method, \"GET\" or \"POST\" expected.", lexer.yyline()); - } - } else { - lexer.pushback(s); + switch (loadType) { + case LOADVARIABLES: + ret = new LoadVariablesTreeItem(null, url2, targetOrNum, lvmethod); + break; + case LOADMOVIE: + ret = new LoadMovieTreeItem(null, url2, targetOrNum, lvmethod); + break; + case LOADVARIABLESNUM: + ret = new LoadVariablesNumTreeItem(null, url2, targetOrNum, lvmethod); + break; + case LOADMOVIENUM: + ret = new LoadMovieNumTreeItem(null, url2, targetOrNum, lvmethod); + break; } - expectedType(SymbolType.PARENT_CLOSE); - ret.add(new ActionGetURL2(method, true, false)); break; case GOTOANDPLAY: expectedType(SymbolType.PARENT_OPEN); - List gtpFrame = expression(registerVars, inFunction, inMethod, true); + GraphTargetItem gtpFrame = expression(registerVars, inFunction, inMethod, true); s = lex(); - if (s.type == SymbolType.COMMA) { + if (s.type == SymbolType.COMMA) { //Handle scene? s = lex(); gtpFrame = expression(registerVars, inFunction, inMethod, true); } else { lexer.pushback(s); } - ret.addAll(gtpFrame); - ret.add(new ActionGotoFrame2(true, false, (int) (long) (Long) s.value)); + ret = new GotoFrame2TreeItem(null, gtpFrame, true, false, 0); expectedType(SymbolType.PARENT_CLOSE); break; case REMOVEMOVIECLIP: expectedType(SymbolType.PARENT_OPEN); - ret.addAll(expression(registerVars, inFunction, inMethod, true)); + ret = new RemoveSpriteTreeItem(null, (expression(registerVars, inFunction, inMethod, true))); expectedType(SymbolType.PARENT_CLOSE); - ret.add(new ActionRemoveSprite()); break; case STARTDRAG: expectedType(SymbolType.PARENT_OPEN); - ret.addAll(expression(registerVars, inFunction, inMethod, true)); + GraphTargetItem dragTarget = (expression(registerVars, inFunction, inMethod, true)); + GraphTargetItem lockCenter = null; + GraphTargetItem constrain = null; + GraphTargetItem x1 = null; + GraphTargetItem y1 = null; + GraphTargetItem x2 = null; + GraphTargetItem y2 = null; s = lex(); if (s.type == SymbolType.COMMA) { - ret.addAll(expression(registerVars, inFunction, inMethod, true)); + lockCenter = (expression(registerVars, inFunction, inMethod, true)); s = lex(); if (s.type == SymbolType.COMMA) { - ret.add(new ActionPush(Boolean.TRUE)); - ret.addAll(expression(registerVars, inFunction, inMethod, true)); + constrain = new DirectValueTreeItem(null, 0, Boolean.TRUE, new ArrayList()); + x1 = (expression(registerVars, inFunction, inMethod, true)); s = lex(); if (s.type == SymbolType.COMMA) { - ret.addAll(expression(registerVars, inFunction, inMethod, true)); + y1 = (expression(registerVars, inFunction, inMethod, true)); s = lex(); if (s.type == SymbolType.COMMA) { - ret.addAll(expression(registerVars, inFunction, inMethod, true)); + x2 = (expression(registerVars, inFunction, inMethod, true)); s = lex(); if (s.type == SymbolType.COMMA) { - ret.addAll(expression(registerVars, inFunction, inMethod, true)); + y2 = (expression(registerVars, inFunction, inMethod, true)); } else { lexer.pushback(s); - ret.add(new ActionPush(new Long(0))); + y2 = new DirectValueTreeItem(null, 0, (Long) 0L, new ArrayList()); } } else { lexer.pushback(s); - ret.add(new ActionPush(new Long(0))); - ret.add(new ActionPush(new Long(0))); + x2 = new DirectValueTreeItem(null, 0, (Long) 0L, new ArrayList()); + y2 = new DirectValueTreeItem(null, 0, (Long) 0L, new ArrayList()); } } else { lexer.pushback(s); - ret.add(new ActionPush(new Long(0))); - ret.add(new ActionPush(new Long(0))); - ret.add(new ActionPush(new Long(0))); + x2 = new DirectValueTreeItem(null, 0, (Long) 0L, new ArrayList()); + y2 = new DirectValueTreeItem(null, 0, (Long) 0L, new ArrayList()); + y1 = new DirectValueTreeItem(null, 0, (Long) 0L, new ArrayList()); + } } else { lexer.pushback(s); - ret.add(new ActionPush(Boolean.FALSE)); + constrain = new DirectValueTreeItem(null, 0, Boolean.FALSE, new ArrayList()); + //ret.add(new ActionPush(Boolean.FALSE)); } } else { - ret.add(new ActionPush(Boolean.FALSE)); - ret.add(new ActionPush(Boolean.FALSE)); + lockCenter = new DirectValueTreeItem(null, 0, Boolean.FALSE, new ArrayList()); + constrain = new DirectValueTreeItem(null, 0, Boolean.FALSE, new ArrayList()); lexer.pushback(s); } expectedType(SymbolType.PARENT_CLOSE); - ret.add(new ActionStartDrag()); + ret = new StartDragTreeItem(null, dragTarget, lockCenter, constrain, x1, y1, x2, y2); break; case IFFRAMELOADED: expectedType(SymbolType.PARENT_OPEN); - ret.addAll(expression(registerVars, inFunction, inMethod, true)); + GraphTargetItem iflExpr = (expression(registerVars, inFunction, inMethod, true)); expectedType(SymbolType.PARENT_CLOSE); expectedType(SymbolType.CURLY_OPEN); - List iflComs = commands(registerVars, inFunction, inMethod, forinlevel); + List iflComs = commands(registerVars, inFunction, inMethod, forinlevel); expectedType(SymbolType.CURLY_CLOSE); - ret.add(new ActionWaitForFrame2(iflComs.size())); - ret.addAll(iflComs); + ret = new IfFrameLoadedTreeItem(iflExpr, iflComs, null); break; case CLASS: - List classTypeStr = type(); + GraphTargetItem classTypeStr = type(); s = lex(); - List extendsTypeStr = new ArrayList<>(); + GraphTargetItem extendsTypeStr = null; if (s.type == SymbolType.EXTENDS) { extendsTypeStr = type(); s = lex(); } - List> implementsTypeStrs = new ArrayList<>(); + List implementsTypeStrs = new ArrayList<>(); if (s.type == SymbolType.IMPLEMENTS) { do { - List implementsTypeStr = type(); + GraphTargetItem implementsTypeStr = type(); implementsTypeStrs.add(implementsTypeStr); s = lex(); } while (s.type == SymbolType.COMMA); } expected(s, lexer.yyline(), SymbolType.CURLY_OPEN); - ret.addAll(traits(false, classTypeStr, extendsTypeStr, implementsTypeStrs)); + ret = (traits(false, classTypeStr, extendsTypeStr, implementsTypeStrs)); expectedType(SymbolType.CURLY_CLOSE); break; case INTERFACE: - List interfaceTypeStr = type(); + GraphTargetItem interfaceTypeStr = type(); s = lex(); - List> intExtendsTypeStrs = new ArrayList<>(); + List intExtendsTypeStrs = new ArrayList<>(); if (s.type == SymbolType.EXTENDS) { do { - List intExtendsTypeStr = type(); + GraphTargetItem intExtendsTypeStr = type(); intExtendsTypeStrs.add(intExtendsTypeStr); s = lex(); } while (s.type == SymbolType.COMMA); } expected(s, lexer.yyline(), SymbolType.CURLY_OPEN); - ret.addAll(traits(true, interfaceTypeStr, new ArrayList(), intExtendsTypeStrs)); + ret = (traits(true, interfaceTypeStr, null, intExtendsTypeStrs)); expectedType(SymbolType.CURLY_CLOSE); break; case FUNCTION: s = lexer.lex(); expected(s, lexer.yyline(), SymbolType.IDENTIFIER); - ret.addAll(function(true, s.value.toString(), false)); + ret = (function(true, s.value.toString(), false)); break; case NEW: - List newcmds = new ArrayList<>(); - newcmds.addAll(typeToActions(type(), null)); + GraphTargetItem type = type(); expectedType(SymbolType.PARENT_OPEN); - if (newcmds.get(newcmds.size() - 1) instanceof ActionGetMember) { - newcmds.remove(newcmds.size() - 1); - newcmds.addAll(0, call(registerVars, inFunction, inMethod)); - newcmds.add(new ActionNewMethod()); - } else if (newcmds.get(newcmds.size() - 1) instanceof ActionGetVariable) { - newcmds.remove(newcmds.size() - 1); - newcmds.addAll(0, call(registerVars, inFunction, inMethod)); - newcmds.add(new ActionNewObject()); + if (type instanceof GetMemberTreeItem) { + GetMemberTreeItem mem = (GetMemberTreeItem) type; + ret = new NewMethodTreeItem(null, mem.object, mem.memberName, call(registerVars, inFunction, inMethod)); + } else if (type instanceof GetVariableTreeItem) { + GetVariableTreeItem var = (GetVariableTreeItem) type; + ret = new NewObjectTreeItem(null, var.name, call(registerVars, inFunction, inMethod)); + } else { + ret = new NewObjectTreeItem(null, ret, call(registerVars, inFunction, inMethod)); } - ret.addAll(newcmds); break; case VAR: s = lex(); @@ -1133,61 +981,58 @@ public class ActionScriptParser { } if (s.type == SymbolType.ASSIGN) { + if (!inFunction) { - ret.add(pushConst(varIdentifier)); + //ret.add(pushConst(varIdentifier)); } - ret.addAll(expression(registerVars, inFunction, inMethod, true)); + GraphTargetItem varval = (expression(registerVars, inFunction, inMethod, true)); if (inFunction) { for (int i = 1; i < 256; i++) { if (!registerVars.containsValue(i)) { registerVars.put(varIdentifier, i); - ret.add(new ActionStoreRegister(i)); - ret.add(new ActionPop()); + ret = new StoreRegisterTreeItem(null, new RegisterNumber(i), varval, true); break; } } } else { - ret.add(new ActionDefineLocal()); + ret = new DefineLocalTreeItem(null, pushConst(varIdentifier), varval); } } else { if (inFunction) { for (int i = 1; i < 256; i++) { if (!registerVars.containsValue(i)) { registerVars.put(varIdentifier, i); + ret = new DefineRegisterTreeItem(varIdentifier, i); break; } } } else { - ret.add(pushConst(varIdentifier)); - ret.add(new ActionDefineLocal2()); + ret = new DefineLocalTreeItem(null, pushConst(varIdentifier), null); } lexer.pushback(s); } break; case CURLY_OPEN: - ret.addAll(commands(registerVars, inFunction, inMethod, forinlevel)); + ret = new BlockItem(null, commands(registerVars, inFunction, inMethod, forinlevel)); expectedType(SymbolType.CURLY_CLOSE); break; - case INCREMENT: - case DECREMENT: - List varincdec = variable(registerVars, inFunction, inMethod); - List incdecval = new ArrayList<>(); - incdecval.addAll(varincdec); + case INCREMENT: //preincrement + case DECREMENT: //predecrement + GraphTargetItem varincdec = variable(registerVars, inFunction, inMethod); if (s.type == SymbolType.INCREMENT) { - incdecval.add(new ActionIncrement()); + ret = new PreIncrementTreeItem(null, varincdec); } else if (s.type == SymbolType.DECREMENT) { - incdecval.add(new ActionDecrement()); + ret = new PreDecrementTreeItem(null, varincdec); } - varincdec = gettoset(varincdec, incdecval); - ret.addAll(varincdec); break; case IDENTIFIER: case THIS: case SUPER: case PARENT_OPEN: case EVAL: + ParsedSymbol varS = s; boolean isEval = false; - List var; + GraphTargetItem var; if (s.type == SymbolType.PARENT_OPEN) { var = expression(registerVars, inFunction, inMethod, true); expectedType(SymbolType.PARENT_CLOSE); @@ -1195,9 +1040,9 @@ public class ActionScriptParser { } else if (s.type == SymbolType.EVAL) { expectedType(SymbolType.PARENT_OPEN); var = expression(registerVars, inFunction, inMethod, true); - var.add(new ActionGetVariable()); + var = new EvalTreeItem(null, var); expectedType(SymbolType.PARENT_CLOSE); - memberOrCall(var, registerVars, inFunction, inMethod); + var = memberOrCall(var, registerVars, inFunction, inMethod); isEval = true; } else { lexer.pushback(s); @@ -1206,8 +1051,8 @@ public class ActionScriptParser { s = lex(); switch (s.type) { case ASSIGN: - ret.addAll(var); - ret = gettoset(ret, expression(registerVars, inFunction, inMethod, true)); + ret = var; + ret = Action.gettoset(ret, expression(registerVars, inFunction, inMethod, true)); break; case ASSIGN_BITAND: case ASSIGN_BITOR: @@ -1220,140 +1065,99 @@ public class ActionScriptParser { case ASSIGN_SHIFT_RIGHT: case ASSIGN_USHIFT_RIGHT: case ASSIGN_XOR: - List varset = new ArrayList<>(); - varset.addAll(var); - var.addAll(expression(registerVars, inFunction, inMethod, true)); + GraphTargetItem valtoappend = (expression(registerVars, inFunction, inMethod, true)); + switch (s.type) { case ASSIGN_BITAND: - var.add(new ActionBitAnd()); + ret = Action.gettoset(var, new BitAndTreeItem(null, var, valtoappend)); break; case ASSIGN_BITOR: - var.add(new ActionBitOr()); + ret = Action.gettoset(var, new BitOrTreeItem(null, var, valtoappend)); break; case ASSIGN_DIVIDE: - var.add(new ActionDivide()); + ret = Action.gettoset(var, new DivideTreeItem(null, var, valtoappend)); break; case ASSIGN_MINUS: - var.add(new ActionSubtract()); + ret = Action.gettoset(var, new SubtractTreeItem(null, var, valtoappend)); break; case ASSIGN_MODULO: - var.add(new ActionModulo()); + ret = Action.gettoset(var, new ModuloTreeItem(null, var, valtoappend)); break; case ASSIGN_MULTIPLY: - var.add(new ActionMultiply()); + ret = Action.gettoset(var, new MultiplyTreeItem(null, var, valtoappend)); break; case ASSIGN_PLUS: - var.add(new ActionAdd()); + ret = Action.gettoset(var, new AddTreeItem(null, var, valtoappend, true)); break; } - varset = gettoset(varset, var); - ret.addAll(varset); break; - case INCREMENT: - case DECREMENT: - ret.addAll(var); - List val = new ArrayList<>(); - val.addAll(var); - - if (s.type == SymbolType.INCREMENT) { - val.add(new ActionIncrement()); - } - if (s.type == SymbolType.DECREMENT) { - val.add(new ActionDecrement()); - } - ret = gettoset(ret, val); + case INCREMENT: //postincrement + ret = new PostIncrementTreeItem(null, var); + break; + case DECREMENT: //postdecrement + ret = new PostDecrementTreeItem(null, var); break; case PARENT_OPEN: //function call - lexer.pushback(s); - ret.addAll(var); - memberOrCall(ret, registerVars, inFunction, inMethod); - ret.add(new ActionPop()); + ret = var; + if (varS.type == SymbolType.SUPER || varS.type == SymbolType.THIS) { + List args = call(registerVars, inFunction, inMethod); + ret = new CallMethodTreeItem(null, ret, new DirectValueTreeItem(null, 0, new Undefined(), constantPool), args); + } else { + lexer.pushback(s); + ret = memberOrCall(ret, registerVars, inFunction, inMethod); + } break; default: - if (!isEval) { - throw new ParseException("Not a command", lexer.yyline()); + if (isEval) { + ret = var; + } else { + if (mustBeCommand) { + throw new ParseException("Not a command", lexer.yyline()); + } } } break; case IF: expectedType(SymbolType.PARENT_OPEN); - ret.addAll(expression(registerVars, inFunction, inMethod, true)); + GraphTargetItem ifExpr = (expression(registerVars, inFunction, inMethod, true)); expectedType(SymbolType.PARENT_CLOSE); - List onTrue = command(registerVars, inFunction, inMethod, forinlevel); - List onFalse = null; + GraphTargetItem onTrue = command(registerVars, inFunction, inMethod, forinlevel, true); + List onTrueList = new ArrayList<>(); + onTrueList.add(onTrue); s = lex(); + List onFalseList = null; if (s.type == SymbolType.ELSE) { - onFalse = command(registerVars, inFunction, inMethod, forinlevel); + onFalseList = new ArrayList<>(); + onFalseList.add(command(registerVars, inFunction, inMethod, forinlevel, true)); } else { lexer.pushback(s); } - byte onTrueBytes[] = Action.actionsToBytes(onTrue, false, SWF.DEFAULT_VERSION); - int onTrueLen = onTrueBytes.length; - ret.add(new ActionNot()); - ActionIf ifaif = new ActionIf(0); - ret.add(ifaif); - ret.addAll(onTrue); - ifaif.setJumpOffset(onTrueLen); - ActionJump ajmp = null; - if (onFalse != null) { - if (!((!nonempty(onTrue).isEmpty()) - && (onTrue.get(onTrue.size() - 1) instanceof ActionJump) - && ((((ActionJump) onTrue.get(onTrue.size() - 1)).isContinue) - || (((ActionJump) onTrue.get(onTrue.size() - 1)).isBreak)))) { - ajmp = new ActionJump(0); - ret.add(ajmp); - onTrueLen += ajmp.getBytes(SWF.DEFAULT_VERSION).length; - } - ifaif.setJumpOffset(onTrueLen); - byte onFalseBytes[] = Action.actionsToBytes(onFalse, false, SWF.DEFAULT_VERSION); - int onFalseLen = onFalseBytes.length; - if (ajmp != null) { - ajmp.setJumpOffset(onFalseLen); - } - ret.addAll(onFalse); - } + ret = new IfItem(null, ifExpr, onTrueList, onFalseList); break; case WHILE: expectedType(SymbolType.PARENT_OPEN); - List whileExpr = expression(registerVars, inFunction, inMethod, true); + List whileExpr = new ArrayList<>(); + whileExpr.add(commaExpression(registerVars, inFunction, inMethod, forinlevel)); expectedType(SymbolType.PARENT_CLOSE); - List whileBody = command(registerVars, inFunction, inMethod, forinlevel); - whileExpr.add(new ActionNot()); - ActionIf whileaif = new ActionIf(0); - whileExpr.add(whileaif); - ActionJump whileajmp = new ActionJump(0); - whileBody.add(whileajmp); - int whileExprLen = Action.actionsToBytes(whileExpr, false, SWF.DEFAULT_VERSION).length; - int whileBodyLen = Action.actionsToBytes(whileBody, false, SWF.DEFAULT_VERSION).length; - whileajmp.setJumpOffset(-(whileExprLen - + whileBodyLen)); - whileaif.setJumpOffset(whileBodyLen); - ret.addAll(whileExpr); - fixLoop(whileBody, whileBodyLen, -whileExprLen); - ret.addAll(whileBody); + List whileBody = new ArrayList<>(); + whileBody.add(command(registerVars, inFunction, inMethod, forinlevel, true)); + ret = new WhileItem(null, null, whileExpr, whileBody); break; case DO: - List doBody = command(registerVars, inFunction, inMethod, forinlevel); + List doBody = new ArrayList<>(); + doBody.add(command(registerVars, inFunction, inMethod, forinlevel, true)); expectedType(SymbolType.WHILE); expectedType(SymbolType.PARENT_OPEN); - List doExpr = expression(registerVars, inFunction, inMethod, true); - + List doExpr = new ArrayList<>(); + doExpr.add(commaExpression(registerVars, inFunction, inMethod, forinlevel)); expectedType(SymbolType.PARENT_CLOSE); - int doBodyLen = Action.actionsToBytes(doBody, false, SWF.DEFAULT_VERSION).length; - int doExprLen = Action.actionsToBytes(doExpr, false, SWF.DEFAULT_VERSION).length; - - ret.addAll(doBody); - ret.addAll(doExpr); - ActionIf doif = new ActionIf(0); - ret.add(doif); - doif.setJumpOffset(-doBodyLen - doExprLen - doif.getBytes(SWF.DEFAULT_VERSION).length); - fixLoop(doBody, doBodyLen + doExprLen + doif.getBytes(SWF.DEFAULT_VERSION).length, doBodyLen); + ret = new DoWhileItem(null, null, doBody, doExpr); break; case FOR: expectedType(SymbolType.PARENT_OPEN); s = lex(); boolean forin = false; - List collection = new ArrayList<>(); + GraphTargetItem collection = null; String objIdent = null; int innerExprReg = 0; if (s.type == SymbolType.VAR || s.type == SymbolType.IDENTIFIER) { @@ -1396,79 +1200,31 @@ public class ActionScriptParser { } else { lexer.pushback(s); } - List forFinalCommands = new ArrayList<>(); - List forExpr = new ArrayList<>(); + List forFinalCommands = new ArrayList<>(); + GraphTargetItem forExpr = null; + List forFirstCommands = new ArrayList<>(); if (!forin) { - ret.addAll(nonempty(command(registerVars, inFunction, inMethod, forinlevel))); - forExpr = expression(registerVars, inFunction, inMethod, true); + forFirstCommands.add((command(registerVars, inFunction, inMethod, forinlevel, true))); + forExpr = (expression(registerVars, inFunction, inMethod, true)); expectedType(SymbolType.SEMICOLON); - forFinalCommands = command(registerVars, inFunction, inMethod, forinlevel); + forFinalCommands.add(command(registerVars, inFunction, inMethod, forinlevel, true)); } expectedType(SymbolType.PARENT_CLOSE); - List forBody = command(registerVars, inFunction, inMethod, forin ? forinlevel + 1 : forinlevel); + List forBody = new ArrayList<>(); + forBody.add(command(registerVars, inFunction, inMethod, forin ? forinlevel + 1 : forinlevel, true)); if (forin) { - ret.addAll(collection); - ret.add(new ActionEnumerate2()); - List loopExpr = new ArrayList<>(); - int exprReg = 0; - for (int i = 0; i < 256; i++) { - if (!registerVars.containsValue(i)) { - registerVars.put("__forin" + uniqId(), i); - exprReg = i; - break; - } - } - - - loopExpr.add(new ActionStoreRegister(exprReg)); - loopExpr.add(new ActionPush(new Null())); - loopExpr.add(new ActionEquals2()); - ActionIf forInEndIf = new ActionIf(0); - loopExpr.add(forInEndIf); - List loopBody = new ArrayList<>(); - loopBody.add(new ActionPush(new RegisterNumber(exprReg))); - if (inFunction) { - loopBody.add(new ActionStoreRegister(innerExprReg)); - loopBody.add(new ActionPop()); - } else { - loopBody.add(0, pushConst(objIdent)); - loopBody.add(new ActionSetVariable()); - } - loopBody.addAll(forBody); - ActionJump forinJmpBack = new ActionJump(0); - loopBody.add(forinJmpBack); - int bodyLen = Action.actionsToBytes(loopBody, false, SWF.DEFAULT_VERSION).length; - int exprLen = Action.actionsToBytes(loopExpr, false, SWF.DEFAULT_VERSION).length; - forinJmpBack.setJumpOffset(-bodyLen - exprLen); - forInEndIf.setJumpOffset(bodyLen); - ret.addAll(loopExpr); - ret.addAll(loopBody); + ret = new ForInTreeItem(null, null, pushConst(objIdent), collection, forBody); } else { - forExpr.add(new ActionNot()); - ActionIf foraif = new ActionIf(0); - forExpr.add(foraif); - ActionJump forajmp = new ActionJump(0); - int forajmpLen = forajmp.getBytes(SWF.DEFAULT_VERSION).length; - int forExprLen = Action.actionsToBytes(forExpr, false, SWF.DEFAULT_VERSION).length; - int forBodyLen = Action.actionsToBytes(forBody, false, SWF.DEFAULT_VERSION).length; - int forFinalLen = Action.actionsToBytes(forFinalCommands, false, SWF.DEFAULT_VERSION).length; - forajmp.setJumpOffset(-(forExprLen - + forBodyLen + forFinalLen + forajmpLen)); - foraif.setJumpOffset(forBodyLen + forFinalLen + forajmpLen); - ret.addAll(forExpr); - ret.addAll(forBody); - ret.addAll(forFinalCommands); - ret.add(forajmp); - fixLoop(forBody, forBodyLen + forFinalLen + forajmpLen, forBodyLen); + ret = new ForItem(null, null, forFirstCommands, forExpr, forFinalCommands, forBody); } break; case SWITCH: expectedType(SymbolType.PARENT_OPEN); - List switchExpr = expression(registerVars, inFunction, inMethod, true); + GraphTargetItem switchExpr = expression(registerVars, inFunction, inMethod, true); expectedType(SymbolType.PARENT_CLOSE); expectedType(SymbolType.CURLY_OPEN); s = lex(); - ret.addAll(switchExpr); + //ret.addAll(switchExpr); int exprReg = 0; for (int i = 0; i < 256; i++) { if (!registerVars.containsValue(i)) { @@ -1477,178 +1233,89 @@ public class ActionScriptParser { break; } } - boolean firstCase = true; List> caseIfs = new ArrayList<>(); - List> caseCmds = new ArrayList<>(); - List>> caseExprsAll = new ArrayList<>(); + List> caseCmds = new ArrayList<>(); + List caseExprsAll = new ArrayList<>(); + List valueMapping = new ArrayList<>(); + int pos = 0; while (s.type == SymbolType.CASE) { - List> caseExprs = new ArrayList<>(); - List caseIfsOne = new ArrayList<>(); + List caseExprs = new ArrayList<>(); while (s.type == SymbolType.CASE) { - List curCaseExpr = expression(registerVars, inFunction, inMethod, true); + GraphTargetItem curCaseExpr = expression(registerVars, inFunction, inMethod, true); caseExprs.add(curCaseExpr); - if (firstCase) { - curCaseExpr.add(0, new ActionStoreRegister(exprReg)); - } else { - curCaseExpr.add(0, new ActionPush(new RegisterNumber(exprReg))); - } - curCaseExpr.add(new ActionStrictEquals()); - ActionIf aif = new ActionIf(0); - caseIfsOne.add(aif); - curCaseExpr.add(aif); - ret.addAll(curCaseExpr); - firstCase = false; expectedType(SymbolType.COLON); s = lex(); + caseExprsAll.add(curCaseExpr); + valueMapping.add(pos); } - caseExprsAll.add(caseExprs); - caseIfs.add(caseIfsOne); + pos++; lexer.pushback(s); - List caseCmd = commands(registerVars, inFunction, inMethod, forinlevel); + List caseCmd = commands(registerVars, inFunction, inMethod, forinlevel); caseCmds.add(caseCmd); s = lex(); } - ActionJump defJump = new ActionJump(0); - ret.add(defJump); - List defCmd = new ArrayList<>(); + List defCmd = new ArrayList<>(); if (s.type == SymbolType.DEFAULT) { expectedType(SymbolType.COLON); defCmd = commands(registerVars, inFunction, inMethod, forinlevel); s = lexer.lex(); } - for (List caseCmd : caseCmds) { - ret.addAll(caseCmd); - } - ret.addAll(defCmd); - - List> exprLengths = new ArrayList<>(); - for (List> caseExprs : caseExprsAll) { - List lengths = new ArrayList<>(); - for (List caseExpr : caseExprs) { - lengths.add(Action.actionsToBytes(caseExpr, false, SWF.DEFAULT_VERSION).length); - } - exprLengths.add(lengths); - } - List caseLengths = new ArrayList<>(); - for (List caseCmd : caseCmds) { - caseLengths.add(Action.actionsToBytes(caseCmd, false, SWF.DEFAULT_VERSION).length); - } - int defLength = Action.actionsToBytes(defCmd, false, SWF.DEFAULT_VERSION).length; - - for (int i = 0; i < caseIfs.size(); i++) { - for (int c = 0; c < caseIfs.get(i).size(); c++) { - int jmpPos = 0; - for (int j = c + 1; j < caseIfs.get(i).size(); j++) { - jmpPos += exprLengths.get(i).get(j); - } - for (int k = i + 1; k < caseIfs.size(); k++) { - for (int m = 0; m < caseIfs.get(k).size(); m++) { - jmpPos += exprLengths.get(k).get(m); - } - } - jmpPos += defJump.getBytes(SWF.DEFAULT_VERSION).length; - for (int n = 0; n < i; n++) { - jmpPos += caseLengths.get(n); - } - caseIfs.get(i).get(c).setJumpOffset(jmpPos); - } - } - int defJmpPos = 0; - for (int i = 0; i < caseIfs.size(); i++) { - defJmpPos += caseLengths.get(i); - } - - defJump.setJumpOffset(defJmpPos); - List caseCmdsAll = new ArrayList<>(); - int breakOffset = 0; - for (int i = 0; i < caseCmds.size(); i++) { - caseCmdsAll.addAll(caseCmds.get(i)); - breakOffset += caseLengths.get(i); - } - breakOffset += defLength; - fixLoop(caseCmdsAll, breakOffset); - expected(s, lexer.yyline(), SymbolType.CURLY_CLOSE); + ret = new SwitchItem(null, null, switchExpr, caseExprsAll, caseCmds, defCmd, valueMapping); break; case BREAK: - ActionJump abreak = new ActionJump(0); - abreak.isBreak = true; - ret.add(abreak); + ret = new BreakItem(null, 0); //? There is no more than 1 level continue/break in AS1/2 break; case CONTINUE: - ActionJump acontinue = new ActionJump(0); - acontinue.isContinue = true; - ret.add(acontinue); + ret = new ContinueItem(null, 0); //? There is no more than 1 level continue/break in AS1/2 break; case RETURN: - for (int i = 0; i < forinlevel; i++) { - List forinret = new ArrayList<>(); - forinret.add(new ActionPush(new Null())); - forinret.add(new ActionEquals2()); - forinret.add(new ActionNot()); - ActionIf aforinif = new ActionIf(0); - forinret.add(aforinif); - aforinif.setJumpOffset(-Action.actionsToBytes(forinret, false, SWF.DEFAULT_VERSION).length); - ret.addAll(forinret); + GraphTargetItem retexpr = expression(true, registerVars, inFunction, inMethod, true); + if (retexpr == null) { + retexpr = new DirectValueTreeItem(null, 0, new Undefined(), new ArrayList()); } - List retexpr = expression(true, registerVars, inFunction, inMethod, true); - ret.addAll(retexpr); - if (retexpr.isEmpty()) { - ret.add(new ActionPush(new Undefined())); - } - ret.add(new ActionReturn()); + ret = new ReturnTreeItem(null, retexpr); break; case TRY: - List tryCommands = command(registerVars, inFunction, inMethod, forinlevel); + List tryCommands = new ArrayList<>(); + tryCommands.add(command(registerVars, inFunction, inMethod, forinlevel, true)); s = lex(); boolean found = false; - List catchCommands = null; - String catchName = null; - int catchSize = 0; + List> catchCommands = null; + List catchExceptions = new ArrayList<>(); if (s.type == SymbolType.CATCH) { expectedType(SymbolType.PARENT_OPEN); s = lex(); - expected(s, lexer.yyline(), SymbolType.IDENTIFIER); - catchName = s.value.toString(); + expected(s, lexer.yyline(), SymbolType.IDENTIFIER, SymbolType.STRING); + catchExceptions.add(pushConst((String) s.value)); expectedType(SymbolType.PARENT_CLOSE); - catchCommands = command(registerVars, inFunction, inMethod, forinlevel); + catchCommands = new ArrayList<>(); + List cc = new ArrayList<>(); + cc.add(command(registerVars, inFunction, inMethod, forinlevel, true)); + catchCommands.add(cc); s = lex(); found = true; - catchSize = Action.actionsToBytes(catchCommands, false, SWF.DEFAULT_VERSION).length; - tryCommands.add(new ActionJump(catchSize)); } - List finallyCommands = null; - int finallySize = 0; + List finallyCommands = null; if (s.type == SymbolType.FINALLY) { - finallyCommands = command(registerVars, inFunction, inMethod, forinlevel); + finallyCommands = new ArrayList<>(); + finallyCommands.add(command(registerVars, inFunction, inMethod, forinlevel, true)); found = true; s = lex(); - finallySize = Action.actionsToBytes(finallyCommands, false, SWF.DEFAULT_VERSION).length; } if (!found) { expected(s, lexer.yyline(), SymbolType.CATCH, SymbolType.FINALLY); } lexer.pushback(s); - int trySize = Action.actionsToBytes(tryCommands, false, SWF.DEFAULT_VERSION).length; - - ret.add(new ActionTry(false, finallyCommands != null, catchCommands != null, catchName, 0, trySize, catchSize, finallySize, SWF.DEFAULT_VERSION)); - ret.addAll(tryCommands); - if (catchCommands != null) { - ret.addAll(catchCommands); - } - if (finallyCommands != null) { - ret.addAll(finallyCommands); - } + ret = new TryTreeItem(tryCommands, catchExceptions, catchCommands, finallyCommands); break; case THROW: - ret.addAll(expression(registerVars, inFunction, inMethod, true)); - ret.add(new ActionThrow()); + ret = new ThrowTreeItem(null, expression(registerVars, inFunction, inMethod, true)); break; default: - List valcmd = expressionCommands(s, registerVars, inFunction, inMethod, forinlevel); + GraphTargetItem valcmd = expressionCommands(s, registerVars, inFunction, inMethod, forinlevel); if (valcmd != null) { - ret.addAll(valcmd); - ret.add(new ActionPop()); + ret = valcmd; break; } if (s.type != SymbolType.SEMICOLON) { @@ -1666,139 +1333,108 @@ public class ActionScriptParser { if (debugMode) { System.out.println("/command"); } + if (ret == null && (!mustBeCommand)) { + buf.pushAllBack(lexer); + } + lexer.removeListener(buf); return ret; } - private List expression(HashMap registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder) throws IOException, ParseException { + private GraphTargetItem expression(HashMap registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder) throws IOException, ParseException { return expression(false, registerVars, inFunction, inMethod, allowRemainder); } - private List expressionRemainder(HashMap registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder) throws IOException, ParseException { - return expressionRemainder(new ArrayList(), registerVars, inFunction, inMethod, allowRemainder); + /*private List expressionRemainder(GraphTargetItem expr, HashMap registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder) throws IOException, ParseException { + return expressionRemainder(null, registerVars, inFunction, inMethod, allowRemainder); + }*/ + private GraphTargetItem fixPrecedence(GraphTargetItem expr) { + GraphTargetItem ret = expr; + if (expr instanceof BinaryOp) { + BinaryOp bo = (BinaryOp) expr; + GraphTargetItem left = bo.getLeftSide(); + //GraphTargetItem right=bo.getRightSide(); + if (left.getPrecedence() > bo.getPrecedence()) { + if (left instanceof BinaryOp) { + BinaryOp leftBo = (BinaryOp) left; + bo.setLeftSide(leftBo.getRightSide()); + leftBo.setRightSide(expr); + return left; + } + } + } + return ret; } - private List expressionRemainder(List expr, HashMap registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder) throws IOException, ParseException { - List ret = new ArrayList<>(); + private GraphTargetItem expressionRemainder(GraphTargetItem expr, HashMap registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder) throws IOException, ParseException { + GraphTargetItem ret = null; ParsedSymbol s = lex(); switch (s.type) { case TERNAR: - List terOnTrue = expression(registerVars, inFunction, inMethod, true); + GraphTargetItem terOnTrue = expression(registerVars, inFunction, inMethod, false); expectedType(SymbolType.COLON); - List terOnFalse = expression(registerVars, inFunction, inMethod, true); - ret.add(new ActionNot()); - ActionIf ifter = new ActionIf(0); - ret.add(ifter); - ActionJump jmpter = new ActionJump(0); - terOnTrue.add(jmpter); - int terOnTrueLen = Action.actionsToBytes(terOnTrue, false, SWF.DEFAULT_VERSION).length; - int terOnFalseLen = Action.actionsToBytes(terOnFalse, false, SWF.DEFAULT_VERSION).length; - ifter.setJumpOffset(terOnTrueLen); - jmpter.setJumpOffset(terOnFalseLen); - ret.addAll(terOnTrue); - ret.addAll(terOnFalse); + GraphTargetItem terOnFalse = expression(registerVars, inFunction, inMethod, false); + ret = new TernarOpItem(null, expr, terOnTrue, terOnFalse); break; case BITAND: - ret.addAll(expression(registerVars, inFunction, inMethod, allowRemainder)); - ret.add(new ActionBitAnd()); + ret = new BitAndTreeItem(null, expr, expression(registerVars, inFunction, inMethod, false)); break; case BITOR: - ret.addAll(expression(registerVars, inFunction, inMethod, allowRemainder)); - ret.add(new ActionBitOr()); + ret = new BitOrTreeItem(null, expr, expression(registerVars, inFunction, inMethod, false)); break; case DIVIDE: - ret.addAll(expression(registerVars, inFunction, inMethod, allowRemainder)); - ret.add(new ActionDivide()); + ret = new DivideTreeItem(null, expr, expression(registerVars, inFunction, inMethod, false)); break; case MODULO: - ret.addAll(expression(registerVars, inFunction, inMethod, allowRemainder)); - ret.add(new ActionModulo()); + ret = new ModuloTreeItem(null, expr, expression(registerVars, inFunction, inMethod, false)); break; case EQUALS: - ret.addAll(expression(registerVars, inFunction, inMethod, allowRemainder)); - ret.add(new ActionEquals2()); + ret = new EqTreeItem(null, expr, expression(registerVars, inFunction, inMethod, false), true/*FIXME SWF version?*/); break; case STRICT_EQUALS: - ret.addAll(expression(registerVars, inFunction, inMethod, allowRemainder)); - ret.add(new ActionStrictEquals()); + ret = new StrictEqTreeItem(null, expr, expression(registerVars, inFunction, inMethod, false)); break; case NOT_EQUAL: - ret.addAll(expression(registerVars, inFunction, inMethod, allowRemainder)); - ret.add(new ActionEquals2()); - ret.add(new ActionNot()); + ret = new NeqTreeItem(null, expr, expression(registerVars, inFunction, inMethod, false), true/*FIXME SWF version?*/); break; case STRICT_NOT_EQUAL: - ret.addAll(expression(registerVars, inFunction, inMethod, allowRemainder)); - ret.add(new ActionStrictEquals()); - ret.add(new ActionNot()); + ret = new StrictNeqTreeItem(null, expr, expression(registerVars, inFunction, inMethod, false)); break; case LOWER_THAN: - ret.addAll(expression(registerVars, inFunction, inMethod, allowRemainder)); - ret.add(new ActionLess2()); + ret = new LtTreeItem(null, expr, expression(registerVars, inFunction, inMethod, false), true/*FIXME SWF version?*/); break; case LOWER_EQUAL: - ret.addAll(expression(registerVars, inFunction, inMethod, allowRemainder)); - ret.add(new ActionGreater()); - ret.add(new ActionNot()); + ret = new LeTreeItem(null, expr, expression(registerVars, inFunction, inMethod, false)); break; case GREATER_THAN: - ret.addAll(expression(registerVars, inFunction, inMethod, allowRemainder)); - ret.add(new ActionGreater()); + ret = new GtTreeItem(null, expr, expression(registerVars, inFunction, inMethod, false)); break; case GREATER_EQUAL: - ret.addAll(expression(registerVars, inFunction, inMethod, allowRemainder)); - ret.add(new ActionLess2()); - ret.add(new ActionNot()); + ret = new GeTreeItem(null, expr, expression(registerVars, inFunction, inMethod, false), true/*FIXME SWF version?*/); break; case AND: - ret.add(new ActionPushDuplicate()); - ret.add(new ActionNot()); - List andExpr = expression(registerVars, inFunction, inMethod, true); - andExpr.add(0, new ActionPop()); - int andExprLen = Action.actionsToBytes(andExpr, false, SWF.DEFAULT_VERSION).length; - ret.add(new ActionIf(andExprLen)); - ret.addAll(andExpr); + ret = new AndItem(null, expr, expression(registerVars, inFunction, inMethod, false)); break; case OR: - ret.add(new ActionPushDuplicate()); - List orExpr = expression(registerVars, inFunction, inMethod, true); - orExpr.add(0, new ActionPop()); - int orExprLen = Action.actionsToBytes(orExpr, false, SWF.DEFAULT_VERSION).length; - ret.add(new ActionIf(orExprLen)); - ret.addAll(orExpr); + ret = new OrItem(null, expr, expression(registerVars, inFunction, inMethod, false)); break; case MINUS: - List minusExp = expression(registerVars, inFunction, inMethod, allowRemainder); - if ((minusExp.size() == 1) && (minusExp.get(0) instanceof ActionPush) && (((ActionPush) minusExp.get(0)).values.get(0).equals(new Long(1)))) { - ret.add(new ActionDecrement()); - } else { - ret.addAll(minusExp); - ret.add(new ActionSubtract()); - } + ret = new SubtractTreeItem(null, expr, expression(registerVars, inFunction, inMethod, false)); break; case MULTIPLY: - ret.addAll(expression(registerVars, inFunction, inMethod, allowRemainder)); - ret.add(new ActionMultiply()); + ret = new MultiplyTreeItem(null, expr, expression(registerVars, inFunction, inMethod, false)); break; case PLUS: - List plusExp = expression(registerVars, inFunction, inMethod, allowRemainder); - if ((plusExp.size() == 1) && (plusExp.get(0) instanceof ActionPush) && (((ActionPush) plusExp.get(0)).values.get(0).equals(new Long(1)))) { - ret.add(new ActionIncrement()); - } else { - ret.addAll(plusExp); - ret.add(new ActionAdd2()); - } + ret = new AddTreeItem(null, expr, expression(registerVars, inFunction, inMethod, false), true); break; case XOR: - ret.addAll(expression(registerVars, inFunction, inMethod, allowRemainder)); - ret.add(new ActionBitXor()); + ret = new BitXorTreeItem(null, expr, expression(registerVars, inFunction, inMethod, false)); break; case AS: break; case INSTANCEOF: - ret.addAll(expression(registerVars, inFunction, inMethod, allowRemainder)); - ret.add(new ActionInstanceOf()); + ret = new InstanceOfTreeItem(null, expr, expression(registerVars, inFunction, inMethod, false)); break; case IS: @@ -1806,10 +1442,11 @@ public class ActionScriptParser { default: lexer.pushback(s); } + ret = fixPrecedence(ret); return ret; } - private int brackets(List ret, HashMap registerVars, boolean inFunction, boolean inMethod) throws IOException, ParseException { + private int brackets(List ret, HashMap registerVars, boolean inFunction, boolean inMethod) throws IOException, ParseException { ParsedSymbol s = lex(); int arrCnt = 0; if (s.type == SymbolType.BRACKET_OPEN) { @@ -1820,7 +1457,7 @@ public class ActionScriptParser { lexer.pushback(s); } arrCnt++; - ret.addAll(expression(registerVars, inFunction, inMethod, true)); + ret.add(expression(registerVars, inFunction, inMethod, true)); s = lex(); if (!s.isType(SymbolType.COMMA, SymbolType.BRACKET_CLOSE)) { expected(s, lexer.yyline(), SymbolType.COMMA, SymbolType.BRACKET_CLOSE); @@ -1833,86 +1470,104 @@ public class ActionScriptParser { return arrCnt; } - private List expression(boolean allowEmpty, HashMap registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder) throws IOException, ParseException { + private GraphTargetItem commaExpression(HashMap registerVars, boolean inFunction, boolean inMethod, int forInLevel) throws IOException, ParseException { + GraphTargetItem cmd = null; + List expr = new ArrayList<>(); + ParsedSymbol s; + do { + cmd = command(registerVars, inFunction, inMethod, forInLevel, false); + if (cmd != null) { + expr.add(cmd); + } + s = lex(); + } while (s.type == SymbolType.COMMA && cmd != null); + lexer.pushback(s); + if (cmd == null) { + expr.add(expression(registerVars, inFunction, inMethod, true)); + } else { + if (!cmd.hasReturnValue()) { + throw new ParseException("Expression expected", lexer.yyline()); + } + } + return new CommaExpressionItem(null, expr); + } + + private GraphTargetItem expression(boolean allowEmpty, HashMap registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder) throws IOException, ParseException { if (debugMode) { System.out.println("expression:"); } - List ret = new ArrayList<>(); + GraphTargetItem ret = null; ParsedSymbol s = lex(); boolean existsRemainder = false; boolean assocRight = false; switch (s.type) { case MINUS: - List num = expression(registerVars, inFunction, inMethod, true); - if ((num.size() == 1) && (num.get(0) instanceof ActionPush) - && (((ActionPush) num.get(0)).values.get(0) instanceof Long)) { - ((ActionPush) num.get(0)).values.set(0, -(Long) ((ActionPush) num.get(0)).values.get(0)); - ret.addAll(num); - } else if ((num.size() == 1) && (num.get(0) instanceof ActionPush) - && (((ActionPush) num.get(0)).values.get(0) instanceof Double)) { - Double d = (Double) ((ActionPush) num.get(0)).values.get(0); + GraphTargetItem num = expression(registerVars, inFunction, inMethod, true); + if ((num instanceof DirectValueTreeItem) + && (((DirectValueTreeItem) num).value instanceof Long)) { + ((DirectValueTreeItem) num).value = -(Long) ((DirectValueTreeItem) num).value; + ret = num; + } else if ((num instanceof DirectValueTreeItem) + && (((DirectValueTreeItem) num).value instanceof Double)) { + Double d = (Double) ((DirectValueTreeItem) num).value; if (d.isInfinite()) { - ((ActionPush) num.get(0)).values.set(0, Double.NEGATIVE_INFINITY); + ((DirectValueTreeItem) num).value = Double.NEGATIVE_INFINITY; } else { - ((ActionPush) num.get(0)).values.set(0, -d); + ((DirectValueTreeItem) num).value = -d; } - - ret.addAll(num); - } else if ((num.size() == 1) && (num.get(0) instanceof ActionPush) - && (((ActionPush) num.get(0)).values.get(0) instanceof Float)) { - ((ActionPush) num.get(0)).values.set(0, -(Float) ((ActionPush) num.get(0)).values.get(0)); - ret.addAll(num); - } else { - ret.add(new ActionPush(Long.valueOf(0))); - ret.addAll(num); - ret.add(new ActionSubtract()); + ret = (num); + } else if ((num instanceof DirectValueTreeItem) + && (((DirectValueTreeItem) num).value instanceof Float)) { + ((DirectValueTreeItem) num).value = -(Float) ((DirectValueTreeItem) num).value; + ret = (num); + } else {; + ret = (new SubtractTreeItem(null, new DirectValueTreeItem(null, 0, (Long) 0L, new ArrayList()), num)); } break; case TYPEOF: expectedType(SymbolType.PARENT_OPEN); - ret.addAll(expression(registerVars, inFunction, inMethod, true)); + ret = new TypeOfTreeItem(null, expression(registerVars, inFunction, inMethod, true)); expectedType(SymbolType.PARENT_CLOSE); existsRemainder = true; break; case TRUE: - ret.add(new ActionPush(Boolean.TRUE)); + ret = new DirectValueTreeItem(null, 0, Boolean.TRUE, new ArrayList()); existsRemainder = true; break; case NULL: - ret.add(new ActionPush(new Null())); + ret = new DirectValueTreeItem(null, 0, new Null(), new ArrayList()); existsRemainder = true; break; case UNDEFINED: - ret.add(new ActionPush(new Undefined())); + ret = new DirectValueTreeItem(null, 0, new Undefined(), new ArrayList()); break; case FALSE: - ret.add(new ActionPush(Boolean.FALSE)); + ret = new DirectValueTreeItem(null, 0, Boolean.FALSE, new ArrayList()); existsRemainder = true; break; case CURLY_OPEN: //Object literal s = lex(); - int objCnt = 0; + List objectNames = new ArrayList<>(); + List objectValues = new ArrayList<>(); while (s.type != SymbolType.CURLY_CLOSE) { if (s.type != SymbolType.COMMA) { lexer.pushback(s); } - objCnt++; - ret.addAll(expression(registerVars, inFunction, inMethod, true)); + objectNames.add(expression(registerVars, inFunction, inMethod, true)); expectedType(SymbolType.COLON); - ret.addAll(expression(registerVars, inFunction, inMethod, true)); + objectValues.add(expression(registerVars, inFunction, inMethod, true)); s = lex(); if (!s.isType(SymbolType.COMMA, SymbolType.CURLY_CLOSE)) { expected(s, lexer.yyline(), SymbolType.COMMA, SymbolType.CURLY_CLOSE); } } - ret.add(new ActionPush(fixZero(new Long(objCnt)))); - ret.add(new ActionInitObject()); + ret = new InitObjectTreeItem(null, objectNames, objectValues); break; case BRACKET_OPEN: //Array literal or just brackets lexer.pushback(s); - int arrCnt = brackets(ret, registerVars, inFunction, inMethod); - ret.add(new ActionPush(fixZero(new Long(arrCnt)))); - ret.add(new ActionInitArray()); + List inBrackets = new ArrayList<>(); + int arrCnt = brackets(inBrackets, registerVars, inFunction, inMethod); + ret = new InitArrayTreeItem(null, inBrackets); break; case FUNCTION: s = lexer.lex(); @@ -1922,127 +1577,114 @@ public class ActionScriptParser { } else { lexer.pushback(s); } - ret.addAll(function(true, fname, false)); + ret = function(true, fname, false); break; case STRING: - ret.add(pushConst(s.value.toString())); - memberOrCall(ret, registerVars, inFunction, inMethod); + ret = pushConst(s.value.toString()); + ret = memberOrCall(ret, registerVars, inFunction, inMethod); existsRemainder = true; break; case NEWLINE: - ret.add(pushConst("\r")); + ret = new DirectValueTreeItem(null, 0, "\r", new ArrayList()); existsRemainder = true; break; case NAN: - ret.add(new ActionPush(Double.NaN)); + ret = new DirectValueTreeItem(null, 0, Double.NaN, new ArrayList()); existsRemainder = true; break; case INFINITY: - ret.add(new ActionPush(Double.POSITIVE_INFINITY)); + ret = new DirectValueTreeItem(null, 0, Double.POSITIVE_INFINITY, new ArrayList()); existsRemainder = true; break; case INTEGER: case DOUBLE: - ret.add(new ActionPush(fixZero(s.value))); - //ret.addAll(expressionRemainder(registerVars, inFunction, inMethod)); + ret = new DirectValueTreeItem(null, 0, s.value, new ArrayList()); existsRemainder = true; break; case DELETE: - ret.addAll(variable(registerVars, inFunction, inMethod)); - if (ret.get(ret.size() - 1) instanceof ActionGetMember) { - ret.remove(ret.size() - 1); + GraphTargetItem varDel = variable(registerVars, inFunction, inMethod); + if (varDel instanceof GetMemberTreeItem) { + GetMemberTreeItem gm = (GetMemberTreeItem) varDel; + ret = new DeleteTreeItem(null, gm.object, gm.memberName); + } else { + throw new ParseException("Not a property", lexer.yyline()); } - ret.add(new ActionDelete()); break; case INCREMENT: case DECREMENT: //preincrement - List prevar = variable(registerVars, inFunction, inMethod); - ret.addAll(prevar); - Action prelast = ret.remove(ret.size() - 1); - ret.addAll(prevar); + GraphTargetItem prevar = variable(registerVars, inFunction, inMethod); if (s.type == SymbolType.INCREMENT) { - ret.add(new ActionIncrement()); + ret = new PreIncrementTreeItem(null, prevar); } if (s.type == SymbolType.DECREMENT) { - ret.add(new ActionDecrement()); + ret = new PreDecrementTreeItem(null, prevar); } - int tmpReg = 0; - for (int i = 0; i < 256; i++) { - if (!registerVars.containsValue(i)) { - tmpReg = i; - break; - } - } - ret.add(new ActionStoreRegister(tmpReg)); - if (prelast instanceof ActionGetVariable) { - ret.add(new ActionSetVariable()); - } - if (prelast instanceof ActionGetMember) { - ret.add(new ActionSetMember()); - } - ret.add(new ActionPush(new RegisterNumber(tmpReg))); - //ret.addAll(expressionRemainder(registerVars, inFunction, inMethod)); existsRemainder = true; break; case NOT: - ret.addAll(expression(registerVars, inFunction, inMethod, true)); - ret.add(new ActionNot()); - //ret.addAll(expressionRemainder(registerVars, inFunction, inMethod)); + ret = new NotItem(null, expression(registerVars, inFunction, inMethod, true)); existsRemainder = true; break; case PARENT_OPEN: - ret.addAll(expression(registerVars, inFunction, inMethod, true)); + ret = new ParenthesisItem(null, expression(registerVars, inFunction, inMethod, true)); expectedType(SymbolType.PARENT_CLOSE); - memberOrCall(ret, registerVars, inFunction, inMethod); - //ret.addAll(expressionRemainder(registerVars, inFunction, inMethod)); + ret = memberOrCall(ret, registerVars, inFunction, inMethod); existsRemainder = true; break; case NEW: - List newcmds = new ArrayList<>(); - newcmds.addAll(variable(registerVars, inFunction, inMethod)); + GraphTargetItem newvar = variable(registerVars, inFunction, inMethod); expectedType(SymbolType.PARENT_OPEN); - if (newcmds.get(newcmds.size() - 1) instanceof ActionGetMember) { - newcmds.remove(newcmds.size() - 1); - newcmds.addAll(0, call(registerVars, inFunction, inMethod)); - newcmds.add(new ActionNewMethod()); - } else if (newcmds.get(newcmds.size() - 1) instanceof ActionGetVariable) { - newcmds.remove(newcmds.size() - 1); - newcmds.addAll(0, call(registerVars, inFunction, inMethod)); - newcmds.add(new ActionNewObject()); + if (newvar instanceof GetMemberTreeItem) { + GetMemberTreeItem mem = (GetMemberTreeItem) newvar; + ret = new NewMethodTreeItem(null, mem.object, mem.memberName, call(registerVars, inFunction, inMethod)); + } else if (newvar instanceof GetVariableTreeItem) { + GetVariableTreeItem gv = (GetVariableTreeItem) newvar; + ret = new NewObjectTreeItem(null, gv.name, call(registerVars, inFunction, inMethod)); + } else { + throw new ParseException("Invalid new item", lexer.yyline()); } - ret.addAll(newcmds); - break; case IDENTIFIER: case THIS: case EVAL: - List var; + GraphTargetItem var; if (s.type == SymbolType.EVAL) { expectedType(SymbolType.PARENT_OPEN); - var = expression(registerVars, inFunction, inMethod, true); - var.add(new ActionGetVariable()); + var = new EvalTreeItem(null, expression(registerVars, inFunction, inMethod, true)); expectedType(SymbolType.PARENT_CLOSE); - memberOrCall(var, registerVars, inFunction, inMethod); + var = memberOrCall(var, registerVars, inFunction, inMethod); } else { lexer.pushback(s); var = variable(registerVars, inFunction, inMethod); } + + GetVariableTreeItem gva = null; + GetMemberTreeItem gmb = null; + RegisterNumber reg = null; + if (var instanceof GetVariableTreeItem) { + gva = (GetVariableTreeItem) var; + } else if (var instanceof GetMemberTreeItem) { + gmb = (GetMemberTreeItem) var; + } else if (var instanceof DirectValueTreeItem) { + if (((DirectValueTreeItem) var).value instanceof RegisterNumber) { + reg = (RegisterNumber) ((DirectValueTreeItem) var).value; + } + } + s = lex(); switch (s.type) { case ASSIGN: - int asTmpReg = 0; - for (int i = 0; i < 256; i++) { - if (!registerVars.containsValue(i)) { - asTmpReg = i; - break; - } + GraphTargetItem varval = expression(registerVars, inFunction, inMethod, true); + if (gva != null) { + ret = new SetVariableTreeItem(null, gva.name, varval); + } else if (gmb != null) { + ret = new SetMemberTreeItem(null, gmb.object, gmb.memberName, varval); + } else if (reg != null) { + ret = new StoreRegisterTreeItem(null, reg, varval, false); + } else { + throw new ParseException("Invalid assignment", lexer.yyline()); } - List varval = expression(registerVars, inFunction, inMethod, true); - varval.add(new ActionStoreRegister(asTmpReg)); - var = gettoset(var, varval); - ret.addAll(var); - ret.add(new ActionPush(new RegisterNumber(asTmpReg))); existsRemainder = true; assocRight = true; break; @@ -2054,93 +1696,108 @@ public class ActionScriptParser { case ASSIGN_MULTIPLY: case ASSIGN_PLUS: case ASSIGN_XOR: - List varset = new ArrayList<>(); - varset.addAll(var); - var.addAll(expression(registerVars, inFunction, inMethod, true)); + //List varset = new ArrayList<>(); + //varset.addAll(var); + if (gva == null && gmb == null) { + throw new ParseException("Invalid assignment", lexer.yyline()); + } + GraphTargetItem varval2 = expression(registerVars, inFunction, inMethod, true); + switch (s.type) { case ASSIGN_BITAND: - var.add(new ActionBitAnd()); + if (gva != null) { + ret = new SetVariableTreeItem(null, gva.name, new BitAndTreeItem(null, gva, varval2)); + } else { + ret = new SetMemberTreeItem(null, gmb.object, gmb.memberName, new BitAndTreeItem(null, gmb, varval2)); + } break; case ASSIGN_BITOR: - var.add(new ActionBitOr()); + if (gva != null) { + ret = new SetVariableTreeItem(null, gva.name, new BitOrTreeItem(null, gva, varval2)); + } else { + ret = new SetMemberTreeItem(null, gmb.object, gmb.memberName, new BitOrTreeItem(null, gmb, varval2)); + } break; case ASSIGN_DIVIDE: - var.add(new ActionDivide()); + if (gva != null) { + ret = new SetVariableTreeItem(null, gva.name, new DivideTreeItem(null, gva, varval2)); + } else { + ret = new SetMemberTreeItem(null, gmb.object, gmb.memberName, new DivideTreeItem(null, gmb, varval2)); + } break; case ASSIGN_MINUS: - var.add(new ActionSubtract()); + if (gva != null) { + ret = new SetVariableTreeItem(null, gva.name, new SubtractTreeItem(null, gva, varval2)); + } else { + ret = new SetMemberTreeItem(null, gmb.object, gmb.memberName, new SubtractTreeItem(null, gmb, varval2)); + } break; case ASSIGN_MODULO: - var.add(new ActionModulo()); + if (gva != null) { + ret = new SetVariableTreeItem(null, gva.name, new ModuloTreeItem(null, gva, varval2)); + } else { + ret = new SetMemberTreeItem(null, gmb.object, gmb.memberName, new ModuloTreeItem(null, gmb, varval2)); + } break; case ASSIGN_MULTIPLY: - var.add(new ActionMultiply()); + if (gva != null) { + ret = new SetVariableTreeItem(null, gva.name, new MultiplyTreeItem(null, gva, varval2)); + } else { + ret = new SetMemberTreeItem(null, gmb.object, gmb.memberName, new MultiplyTreeItem(null, gmb, varval2)); + } break; case ASSIGN_PLUS: - var.add(new ActionAdd()); + if (gva != null) { + ret = new SetVariableTreeItem(null, gva.name, new AddTreeItem(null, gva, varval2, true/*TODO:SWF version?*/)); + } else { + ret = new SetMemberTreeItem(null, gmb.object, gmb.memberName, new AddTreeItem(null, gmb, varval2, true/*TODO:SWF version?*/)); + } break; } - int asaTmpReg = 0; - for (int i = 0; i < 256; i++) { - if (!registerVars.containsValue(i)) { - asaTmpReg = i; - break; - } - } - var.add(new ActionStoreRegister(asaTmpReg)); - varset = gettoset(varset, var); - ret.addAll(varset); - ret.add(new ActionPush(new RegisterNumber(asaTmpReg))); existsRemainder = true; assocRight = true; break; - case INCREMENT: - case DECREMENT: - ret.addAll(var); - ret.addAll(var); - Action at = ret.remove(ret.size() - 1); - ret.addAll(var); - if (s.type == SymbolType.INCREMENT) { - ret.add(new ActionIncrement()); + case INCREMENT: //postincrement + if (gva == null && gmb == null) { + throw new ParseException("Invalid assignment", lexer.yyline()); } - if (s.type == SymbolType.DECREMENT) { - ret.add(new ActionDecrement()); - } - if (at instanceof ActionGetMember) { - ret.add(new ActionSetMember()); - } - if (at instanceof ActionGetVariable) { - ret.add(new ActionSetVariable()); + ret = new PostIncrementTreeItem(null, var); + break; + case DECREMENT: //postdecrement + if (gva == null && gmb == null) { + throw new ParseException("Invalid assignment", lexer.yyline()); } + ret = new PostDecrementTreeItem(null, var); break; case PARENT_OPEN: //function call lexer.pushback(s); - ret.addAll(var); - memberOrCall(ret, registerVars, inFunction, inMethod); + ret = memberOrCall(var, registerVars, inFunction, inMethod); existsRemainder = true; break; default: - ret.addAll(var); + ret = var; lexer.pushback(s); existsRemainder = true; //ret.addAll(expressionRemainder(registerVars, inFunction, inMethod)); } break; default: - List excmd = expressionCommands(s, registerVars, inFunction, inMethod, -1); + GraphTargetItem excmd = expressionCommands(s, registerVars, inFunction, inMethod, -1); if (excmd != null) { existsRemainder = true; //? - ret.addAll(excmd); + ret = excmd; break; } lexer.pushback(s); } - List rem = new ArrayList<>(); if (allowRemainder && existsRemainder) { + GraphTargetItem rem = ret; do { - rem = expressionRemainder(registerVars, inFunction, inMethod, assocRight); - ret.addAll(rem); - } while ((!assocRight) && (!rem.isEmpty())); + rem = expressionRemainder(rem, registerVars, inFunction, inMethod, assocRight); + if (rem != null) { + ret = rem; + } + } while ((!assocRight) && (rem != null)); } if (debugMode) { System.out.println("/expression"); @@ -2148,41 +1805,54 @@ public class ActionScriptParser { return ret; } - private ActionPush pushConst(String s) throws IOException, ParseException { + private DirectValueTreeItem pushConst(String s) throws IOException, ParseException { int index = constantPool.indexOf(s); if (index == -1) { constantPool.add(s); index = constantPool.indexOf(s); } - return new ActionPush(new ConstantIndex(index)); + return new DirectValueTreeItem(null, 0, new ConstantIndex(index), constantPool); } private ActionScriptLexer lexer = null; private List constantPool; - public List parse(String str) throws ParseException, IOException { - List ret = new ArrayList<>(); - + public List treeFromString(String str, List constantPool) throws ParseException, IOException { + List retTree = new ArrayList<>(); + this.constantPool = constantPool; try { lexer = new ActionScriptLexer(new InputStreamReader(new ByteArrayInputStream(str.getBytes("UTF8")), "UTF8")); } catch (UnsupportedEncodingException ex) { Logger.getLogger(ActionScriptParser.class.getName()).log(Level.SEVERE, null, ex); - return ret; - } - - constantPool = new ArrayList<>(); - ret.addAll(commands(new HashMap(), false, false, 0)); - if (!constantPool.isEmpty()) { - ret.add(0, new ActionConstantPool(constantPool)); + return retTree; } + retTree.addAll(commands(new HashMap(), false, false, 0)); if (lexer.lex().type != SymbolType.EOF) { throw new ParseException("Parsing finisned before end of the file", lexer.yyline()); } - List retgs = new ArrayList<>(); - retgs.addAll(ret); - if (!constantPool.isEmpty()) { - Action.setConstantPool(retgs, new ConstantPool(constantPool)); + return retTree; + } + + public List actionsFromTree(List tree, List constantPool) { + ActionScriptSourceGenerator gen = new ActionScriptSourceGenerator(constantPool); + List ret = new ArrayList<>(); + List localDate = new ArrayList<>(); + localDate.add(new HashMap()); //registerVars + localDate.add(Boolean.FALSE); //inFunction + localDate.add(Boolean.FALSE); //inMethod + localDate.add((Integer) 0); //forInLevel + List srcList = gen.generate(localDate, tree); + for (GraphSourceItem s : srcList) { + if (s instanceof Action) { + ret.add((Action) s); + } } - Action.setActionsAddresses(ret, 0, SWF.DEFAULT_VERSION); + ret.add(0, new ActionConstantPool(constantPool)); return ret; } + + public List actionsFromString(String s) throws ParseException, IOException { + List constantPool = new ArrayList<>(); + List tree = treeFromString(s, constantPool); + return actionsFromTree(tree, constantPool); + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/parser/script/ActionScriptSourceGenerator.java b/trunk/src/com/jpexs/decompiler/flash/action/parser/script/ActionScriptSourceGenerator.java new file mode 100644 index 000000000..aee4a5e5c --- /dev/null +++ b/trunk/src/com/jpexs/decompiler/flash/action/parser/script/ActionScriptSourceGenerator.java @@ -0,0 +1,766 @@ +/* + * 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 . + */ +package com.jpexs.decompiler.flash.action.parser.script; + +import com.jpexs.decompiler.flash.SWF; +import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.swf4.ActionGetVariable; +import com.jpexs.decompiler.flash.action.swf4.ActionIf; +import com.jpexs.decompiler.flash.action.swf4.ActionJump; +import com.jpexs.decompiler.flash.action.swf4.ActionNot; +import com.jpexs.decompiler.flash.action.swf4.ActionPop; +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.RegisterNumber; +import com.jpexs.decompiler.flash.action.swf5.ActionCallFunction; +import com.jpexs.decompiler.flash.action.swf5.ActionDefineFunction; +import com.jpexs.decompiler.flash.action.swf5.ActionGetMember; +import com.jpexs.decompiler.flash.action.swf5.ActionNewObject; +import com.jpexs.decompiler.flash.action.swf5.ActionPushDuplicate; +import com.jpexs.decompiler.flash.action.swf5.ActionSetMember; +import com.jpexs.decompiler.flash.action.swf5.ActionStoreRegister; +import com.jpexs.decompiler.flash.action.swf6.ActionStrictEquals; +import com.jpexs.decompiler.flash.action.swf7.ActionExtends; +import com.jpexs.decompiler.flash.action.swf7.ActionImplementsOp; +import com.jpexs.decompiler.flash.action.treemodel.DirectValueTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.FunctionTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.GetMemberTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.GetVariableTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.operations.Inverted; +import com.jpexs.decompiler.flash.ecma.Null; +import com.jpexs.decompiler.flash.graph.AndItem; +import com.jpexs.decompiler.flash.graph.BreakItem; +import com.jpexs.decompiler.flash.graph.CommaExpressionItem; +import com.jpexs.decompiler.flash.graph.ContinueItem; +import com.jpexs.decompiler.flash.graph.DoWhileItem; +import com.jpexs.decompiler.flash.graph.DuplicateItem; +import com.jpexs.decompiler.flash.graph.ForItem; +import com.jpexs.decompiler.flash.graph.GraphSourceItem; +import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.IfItem; +import com.jpexs.decompiler.flash.graph.NotItem; +import com.jpexs.decompiler.flash.graph.OrItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import com.jpexs.decompiler.flash.graph.SwitchItem; +import com.jpexs.decompiler.flash.graph.TernarOpItem; +import com.jpexs.decompiler.flash.graph.WhileItem; +import com.jpexs.decompiler.flash.helpers.Helper; +import com.jpexs.decompiler.flash.helpers.collections.MyEntry; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +/** + * + * @author JPEXS + */ +public class ActionScriptSourceGenerator implements SourceGenerator { + + @Override + public List generate(List localData, AndItem item) { + List ret = new ArrayList<>(); + ret.addAll(generateToActionList(localData, item.leftSide)); + ret.add(new ActionPushDuplicate()); + ret.add(new ActionNot()); + List andExpr = generateToActionList(localData, item.rightSide); + andExpr.add(0, new ActionPop()); + int andExprLen = Action.actionsToBytes(andExpr, false, SWF.DEFAULT_VERSION).length; + ret.add(new ActionIf(andExprLen)); + ret.addAll(andExpr); + return ret; + + } + + @Override + public List generate(List localData, OrItem item) { + List ret = new ArrayList<>(); + ret.addAll(generateToActionList(localData, item.leftSide)); + ret.add(new ActionPushDuplicate()); + List orExpr = generateToActionList(localData, item.rightSide); + orExpr.add(0, new ActionPop()); + int orExprLen = Action.actionsToBytes(orExpr, false, SWF.DEFAULT_VERSION).length; + ret.add(new ActionIf(orExprLen)); + ret.addAll(orExpr); + return ret; + } + + public List toActionList(List items) { + List ret = new ArrayList<>(); + for (GraphSourceItem s : items) { + if (s instanceof Action) { + ret.add((Action) s); + } + } + return ret; + } + + private List nonempty(List list) { + if (list == null) { + return new ArrayList<>(); + } + return list; + } + + private List generateIf(List localData, GraphTargetItem expression, List onTrueCmds, List onFalseCmds, boolean ternar) { + List ret = new ArrayList<>(); + if (expression instanceof Inverted) { + ret.addAll(((Inverted) expression).invert().toSource(localData, this)); + } else { + ret.addAll(expression.toSource(localData, this)); + ret.add(new ActionNot()); + } + List onTrue = null; + List onFalse = null; + if (ternar) { + onTrue = toActionList(onTrueCmds.get(0).toSource(localData, this)); + } else { + onTrue = generateToActionList(localData, onTrueCmds); + } + + if (onFalseCmds != null && !onFalseCmds.isEmpty()) { + if (ternar) { + onFalse = toActionList(onFalseCmds.get(0).toSource(localData, this)); + } else { + onFalse = generateToActionList(localData, onFalseCmds); + } + } + byte onTrueBytes[] = Action.actionsToBytes(onTrue, false, SWF.DEFAULT_VERSION); + int onTrueLen = onTrueBytes.length; + + ActionIf ifaif = new ActionIf(0); + ret.add(ifaif); + ret.addAll(onTrue); + ifaif.setJumpOffset(onTrueLen); + ActionJump ajmp = null; + if (onFalse != null) { + if (!((!nonempty(onTrue).isEmpty()) + && (onTrue.get(onTrue.size() - 1) instanceof ActionJump) + && ((((ActionJump) onTrue.get(onTrue.size() - 1)).isContinue) + || (((ActionJump) onTrue.get(onTrue.size() - 1)).isBreak)))) { + ajmp = new ActionJump(0); + ret.add(ajmp); + onTrueLen += ajmp.getBytes(SWF.DEFAULT_VERSION).length; + } + ifaif.setJumpOffset(onTrueLen); + byte onFalseBytes[] = Action.actionsToBytes(onFalse, false, SWF.DEFAULT_VERSION); + int onFalseLen = onFalseBytes.length; + if (ajmp != null) { + ajmp.setJumpOffset(onFalseLen); + } + ret.addAll(onFalse); + } + return ret; + } + + @Override + public List generate(List localData, IfItem item) { + return generateIf(localData, item.expression, item.onTrue, item.onFalse, false); + } + + private void fixLoop(List code, int breakOffset) { + fixLoop(code, breakOffset, Integer.MAX_VALUE); + } + + private void fixLoop(List code, int breakOffset, int continueOffset) { + int pos = 0; + for (Action a : code) { + pos += a.getBytes(SWF.DEFAULT_VERSION).length; + if (a instanceof ActionJump) { + ActionJump aj = (ActionJump) a; + if (aj.isContinue && (continueOffset != Integer.MAX_VALUE)) { + aj.setJumpOffset(-pos + continueOffset); + aj.isContinue = false; + } + if (aj.isBreak) { + aj.setJumpOffset(-pos + breakOffset); + aj.isBreak = false; + } + } + } + } + + @Override + public List generate(List localData, TernarOpItem item) { + List onTrue = new ArrayList<>(); + onTrue.add(item.onTrue); + List onFalse = new ArrayList<>(); + onFalse.add(item.onFalse); + return generateIf(localData, item.expression, onTrue, onFalse, true); + } + + @Override + public List generate(List localData, WhileItem item) { + List ret = new ArrayList<>(); + List whileExpr = new ArrayList<>(); + + List ex = new ArrayList<>(item.expression); + if (!ex.isEmpty()) { + GraphTargetItem lastItem = ex.remove(ex.size() - 1); + whileExpr.addAll(generateToActionList(localData, ex)); + whileExpr.addAll(toActionList(lastItem.toSource(localData, this))); //Want result + } + + List whileBody = generateToActionList(localData, item.commands); + whileExpr.add(new ActionNot()); + ActionIf whileaif = new ActionIf(0); + whileExpr.add(whileaif); + ActionJump whileajmp = new ActionJump(0); + whileBody.add(whileajmp); + int whileExprLen = Action.actionsToBytes(whileExpr, false, SWF.DEFAULT_VERSION).length; + int whileBodyLen = Action.actionsToBytes(whileBody, false, SWF.DEFAULT_VERSION).length; + whileajmp.setJumpOffset(-(whileExprLen + + whileBodyLen)); + whileaif.setJumpOffset(whileBodyLen); + ret.addAll(whileExpr); + fixLoop(whileBody, whileBodyLen, -whileExprLen); + ret.addAll(whileBody); + return ret; + } + + @Override + public List generate(List localData, DoWhileItem item) { + List ret = new ArrayList<>(); + List doExpr = generateToActionList(localData, item.expression); + List doBody = generateToActionList(localData, item.commands); + + int doBodyLen = Action.actionsToBytes(doBody, false, SWF.DEFAULT_VERSION).length; + int doExprLen = Action.actionsToBytes(doExpr, false, SWF.DEFAULT_VERSION).length; + + ret.addAll(doBody); + ret.addAll(doExpr); + ActionIf doif = new ActionIf(0); + ret.add(doif); + doif.setJumpOffset(-doBodyLen - doExprLen - doif.getBytes(SWF.DEFAULT_VERSION).length); + fixLoop(doBody, doBodyLen + doExprLen + doif.getBytes(SWF.DEFAULT_VERSION).length, doBodyLen); + return ret; + } + + @Override + public List generate(List localData, ForItem item) { + List ret = new ArrayList<>(); + List forExpr = generateToActionList(localData, item.expression); + List forBody = generateToActionList(localData, item.commands); + List forFinalCommands = generateToActionList(localData, item.finalCommands); + + forExpr.add(new ActionNot()); + ActionIf foraif = new ActionIf(0); + forExpr.add(foraif); + ActionJump forajmp = new ActionJump(0); + int forajmpLen = forajmp.getBytes(SWF.DEFAULT_VERSION).length; + int forExprLen = Action.actionsToBytes(forExpr, false, SWF.DEFAULT_VERSION).length; + int forBodyLen = Action.actionsToBytes(forBody, false, SWF.DEFAULT_VERSION).length; + int forFinalLen = Action.actionsToBytes(forFinalCommands, false, SWF.DEFAULT_VERSION).length; + forajmp.setJumpOffset(-(forExprLen + + forBodyLen + forFinalLen + forajmpLen)); + foraif.setJumpOffset(forBodyLen + forFinalLen + forajmpLen); + ret.addAll(forExpr); + ret.addAll(forBody); + ret.addAll(forFinalCommands); + ret.add(forajmp); + fixLoop(forBody, forBodyLen + forFinalLen + forajmpLen, forBodyLen); + return ret; + } + private long uniqLast = 0; + + public String uniqId() { + uniqLast++; + return "" + uniqLast; + } + + @Override + public List generate(List localData, SwitchItem item) { + List ret = new ArrayList<>(); + HashMap registerVars = getRegisterVars(localData); + int exprReg = 0; + for (int i = 0; i < 256; i++) { + if (!registerVars.containsValue(i)) { + registerVars.put("__switch" + uniqId(), i); + exprReg = i; + break; + } + } + + ret.addAll(toActionList(item.switchedObject.toSource(localData, this))); + + + boolean firstCase = true; + List> caseIfs = new ArrayList<>(); + List> caseCmds = new ArrayList<>(); + List>> caseExprsAll = new ArrayList<>(); + + loopm: + for (int m = 0; m < item.caseValues.size(); m++) { + List> caseExprs = new ArrayList<>(); + List caseIfsOne = new ArrayList<>(); + int mapping = item.valuesMapping.get(m); + for (; m < item.caseValues.size(); m++) { + int newmapping = item.valuesMapping.get(m); + if (newmapping != mapping) { + m--; + break; + } + List curCaseExpr = generateToActionList(localData, item.caseValues.get(m)); + caseExprs.add(curCaseExpr); + if (firstCase) { + curCaseExpr.add(0, new ActionStoreRegister(exprReg)); + } else { + curCaseExpr.add(0, new ActionPush(new RegisterNumber(exprReg))); + } + curCaseExpr.add(new ActionStrictEquals()); + ActionIf aif = new ActionIf(0); + caseIfsOne.add(aif); + curCaseExpr.add(aif); + ret.addAll(curCaseExpr); + firstCase = false; + } + caseExprsAll.add(caseExprs); + caseIfs.add(caseIfsOne); + List caseCmd = generateToActionList(localData, item.caseCommands.get(mapping)); + caseCmds.add(caseCmd); + } + ActionJump defJump = new ActionJump(0); + ret.add(defJump); + List defCmd = new ArrayList<>(); + if (!item.defaultCommands.isEmpty()) { + defCmd = generateToActionList(localData, item.defaultCommands); + } + for (List caseCmd : caseCmds) { + ret.addAll(caseCmd); + } + ret.addAll(defCmd); + + List> exprLengths = new ArrayList<>(); + for (List> caseExprs : caseExprsAll) { + List lengths = new ArrayList<>(); + for (List caseExpr : caseExprs) { + lengths.add(Action.actionsToBytes(caseExpr, false, SWF.DEFAULT_VERSION).length); + } + exprLengths.add(lengths); + } + List caseLengths = new ArrayList<>(); + for (List caseCmd : caseCmds) { + caseLengths.add(Action.actionsToBytes(caseCmd, false, SWF.DEFAULT_VERSION).length); + } + int defLength = Action.actionsToBytes(defCmd, false, SWF.DEFAULT_VERSION).length; + + for (int i = 0; i < caseIfs.size(); i++) { + for (int c = 0; c < caseIfs.get(i).size(); c++) { + int jmpPos = 0; + for (int j = c + 1; j < caseIfs.get(i).size(); j++) { + jmpPos += exprLengths.get(i).get(j); + } + for (int k = i + 1; k < caseIfs.size(); k++) { + for (int m = 0; m < caseIfs.get(k).size(); m++) { + jmpPos += exprLengths.get(k).get(m); + } + } + jmpPos += defJump.getBytes(SWF.DEFAULT_VERSION).length; + for (int n = 0; n < i; n++) { + jmpPos += caseLengths.get(n); + } + caseIfs.get(i).get(c).setJumpOffset(jmpPos); + } + } + int defJmpPos = 0; + for (int i = 0; i < caseIfs.size(); i++) { + defJmpPos += caseLengths.get(i); + } + + defJump.setJumpOffset(defJmpPos); + List caseCmdsAll = new ArrayList<>(); + int breakOffset = 0; + for (int i = 0; i < caseCmds.size(); i++) { + caseCmdsAll.addAll(caseCmds.get(i)); + breakOffset += caseLengths.get(i); + } + breakOffset += defLength; + fixLoop(caseCmdsAll, breakOffset); + return ret; + } + + @Override + public List generate(List localData, NotItem item) { + if (item.getOriginal() instanceof Inverted) { + GraphTargetItem norig = ((Inverted) item).invert(); + return norig.toSource(localData, this); + } + List ret = new ArrayList<>(); + ret.addAll(item.getOriginal().toSource(localData, this)); + ret.add(new ActionNot()); + return ret; + } + + @Override + public List generate(List localData, DuplicateItem item) { + List ret = new ArrayList<>(); + ret.add(new ActionPushDuplicate()); + return ret; + } + + @Override + public List generate(List localData, BreakItem item) { + List ret = new ArrayList<>(); + ActionJump abreak = new ActionJump(0); + abreak.isBreak = true; + ret.add(abreak); + return ret; + } + + @Override + public List generate(List localData, ContinueItem item) { + List ret = new ArrayList<>(); + ActionJump acontinue = new ActionJump(0); + acontinue.isContinue = true; + ret.add(acontinue); + return ret; + } + + private List generateToActionList(List localData, List commands) { + return toActionList(generate(localData, commands)); + } + + private List generateToActionList(List localData, GraphTargetItem command) { + return toActionList(command.toSource(localData, this)); + } + + @Override + public List generate(List localData, List commands) { + List ret = new ArrayList<>(); + for (GraphTargetItem item : commands) { + ret.addAll(item.toSourceIgnoreReturnValue(localData, this)); + } + return ret; + } + + @SuppressWarnings("unchecked") + public HashMap getRegisterVars(List localData) { + return (HashMap) localData.get(0); + } + + public void setRegisterVars(List localData, HashMap value) { + localData.set(0, value); + } + + public void setInFunction(List localData, boolean value) { + localData.set(1, value); + } + + public boolean isInFunction(List localData) { + return (Boolean) localData.get(1); + } + + public boolean isInMethod(List localData) { + return (Boolean) localData.get(2); + } + + public void setInMethod(List localData, boolean value) { + localData.set(2, value); + } + + public int getForInLevel(List localData) { + return (Integer) localData.get(3); + } + + public void setForInLevel(List localData, int value) { + localData.set(3, value); + } + + public int getTempRegister(List localData) { + HashMap registerVars = getRegisterVars(localData); + int tmpReg = 0; + for (int i = 0; i < 256; i++) { + if (!registerVars.containsValue(i)) { + tmpReg = i; + break; + } + } + return tmpReg; + } + + private String getName(GraphTargetItem item) { + if (item instanceof DirectValueTreeItem) { + DirectValueTreeItem dv = (DirectValueTreeItem) item; + return (String) dv.getResult(); + } + if (item instanceof GetVariableTreeItem) { + GetVariableTreeItem gv = (GetVariableTreeItem) item; + return getName(gv.name); + } + if (item instanceof GetMemberTreeItem) { + GetMemberTreeItem mem = (GetMemberTreeItem) item; + return getName(mem.memberName); + } + return null; + } + + private List getVarParts(GraphTargetItem item) { + List ret = new ArrayList<>(); + do { + if (item instanceof GetMemberTreeItem) { + GetMemberTreeItem mem = (GetMemberTreeItem) item; + ret.add(0, getName(mem)); + item = mem.object; + } + } while (item instanceof GetMemberTreeItem); + String f = getName(item); + if (f != null) { + ret.add(0, f); + } + return ret; + } + + private int getVarLength(GraphTargetItem item) { + int len = 1; + do { + if (item instanceof GetMemberTreeItem) { + GetMemberTreeItem mem = (GetMemberTreeItem) item; + item = mem.object; + len++; + } + } while (item instanceof GetMemberTreeItem); + return len; + } + + private GraphTargetItem removeVarLast(GraphTargetItem item, int cnt) { + item = (GraphTargetItem) Helper.deepCopy(item); + + for (int i = 0; i < cnt; i++) { + if (item instanceof GetMemberTreeItem) { + GetMemberTreeItem mem = (GetMemberTreeItem) item; + item = mem.object; + } + } + return item; + } + + private GraphTargetItem addGlobalPrefix(GraphTargetItem item) { + item = (GraphTargetItem) Helper.deepCopy(item); + GraphTargetItem first = item; + GetMemberTreeItem mem = null; + do { + if (item instanceof GetMemberTreeItem) { + mem = (GetMemberTreeItem) item; + item = mem.object; + } + } while (item instanceof GetMemberTreeItem); + if (item instanceof GetVariableTreeItem) { + GetVariableTreeItem v = (GetVariableTreeItem) item; + item = new GetMemberTreeItem(null, new GetVariableTreeItem(null, new DirectValueTreeItem(null, 0, "_global", new ArrayList())), v.name); + if (mem != null) { + mem.object = item; + } + } + return first; + } + + private List typeToActions(List type, List value) { + List ret = new ArrayList<>(); + if (type.isEmpty()) { + return ret; + } + ret.add(pushConst(type.get(0))); + if (type.size() == 1 && (value != null)) { + ret.addAll(value); + ret.add(new ActionSetVariable()); + } else { + ret.add(new ActionGetVariable()); + } + for (int i = 1; i < type.size(); i++) { + ret.add(pushConst(type.get(i))); + if ((i == type.size() - 1) && (value != null)) { + ret.addAll(value); + ret.add(new ActionSetMember()); + } else { + ret.add(new ActionGetMember()); + } + } + return ret; + } + private List constantPool; + + public ActionScriptSourceGenerator(List constantPool) { + this.constantPool = constantPool; + } + + public List getConstantPool() { + return constantPool; + } + + public DirectValueTreeItem pushConstTargetItem(String s) { + int index = constantPool.indexOf(s); + if (index == -1) { + constantPool.add(s); + index = constantPool.indexOf(s); + } + return new DirectValueTreeItem(null, 0, new ConstantIndex(index), constantPool); + } + + public ActionPush pushConst(String s) { + int index = constantPool.indexOf(s); + if (index == -1) { + constantPool.add(s); + index = constantPool.indexOf(s); + } + return new ActionPush(new ConstantIndex(index)); + } + + public List generateTraits(List localData, boolean isInterface, GraphTargetItem name, GraphTargetItem extendsVal, List implementsStr, GraphTargetItem constructor, List functions, List> vars, List staticFunctions, List> staticVars) { + List extendsStr = getVarParts(extendsVal); + List ret = new ArrayList<>(); + List nameStr = getVarParts(name); + for (int i = 0; i < nameStr.size() - 1; i++) { + List notBody = new ArrayList<>(); + List globalClassTypeStr = new ArrayList<>(); + globalClassTypeStr.add("_global"); + for (int j = 0; j <= i; j++) { + globalClassTypeStr.add(nameStr.get(j)); + } + + List val = new ArrayList<>(); + val.add(new ActionPush((Long) 0L)); + val.add(pushConst("Object")); + val.add(new ActionNewObject()); + notBody.addAll(typeToActions(globalClassTypeStr, val)); + ret.addAll(typeToActions(globalClassTypeStr, null)); + ret.add(new ActionNot()); + ret.add(new ActionNot()); + ret.add(new ActionIf(Action.actionsToBytes(notBody, false, SWF.DEFAULT_VERSION).length)); + ret.addAll(notBody); + } + List ifbody = new ArrayList<>(); + List globalClassTypeStr = new ArrayList<>(); + globalClassTypeStr.add("_global"); + globalClassTypeStr.addAll(nameStr); + + + ParsedSymbol s = null; + List constr = new ArrayList<>(); + + + + if (constructor == null) { + List val = new ArrayList<>(); + val.add(new ActionDefineFunction("", new ArrayList(), 0, SWF.DEFAULT_VERSION)); + if (!isInterface) { + val.add(new ActionStoreRegister(1)); + } + constr.addAll(typeToActions(globalClassTypeStr, val)); + } else { + constr.addAll(toActionList(((FunctionTreeItem) constructor).toSource(localData, this))); + constr.add(new ActionStoreRegister(1)); + constr = (typeToActions(globalClassTypeStr, constr)); + } + if (!isInterface) { + for (GraphTargetItem f : staticFunctions) { + FunctionTreeItem fi = (FunctionTreeItem) f; + ifbody.add(new ActionPush(new RegisterNumber(1/*static*/))); + ifbody.add(new ActionPush(getName(fi.calculatedFunctionName))); + ifbody.addAll(toActionList(fi.toSource(localData, this))); + ifbody.add(new ActionSetMember()); + } + for (GraphTargetItem f : functions) { + FunctionTreeItem fi = (FunctionTreeItem) f; + ifbody.add(new ActionPush(new RegisterNumber(2/*instance*/))); + ifbody.add(new ActionPush(getName(fi.calculatedFunctionName))); + ifbody.addAll(toActionList(fi.toSource(localData, this))); + ifbody.add(new ActionSetMember()); + } + for (MyEntry en : staticVars) { + ifbody.add(new ActionPush(new RegisterNumber(1/*static*/))); + ifbody.add(new ActionPush(getName(en.key))); + ifbody.addAll(toActionList(en.value.toSource(localData, this))); + ifbody.add(new ActionSetMember()); + } + for (MyEntry en : vars) { + ifbody.add(new ActionPush(new RegisterNumber(2/*instance*/))); + ifbody.add(new ActionPush(getName(en.key))); + ifbody.addAll(toActionList(en.value.toSource(localData, this))); + ifbody.add(new ActionSetMember()); + } + } + + if (!isInterface) { + ifbody.add(new ActionPush((Long) 1L)); + ifbody.add(new ActionPush(new Null())); + ifbody.addAll(typeToActions(globalClassTypeStr, null)); + ifbody.add(pushConst("prototype")); + ifbody.add(new ActionGetMember()); + ifbody.add(new ActionPush((Long) 3L)); + ifbody.add(pushConst("ASSetPropFlags")); + ifbody.add(new ActionCallFunction()); + } + + if (constr.isEmpty()) { + List val = new ArrayList<>(); + val.add(new ActionDefineFunction("", new ArrayList(), 0, SWF.DEFAULT_VERSION)); + if (!isInterface) { + val.add(new ActionStoreRegister(1)); + } + constr.addAll(typeToActions(globalClassTypeStr, val)); + } + if (!extendsStr.isEmpty()) { + constr.addAll(typeToActions(globalClassTypeStr, null)); + constr.addAll(typeToActions(extendsStr, null)); + constr.add(new ActionExtends()); + } + if (!isInterface) { + constr.add(new ActionPush(new RegisterNumber(1))); + constr.add(pushConst("prototype")); + constr.add(new ActionGetMember()); + constr.add(new ActionStoreRegister(2)); + constr.add(new ActionPop()); + } + + if (!implementsStr.isEmpty()) { + for (GraphTargetItem imp : implementsStr) { + List impList = getVarParts(imp); + List globImp = new ArrayList<>(); + globImp.add("_global"); + globImp.addAll(impList); + constr.addAll(typeToActions(globImp, null)); + } + constr.add(new ActionPush(new Long(implementsStr.size()))); + constr.addAll(typeToActions(globalClassTypeStr, null)); + constr.add(new ActionImplementsOp()); + } + ifbody.addAll(0, constr); + + ret.addAll(typeToActions(globalClassTypeStr, null)); + ret.add(new ActionNot()); + ret.add(new ActionNot()); + ret.add(new ActionIf(Action.actionsToBytes(ifbody, false, SWF.DEFAULT_VERSION).length)); + ret.addAll(ifbody); + ret.add(new ActionPop()); + return ret; + } + + @Override + public List generate(List localData, CommaExpressionItem item) { + if (item.commands.isEmpty()) { + return new ArrayList<>(); + } + + //We need to handle commands and last expression separately, otherwise last expression result will be popped + List cmds = new ArrayList<>(item.commands); + GraphTargetItem lastExpr = cmds.remove(cmds.size() - 1); + List ret = new ArrayList<>(); + ret.addAll(generate(localData, cmds)); + ret.addAll(lastExpr.toSource(localData, this)); + return ret; + } +} diff --git a/trunk/src/com/jpexs/decompiler/flash/action/parser/script/LexBufferer.java b/trunk/src/com/jpexs/decompiler/flash/action/parser/script/LexBufferer.java new file mode 100644 index 000000000..86b2a54e9 --- /dev/null +++ b/trunk/src/com/jpexs/decompiler/flash/action/parser/script/LexBufferer.java @@ -0,0 +1,48 @@ +/* + * 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 . + */ +package com.jpexs.decompiler.flash.action.parser.script; + +import java.util.ArrayList; +import java.util.List; + +/** + * + * @author JPEXS + */ +public class LexBufferer implements LexListener { + + private List items = new ArrayList<>(); + + @Override + public void onLex(ParsedSymbol s) { + items.add(s); + } + + @Override + public void onPushBack(ParsedSymbol s) { + if (items.get(items.size() - 1) == s) { + items.remove(items.size() - 1); + } + } + + public void pushAllBack(ActionScriptLexer lexer) { + for (int i = items.size() - 1; i >= 0; i--) { + lexer.pushback(items.get(i)); + } + items.clear(); + } +} diff --git a/trunk/src/com/jpexs/decompiler/flash/action/parser/script/LexListener.java b/trunk/src/com/jpexs/decompiler/flash/action/parser/script/LexListener.java new file mode 100644 index 000000000..543276992 --- /dev/null +++ b/trunk/src/com/jpexs/decompiler/flash/action/parser/script/LexListener.java @@ -0,0 +1,28 @@ +/* + * 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 . + */ +package com.jpexs.decompiler.flash.action.parser.script; + +/** + * + * @author JPEXS + */ +public interface LexListener { + + public void onLex(ParsedSymbol s); + + public void onPushBack(ParsedSymbol s); +} diff --git a/trunk/src/com/jpexs/decompiler/flash/action/parser/script/SymbolType.java b/trunk/src/com/jpexs/decompiler/flash/action/parser/script/SymbolType.java index 3fac4adc8..38fbfee44 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/parser/script/SymbolType.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/parser/script/SymbolType.java @@ -171,5 +171,14 @@ public enum SymbolType { UNDEFINED, NEWLINE, NAN, - GETVERSION + GETVERSION, + CALL, + LOADMOVIENUM, + LOADVARIABLESNUM, + PRINT, + PRINTNUM, + PRINTASBITMAP, + PRINTASBITMAPNUM, + UNLOADMOVIE, + UNLOADMOVIENUM } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/parser/script/actionscript.flex b/trunk/src/com/jpexs/decompiler/flash/action/parser/script/actionscript.flex index 7a2062ab1..e4072995a 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/parser/script/actionscript.flex +++ b/trunk/src/com/jpexs/decompiler/flash/action/parser/script/actionscript.flex @@ -17,6 +17,8 @@ package com.jpexs.decompiler.flash.action.parser.script; import com.jpexs.decompiler.flash.action.parser.ParseException; import java.util.Stack; +import java.util.List; +import java.util.ArrayList; %% @@ -43,17 +45,43 @@ import java.util.Stack; public int yyline() { return yyline+1; } + private List listeners=new ArrayList<>(); + + public void addListener(LexListener listener){ + listeners.add(listener); + } + + public void removeListener(LexListener listener){ + listeners.remove(listener); + } + + public void informListenersLex(ParsedSymbol s){ + for(LexListener l:listeners){ + l.onLex(s); + } + } + + public void informListenersPushBack(ParsedSymbol s){ + for(LexListener l:listeners){ + l.onPushBack(s); + } + } public void pushback(ParsedSymbol symb) { pushedBack.push(symb); last = null; + informListenersPushBack(symb); } ParsedSymbol last; public ParsedSymbol lex() throws java.io.IOException, ParseException{ + ParsedSymbol ret=null; if(!pushedBack.isEmpty()){ - return last=pushedBack.pop(); + ret = last = pushedBack.pop(); + }else{ + ret = last = yylex(); } - return last=yylex(); + informListenersLex(ret); + return ret; } %} @@ -195,6 +223,15 @@ SingleCharacter = [^\r\n\'\\] "Infinity" { return new ParsedSymbol(SymbolGroup.GLOBALCONST,SymbolType.INFINITY,yytext()); } "NaN" { return new ParsedSymbol(SymbolGroup.GLOBALCONST,SymbolType.NAN,yytext()); } "getVersion" { return new ParsedSymbol(SymbolGroup.GLOBALFUNC,SymbolType.GETVERSION,yytext()); } + "call" { return new ParsedSymbol(SymbolGroup.GLOBALFUNC,SymbolType.CALL,yytext()); } + "loadMovieNum" { return new ParsedSymbol(SymbolGroup.GLOBALFUNC,SymbolType.LOADMOVIENUM,yytext()); } + "loadVariablesNum" { return new ParsedSymbol(SymbolGroup.GLOBALFUNC,SymbolType.LOADVARIABLESNUM,yytext()); } + "printAsBitmapNum" { return new ParsedSymbol(SymbolGroup.GLOBALFUNC,SymbolType.PRINTASBITMAPNUM,yytext()); } + "printNum" { return new ParsedSymbol(SymbolGroup.GLOBALFUNC,SymbolType.PRINTNUM,yytext()); } + "printAsBitmap" { return new ParsedSymbol(SymbolGroup.GLOBALFUNC,SymbolType.PRINTASBITMAP,yytext()); } + "print" { return new ParsedSymbol(SymbolGroup.GLOBALFUNC,SymbolType.PRINT,yytext()); } + "unloadMovie" { return new ParsedSymbol(SymbolGroup.GLOBALFUNC,SymbolType.UNLOADMOVIE,yytext()); } + "unloadMovieNum" { return new ParsedSymbol(SymbolGroup.GLOBALFUNC,SymbolType.UNLOADMOVIENUM,yytext()); } /* operators */ diff --git a/trunk/src/com/jpexs/decompiler/flash/action/swf3/ActionGetURL.java b/trunk/src/com/jpexs/decompiler/flash/action/swf3/ActionGetURL.java index 30db033ee..cc0877f1a 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/swf3/ActionGetURL.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/swf3/ActionGetURL.java @@ -41,6 +41,12 @@ public class ActionGetURL extends Action { public String urlString; public String targetString; + public ActionGetURL(String urlString, String targetString) { + super(0x83, 0); + this.urlString = urlString; + this.targetString = targetString; + } + public ActionGetURL(int actionLength, SWFInputStream sis, int version) throws IOException { super(0x83, actionLength); //byte data[] = sis.readBytes(actionLength); @@ -86,10 +92,10 @@ public class ActionGetURL extends Action { try { int num = Integer.valueOf(targetString.substring(levelPrefix.length())); if (urlString.equals("")) { - output.add(new UnLoadMovieNumTreeItem(this, num)); + output.add(new UnLoadMovieNumTreeItem(this, new DirectValueTreeItem((Long) (long) (int) num))); } else { DirectValueTreeItem urlStringDi = new DirectValueTreeItem(null, 0, urlString, new ArrayList()); - output.add(new LoadMovieNumTreeItem(this, urlStringDi, num, 1/*GET*/)); + output.add(new LoadMovieNumTreeItem(this, urlStringDi, new DirectValueTreeItem((Long) (long) (int) num), 1/*GET*/)); } return; } catch (NumberFormatException nfe) { diff --git a/trunk/src/com/jpexs/decompiler/flash/action/swf3/ActionGotoFrame.java b/trunk/src/com/jpexs/decompiler/flash/action/swf3/ActionGotoFrame.java index ec0e647d6..fa3b5c26b 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/swf3/ActionGotoFrame.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/swf3/ActionGotoFrame.java @@ -67,6 +67,6 @@ public class ActionGotoFrame extends Action { @Override public void translate(Stack stack, List output, java.util.HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) { - output.add(new GotoFrameTreeItem(this, frame + 1)); + output.add(new GotoFrameTreeItem(this, frame)); } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/swf3/ActionNextFrame.java b/trunk/src/com/jpexs/decompiler/flash/action/swf3/ActionNextFrame.java index fcc80c900..66c3ee265 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/swf3/ActionNextFrame.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/swf3/ActionNextFrame.java @@ -17,7 +17,7 @@ package com.jpexs.decompiler.flash.action.swf3; import com.jpexs.decompiler.flash.action.Action; -import com.jpexs.decompiler.flash.action.treemodel.SimpleActionTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.NextFrameTreeItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; import java.util.HashMap; import java.util.List; @@ -36,6 +36,6 @@ public class ActionNextFrame extends Action { @Override public void translate(Stack stack, List output, java.util.HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) { - output.add(new SimpleActionTreeItem(this, "nextFrame()")); + output.add(new NextFrameTreeItem(this)); } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/swf3/ActionPlay.java b/trunk/src/com/jpexs/decompiler/flash/action/swf3/ActionPlay.java index 55e821bb5..d214cb29b 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/swf3/ActionPlay.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/swf3/ActionPlay.java @@ -17,7 +17,7 @@ package com.jpexs.decompiler.flash.action.swf3; import com.jpexs.decompiler.flash.action.Action; -import com.jpexs.decompiler.flash.action.treemodel.SimpleActionTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.PlayTreeItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; import java.util.HashMap; import java.util.List; @@ -36,6 +36,6 @@ public class ActionPlay extends Action { @Override public void translate(Stack stack, List output, java.util.HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) { - output.add(new SimpleActionTreeItem(this, "Play()")); + output.add(new PlayTreeItem(this)); } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/swf3/ActionPrevFrame.java b/trunk/src/com/jpexs/decompiler/flash/action/swf3/ActionPrevFrame.java index b6c9ac9b7..b64121570 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/swf3/ActionPrevFrame.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/swf3/ActionPrevFrame.java @@ -17,7 +17,7 @@ package com.jpexs.decompiler.flash.action.swf3; import com.jpexs.decompiler.flash.action.Action; -import com.jpexs.decompiler.flash.action.treemodel.SimpleActionTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.PrevFrameTreeItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; import java.util.HashMap; import java.util.List; @@ -36,6 +36,6 @@ public class ActionPrevFrame extends Action { @Override public void translate(Stack stack, List output, java.util.HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) { - output.add(new SimpleActionTreeItem(this, "prevFrame()")); + output.add(new PrevFrameTreeItem(this)); } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/swf3/ActionSetTarget.java b/trunk/src/com/jpexs/decompiler/flash/action/swf3/ActionSetTarget.java index 0525907f7..d43373f98 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/swf3/ActionSetTarget.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/swf3/ActionSetTarget.java @@ -34,6 +34,11 @@ public class ActionSetTarget extends Action { public String targetName; + public ActionSetTarget(String targetName) { + super(0x8B, 0); + this.targetName = targetName; + } + public ActionSetTarget(int actionLength, SWFInputStream sis, int version) throws IOException { super(0x8B, actionLength); //byte data[] = sis.readBytes(actionLength); diff --git a/trunk/src/com/jpexs/decompiler/flash/action/swf3/ActionStop.java b/trunk/src/com/jpexs/decompiler/flash/action/swf3/ActionStop.java index d4106cffd..b7ba44e65 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/swf3/ActionStop.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/swf3/ActionStop.java @@ -17,7 +17,7 @@ package com.jpexs.decompiler.flash.action.swf3; import com.jpexs.decompiler.flash.action.Action; -import com.jpexs.decompiler.flash.action.treemodel.SimpleActionTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.StopTreeItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; import java.util.HashMap; import java.util.List; @@ -36,6 +36,6 @@ public class ActionStop extends Action { @Override public void translate(Stack stack, List output, java.util.HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) { - output.add(new SimpleActionTreeItem(this, "stop()")); + output.add(new StopTreeItem(this)); } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/swf3/ActionStopSounds.java b/trunk/src/com/jpexs/decompiler/flash/action/swf3/ActionStopSounds.java index 25c8c2b74..00a472f0f 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/swf3/ActionStopSounds.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/swf3/ActionStopSounds.java @@ -17,7 +17,7 @@ package com.jpexs.decompiler.flash.action.swf3; import com.jpexs.decompiler.flash.action.Action; -import com.jpexs.decompiler.flash.action.treemodel.SimpleActionTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.StopAllSoundsTreeItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; import java.util.HashMap; import java.util.List; @@ -36,6 +36,6 @@ public class ActionStopSounds extends Action { @Override public void translate(Stack stack, List output, java.util.HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) { - output.add(new SimpleActionTreeItem(this, "stopAllSounds()")); + output.add(new StopAllSoundsTreeItem(this)); } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/swf3/ActionToggleQuality.java b/trunk/src/com/jpexs/decompiler/flash/action/swf3/ActionToggleQuality.java index f0ff29562..60380afb5 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/swf3/ActionToggleQuality.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/swf3/ActionToggleQuality.java @@ -17,7 +17,7 @@ package com.jpexs.decompiler.flash.action.swf3; import com.jpexs.decompiler.flash.action.Action; -import com.jpexs.decompiler.flash.action.treemodel.SimpleActionTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.ToggleHighQualityTreeItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; import java.util.HashMap; import java.util.List; @@ -36,6 +36,6 @@ public class ActionToggleQuality extends Action { @Override public void translate(Stack stack, List output, java.util.HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) { - output.add(new SimpleActionTreeItem(this, "toggleHighQuality()")); + output.add(new ToggleHighQualityTreeItem(this)); } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/swf4/ActionEndDrag.java b/trunk/src/com/jpexs/decompiler/flash/action/swf4/ActionEndDrag.java index b70bbb56d..2fa568ba8 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/swf4/ActionEndDrag.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/swf4/ActionEndDrag.java @@ -17,7 +17,7 @@ package com.jpexs.decompiler.flash.action.swf4; import com.jpexs.decompiler.flash.action.Action; -import com.jpexs.decompiler.flash.action.treemodel.SimpleActionTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.StopDragTreeItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; import java.util.HashMap; import java.util.List; @@ -36,6 +36,6 @@ public class ActionEndDrag extends Action { @Override public void translate(Stack stack, List output, java.util.HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) { - output.add(new SimpleActionTreeItem(this, "stopDrag()")); + output.add(new StopDragTreeItem(this)); } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/swf4/ActionGetURL2.java b/trunk/src/com/jpexs/decompiler/flash/action/swf4/ActionGetURL2.java index 271f0cb6c..f814da7f2 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/swf4/ActionGetURL2.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/swf4/ActionGetURL2.java @@ -36,6 +36,7 @@ import com.jpexs.decompiler.flash.action.treemodel.UnLoadMovieTreeItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Stack; @@ -95,9 +96,8 @@ public class ActionGetURL2 extends Action { GraphTargetItem targetString = stack.pop(); GraphTargetItem urlString = stack.pop(); Integer num = null; - if (targetString instanceof DirectValueTreeItem) { - DirectValueTreeItem di = (DirectValueTreeItem) targetString; - Object res = di.getResult(); + if (targetString.isCompileTime()) { + Object res = targetString.getResult(); if (res instanceof String) { String tarStr = (String) res; String levelPrefix = "_level"; @@ -111,7 +111,7 @@ public class ActionGetURL2 extends Action { } if (loadVariablesFlag) { if (num != null) { - output.add(new LoadVariablesNumTreeItem(this, urlString, num, sendVarsMethod)); + output.add(new LoadVariablesNumTreeItem(this, urlString, new DirectValueTreeItem(null, 0, (Long) (long) (int) num, new ArrayList()), sendVarsMethod)); } else { output.add(new LoadVariablesTreeItem(this, urlString, targetString, sendVarsMethod)); } @@ -125,24 +125,26 @@ public class ActionGetURL2 extends Action { String printPrefix = "print:#"; String printAsBitmapPrefix = "printasbitmap:#"; String urlStr = null; - if ((urlString instanceof DirectValueTreeItem) && (urlString.getResult() instanceof String)) { + if (urlString.isCompileTime() && (urlString.getResult() instanceof String)) { urlStr = (String) urlString.getResult(); } + if (num != null) { if ("".equals(urlStr)) { - output.add(new UnLoadMovieNumTreeItem(this, num)); + output.add(new UnLoadMovieNumTreeItem(this, new DirectValueTreeItem(null, 0, (Long) (long) (int) num, new ArrayList()))); } else if (urlStr != null && urlStr.startsWith(printPrefix)) { - output.add(new PrintNumTreeItem(this, num, urlStr.substring(printPrefix.length()))); + output.add(new PrintNumTreeItem(this, new DirectValueTreeItem((Long) (long) (int) num), + new DirectValueTreeItem(urlStr.substring(printPrefix.length())))); } else if (urlStr != null && urlStr.startsWith(printAsBitmapPrefix)) { - output.add(new PrintAsBitmapNumTreeItem(this, num, urlStr.substring(printAsBitmapPrefix.length()))); + output.add(new PrintAsBitmapNumTreeItem(this, new DirectValueTreeItem((Long) (long) (int) num), new DirectValueTreeItem(urlStr.substring(printAsBitmapPrefix.length())))); } else { - output.add(new LoadMovieNumTreeItem(this, urlString, num, sendVarsMethod)); + output.add(new LoadMovieNumTreeItem(this, urlString, new DirectValueTreeItem(null, 0, (Long) (long) (int) num, new ArrayList()), sendVarsMethod)); } } else { if (urlStr != null && urlStr.startsWith(printPrefix)) { - output.add(new PrintTreeItem(this, targetString, urlStr.substring(printPrefix.length()))); + output.add(new PrintTreeItem(this, targetString, new DirectValueTreeItem(urlStr.substring(printPrefix.length())))); } else if (urlStr != null && urlStr.startsWith(printAsBitmapPrefix)) { - output.add(new PrintAsBitmapTreeItem(this, targetString, urlStr.substring(printAsBitmapPrefix.length()))); + output.add(new PrintAsBitmapTreeItem(this, targetString, new DirectValueTreeItem(urlStr.substring(printAsBitmapPrefix.length())))); } else { output.add(new GetURL2TreeItem(this, urlString, targetString, sendVarsMethod)); } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/swf4/ActionPush.java b/trunk/src/com/jpexs/decompiler/flash/action/swf4/ActionPush.java index ab6be7fd4..623149e5d 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/swf4/ActionPush.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/swf4/ActionPush.java @@ -37,6 +37,8 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Stack; +import java.util.logging.Level; +import java.util.logging.Logger; public class ActionPush extends Action { @@ -169,11 +171,12 @@ public class ActionPush extends Action { } sos.close(); } catch (IOException e) { + Logger.getLogger(ActionPush.class.getName()).log(Level.SEVERE, "Error during push to bytes", e); } return surroundWithAction(baos.toByteArray(), version); } - public ActionPush(Object... values) throws IOException, ParseException { + public ActionPush(Object... values) { super(0x96, 0); this.values = new ArrayList<>(); for (Object o : values) { diff --git a/trunk/src/com/jpexs/decompiler/flash/action/swf4/ActionStringLength.java b/trunk/src/com/jpexs/decompiler/flash/action/swf4/ActionStringLength.java index 1a67a4796..0279629e4 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/swf4/ActionStringLength.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/swf4/ActionStringLength.java @@ -17,7 +17,7 @@ package com.jpexs.decompiler.flash.action.swf4; import com.jpexs.decompiler.flash.action.Action; -import com.jpexs.decompiler.flash.action.treemodel.operations.StringLengthTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.StringLengthTreeItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; import java.util.HashMap; import java.util.List; diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/AsciiToCharTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/AsciiToCharTreeItem.java index fe7b070b3..b0007d60e 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/AsciiToCharTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/AsciiToCharTreeItem.java @@ -16,8 +16,10 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.swf4.ActionAsciiToChar; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; import java.util.List; public class AsciiToCharTreeItem extends TreeItem { @@ -40,4 +42,14 @@ public class AsciiToCharTreeItem extends TreeItem { ret.addAll(value.getNeededSources()); return ret; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, value, new ActionAsciiToChar()); + } + + @Override + public boolean hasReturnValue() { + return true; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/CallFunctionTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/CallFunctionTreeItem.java index 79188f3c6..3bb9405bb 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/CallFunctionTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/CallFunctionTreeItem.java @@ -16,8 +16,10 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.swf5.ActionCallFunction; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; import java.util.List; public class CallFunctionTreeItem extends TreeItem { @@ -95,4 +97,14 @@ public class CallFunctionTreeItem extends TreeItem { } return true; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, toSourceCall(localData, generator, arguments), functionName, new ActionCallFunction()); + } + + @Override + public boolean hasReturnValue() { + return true; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/CallMethodTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/CallMethodTreeItem.java index 4587866e3..4bbf3857d 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/CallMethodTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/CallMethodTreeItem.java @@ -16,9 +16,11 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.swf5.ActionCallMethod; 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.graph.SourceGenerator; import java.util.List; public class CallMethodTreeItem extends TreeItem { @@ -74,4 +76,14 @@ public class CallMethodTreeItem extends TreeItem { } return ret; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, toSourceCall(localData, generator, arguments), scriptObject, methodName, new ActionCallMethod()); + } + + @Override + public boolean hasReturnValue() { + return true; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/CallTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/CallTreeItem.java index 88c692bdc..11d7a7ab6 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/CallTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/CallTreeItem.java @@ -16,8 +16,10 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.swf4.ActionCall; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; import java.util.List; public class CallTreeItem extends TreeItem { @@ -40,4 +42,14 @@ public class CallTreeItem extends TreeItem { ret.addAll(value.getNeededSources()); return ret; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, value, new ActionCall()); + } + + @Override + public boolean hasReturnValue() { + return false; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/CastOpTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/CastOpTreeItem.java index 024561921..94fadeea2 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/CastOpTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/CastOpTreeItem.java @@ -16,8 +16,10 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.swf7.ActionCastOp; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; import com.jpexs.decompiler.flash.helpers.Helper; import java.util.List; @@ -44,4 +46,14 @@ public class CastOpTreeItem extends TreeItem { ret.addAll(object.getNeededSources()); return ret; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, constructor, object, new ActionCastOp()); + } + + @Override + public boolean hasReturnValue() { + return true; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/CharToAsciiTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/CharToAsciiTreeItem.java index a5299164d..a8bb05586 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/CharToAsciiTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/CharToAsciiTreeItem.java @@ -16,8 +16,10 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.swf4.ActionCharToAscii; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; import java.util.List; public class CharToAsciiTreeItem extends TreeItem { @@ -65,4 +67,14 @@ public class CharToAsciiTreeItem extends TreeItem { } return 0; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, value, new ActionCharToAscii()); + } + + @Override + public boolean hasReturnValue() { + return true; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/CloneSpriteTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/CloneSpriteTreeItem.java index c4327952d..c5b68de70 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/CloneSpriteTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/CloneSpriteTreeItem.java @@ -16,8 +16,10 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.swf4.ActionCloneSprite; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; import java.util.List; public class CloneSpriteTreeItem extends TreeItem { @@ -46,4 +48,14 @@ public class CloneSpriteTreeItem extends TreeItem { ret.addAll(depth.getNeededSources()); return ret; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, source, target, depth, new ActionCloneSprite()); + } + + @Override + public boolean hasReturnValue() { + return false; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/DecrementTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/DecrementTreeItem.java index f9a5bbf4b..13e560b0d 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/DecrementTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/DecrementTreeItem.java @@ -16,9 +16,11 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.swf5.ActionDecrement; 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.SourceGenerator; import java.util.List; public class DecrementTreeItem extends TreeItem { @@ -51,4 +53,14 @@ public class DecrementTreeItem extends TreeItem { ret.addAll(object.getNeededSources()); return ret; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, object, new ActionDecrement()); + } + + @Override + public boolean hasReturnValue() { + return true; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/DefineLocalTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/DefineLocalTreeItem.java index 3eaddf3b6..8ddcad0de 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/DefineLocalTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/DefineLocalTreeItem.java @@ -16,8 +16,11 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.swf5.ActionDefineLocal; +import com.jpexs.decompiler.flash.action.swf5.ActionDefineLocal2; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; import java.util.List; public class DefineLocalTreeItem extends TreeItem implements SetTypeTreeItem { @@ -72,4 +75,19 @@ public class DefineLocalTreeItem extends TreeItem implements SetTypeTreeItem { public GraphTargetItem getObject() { return new DefineLocalTreeItem(src, name, null); } + + @Override + public List toSource(List localData, SourceGenerator generator) { + if (value == null) { + return toSourceMerge(localData, generator, name, new ActionDefineLocal2()); + } else { + return toSourceMerge(localData, generator, name, value, new ActionDefineLocal()); + } + + } + + @Override + public boolean hasReturnValue() { + return false; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/DefineRegisterTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/DefineRegisterTreeItem.java new file mode 100644 index 000000000..9094a6141 --- /dev/null +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/DefineRegisterTreeItem.java @@ -0,0 +1,43 @@ +/* + * 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 . + */ +package com.jpexs.decompiler.flash.action.treemodel; + +/** + * + * @author JPEXS + */ +public class DefineRegisterTreeItem extends TreeItem { + + private String identifier; + private int register; + + public DefineRegisterTreeItem(String identifier, int register) { + super(null, PRECEDENCE_PRIMARY); + this.identifier = identifier; + this.register = register; + } + + @Override + public String toString(ConstantPool constants) { + return "var " + identifier; + } + + @Override + public boolean hasReturnValue() { + return false; + } +} diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/DeleteTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/DeleteTreeItem.java index d0015771d..256c86253 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/DeleteTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/DeleteTreeItem.java @@ -16,8 +16,10 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.swf5.ActionDelete; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; import java.util.List; public class DeleteTreeItem extends TreeItem { @@ -46,4 +48,14 @@ public class DeleteTreeItem extends TreeItem { ret.addAll(propertyName.getNeededSources()); return ret; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, object, propertyName, new ActionDelete()); + } + + @Override + public boolean hasReturnValue() { + return false; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/DirectValueTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/DirectValueTreeItem.java index 3f8548eb6..fc08d8807 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/DirectValueTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/DirectValueTreeItem.java @@ -16,13 +16,16 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.swf4.ActionPush; import com.jpexs.decompiler.flash.action.swf4.ConstantIndex; 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.graph.SourceGenerator; import com.jpexs.decompiler.flash.helpers.Helper; +import java.util.ArrayList; import java.util.List; import java.util.Objects; @@ -32,6 +35,10 @@ public class DirectValueTreeItem extends TreeItem { public List constants; public GraphTargetItem computedRegValue; + public DirectValueTreeItem(Object o) { + this(null, 0, o, new ArrayList()); + } + public DirectValueTreeItem(GraphSourceItem instruction, int instructionPos, Object value, List constants) { super(instruction, PRECEDENCE_PRIMARY); this.constants = constants; @@ -141,8 +148,7 @@ public class DirectValueTreeItem extends TreeItem { @Override public boolean isCompileTime() { - return (value instanceof Double) || (value instanceof Float) || (value instanceof Boolean) || (value instanceof Long) || (value instanceof Null) || (computedRegValue != null && computedRegValue.isCompileTime()) //||(value instanceof String) || (value instanceof ConstantIndex) - ; + return (value instanceof Double) || (value instanceof Float) || (value instanceof Boolean) || (value instanceof Long) || (value instanceof Null) || (computedRegValue != null && computedRegValue.isCompileTime()) || (value instanceof String) || (value instanceof ConstantIndex); } @Override @@ -192,4 +198,14 @@ public class DirectValueTreeItem extends TreeItem { } return true; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, new ActionPush(value)); + } + + @Override + public boolean hasReturnValue() { + return true; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/EachTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/EachTreeItem.java deleted file mode 100644 index b22192908..000000000 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/EachTreeItem.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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 . - */ -package com.jpexs.decompiler.flash.action.treemodel; - -import com.jpexs.decompiler.flash.graph.GraphSourceItem; -import java.util.List; - -public class EachTreeItem extends TreeItem { - - public TreeItem object; - public TreeItem collection; - - public EachTreeItem(GraphSourceItem instruction, TreeItem object, TreeItem collection) { - super(instruction, NOPRECEDENCE); - this.object = object; - this.collection = collection; - } - - @Override - public String toString(ConstantPool constants) { - return hilight("each (") + object.toString(constants) + hilight(" in ") + collection.toString(constants) + ")"; - } - - @Override - public List getNeededSources() { - List ret = super.getNeededSources(); - ret.addAll(object.getNeededSources()); - ret.addAll(collection.getNeededSources()); - return ret; - } -} diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/EnumerateTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/EnumerateTreeItem.java index 516130eae..6d33efa69 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/EnumerateTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/EnumerateTreeItem.java @@ -41,4 +41,9 @@ public class EnumerateTreeItem extends TreeItem { ret.addAll(object.getNeededSources()); return ret; } + + @Override + public boolean hasReturnValue() { + return true; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/EvalTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/EvalTreeItem.java index dbb0e9d72..97aad62cf 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/EvalTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/EvalTreeItem.java @@ -16,8 +16,11 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.swf4.ActionGetVariable; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.List; /** * @@ -34,4 +37,14 @@ public class EvalTreeItem extends TreeItem { public String toString(ConstantPool constants) { return hilight("eval(") + value.toString(constants) + hilight(")"); } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, value, new ActionGetVariable()); + } + + @Override + public boolean hasReturnValue() { + return true; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/ExtendsTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/ExtendsTreeItem.java index 2731ae349..6bd2f9bec 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/ExtendsTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/ExtendsTreeItem.java @@ -47,4 +47,9 @@ public class ExtendsTreeItem extends TreeItem { ret.addAll(superclass.getNeededSources()); return ret; } + + @Override + public boolean hasReturnValue() { + return false; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/FSCommand2TreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/FSCommand2TreeItem.java index 162623bca..09e82ab1d 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/FSCommand2TreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/FSCommand2TreeItem.java @@ -16,8 +16,12 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.flashlite.ActionFSCommand2; +import com.jpexs.decompiler.flash.action.swf4.ActionPush; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.ArrayList; import java.util.List; public class FSCommand2TreeItem extends TreeItem { @@ -51,4 +55,21 @@ public class FSCommand2TreeItem extends TreeItem { } return ret; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + List ret = new ArrayList<>(); + for (GraphTargetItem a : arguments) { + ret.addAll(a.toSource(localData, generator)); + } + ret.addAll(command.toSource(localData, generator)); + ret.add(new ActionPush((Long) (long) arguments.size())); + ret.add(new ActionFSCommand2()); + return ret; + } + + @Override + public boolean hasReturnValue() { + return true; //FIXME ? + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/FSCommandTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/FSCommandTreeItem.java index 0b62620f4..70321e9ce 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/FSCommandTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/FSCommandTreeItem.java @@ -16,8 +16,11 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.swf3.ActionGetURL; import com.jpexs.decompiler.flash.graph.GraphSourceItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; import com.jpexs.decompiler.flash.helpers.Helper; +import java.util.List; /** * @@ -36,4 +39,14 @@ public class FSCommandTreeItem extends TreeItem { public String toString(ConstantPool constants) { return hilight("fscommand(\"") + Helper.escapeString(command) + hilight("\")"); } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, new ActionGetURL("FSCommand:" + command, "")); + } + + @Override + public boolean hasReturnValue() { + return false; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/FunctionTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/FunctionTreeItem.java index 502c72e5f..68a2393c8 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/FunctionTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/FunctionTreeItem.java @@ -16,10 +16,23 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.SWF; +import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.parser.script.ActionScriptSourceGenerator; +import com.jpexs.decompiler.flash.action.swf4.ActionPush; +import com.jpexs.decompiler.flash.action.swf4.RegisterNumber; +import com.jpexs.decompiler.flash.action.swf5.ActionDefineFunction; +import com.jpexs.decompiler.flash.action.swf5.ActionStoreRegister; +import com.jpexs.decompiler.flash.action.swf7.ActionDefineFunction2; import com.jpexs.decompiler.flash.graph.Graph; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import com.jpexs.decompiler.flash.helpers.Helper; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.TreeSet; public class FunctionTreeItem extends TreeItem { @@ -29,6 +42,12 @@ public class FunctionTreeItem extends TreeItem { public List paramNames; public GraphTargetItem calculatedFunctionName; private int regStart; + public static final int REGISTER_THIS = 1; + public static final int REGISTER_ARGUMENTS = 2; + public static final int REGISTER_SUPER = 3; + public static final int REGISTER_ROOT = 4; + public static final int REGISTER_PARENT = 5; + public static final int REGISTER_GLOBAL = 6; public FunctionTreeItem(GraphSourceItem instruction, String functionName, List paramNames, List actions, List constants, int regStart) { super(instruction, PRECEDENCE_PRIMARY); @@ -104,4 +123,182 @@ public class FunctionTreeItem extends TreeItem { public boolean needsNewLine() { return true; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + List ret = new ArrayList<>(); + ActionScriptSourceGenerator asGenerator = (ActionScriptSourceGenerator) generator; + List paramRegs = new ArrayList<>(); + @SuppressWarnings("unchecked") + List localDataCopy = (List) Helper.deepCopy(localData); + HashMap registerVars = asGenerator.getRegisterVars(localDataCopy); + registerVars.put("_parent", REGISTER_PARENT); + registerVars.put("_root", REGISTER_ROOT); + registerVars.put("super", REGISTER_SUPER); + registerVars.put("arguments", REGISTER_ARGUMENTS); + registerVars.put("this", REGISTER_THIS); + registerVars.put("_global", REGISTER_GLOBAL); + for (int i = 0; i < paramNames.size(); i++) { + registerVars.put(paramNames.get(i), (7 + i)); //(paramNames.size() - i))); + } + boolean preloadParentFlag = false; + boolean preloadRootFlag = false; + boolean preloadSuperFlag = false; + boolean preloadArgumentsFlag = false; + boolean preloadThisFlag = false; + boolean preloadGlobalFlag = false; + + boolean suppressParentFlag = false; + boolean suppressArgumentsFlag = false; + boolean suppressThisFlag = false; + TreeSet usedRegisters = new TreeSet<>(); + if (actions != null && !actions.isEmpty()) { + asGenerator.setInFunction(localDataCopy, true); + List body = asGenerator.toActionList(asGenerator.generate(localDataCopy, actions)); + for (Action a : body) { + if (a instanceof ActionStoreRegister) { + usedRegisters.add(((ActionStoreRegister) a).registerNumber); + } + if (a instanceof ActionPush) { + ActionPush ap = (ActionPush) a; + for (Object o : ap.values) { + if (o instanceof RegisterNumber) { + usedRegisters.add(((RegisterNumber) o).number); + } + } + } + } + if (usedRegisters.contains(REGISTER_PARENT)) { + preloadParentFlag = true; + } else { + suppressParentFlag = true; + } + if (usedRegisters.contains(REGISTER_ROOT)) { + preloadRootFlag = true; + } + if (usedRegisters.contains(REGISTER_SUPER)) { + preloadSuperFlag = true; + } + if (usedRegisters.contains(REGISTER_ARGUMENTS)) { + preloadArgumentsFlag = true; + } else { + suppressArgumentsFlag = true; + } + if (usedRegisters.contains(REGISTER_THIS)) { + preloadThisFlag = true; + } else { + suppressThisFlag = true; + } + if (usedRegisters.contains(REGISTER_GLOBAL)) { + preloadGlobalFlag = true; + } + + int newpos = 1; + HashMap registerMap = new HashMap<>(); + if (preloadThisFlag) { + registerMap.put(REGISTER_THIS, newpos); + newpos++; + } + if (preloadArgumentsFlag) { + registerMap.put(REGISTER_ARGUMENTS, newpos); + newpos++; + } + if (preloadSuperFlag) { + registerMap.put(REGISTER_SUPER, newpos); + newpos++; + } + if (preloadRootFlag) { + registerMap.put(REGISTER_ROOT, newpos); + newpos++; + } + if (preloadParentFlag) { + registerMap.put(REGISTER_PARENT, newpos); + newpos++; + } + if (preloadGlobalFlag) { + registerMap.put(REGISTER_GLOBAL, newpos); + newpos++; + } + if (newpos < 1) { + newpos = 1; + } + for (int i = 0; i < 256; i++) { + if (usedRegisters.contains(7 + i)) { + registerMap.put(7 + i, newpos); + if (i < paramNames.size()) { + paramRegs.add(newpos); + } + newpos++; + } else { + if (i < paramNames.size()) { + paramRegs.add(0); + } + } + } + + TreeSet usedRegisters2 = new TreeSet<>(); + for (int i : usedRegisters) { + if (registerMap.get(i) == null) { + usedRegisters2.add(i); + } else { + usedRegisters2.add(registerMap.get(i)); + } + } + usedRegisters = usedRegisters2; + + for (Action a : body) { + if (a instanceof ActionStoreRegister) { + if (registerMap.containsKey(((ActionStoreRegister) a).registerNumber)) { + ((ActionStoreRegister) a).registerNumber = registerMap.get(((ActionStoreRegister) a).registerNumber); + } + } + if (a instanceof ActionPush) { + ActionPush ap = (ActionPush) a; + for (Object o : ap.values) { + if (o instanceof RegisterNumber) { + if (registerMap.containsKey(((RegisterNumber) o).number)) { + ((RegisterNumber) o).number = registerMap.get(((RegisterNumber) o).number); + } + } + } + } + } + ret.addAll(body); + } else { + for (int i = 0; i < paramNames.size(); i++) { + paramRegs.add(1 + i); + } + } + int len = Action.actionsToBytes(asGenerator.toActionList(ret), false, SWF.DEFAULT_VERSION).length; + if ((!preloadParentFlag) + && (!preloadRootFlag) + && (!preloadSuperFlag) + && (!preloadArgumentsFlag) + && (!preloadThisFlag) + && (!preloadGlobalFlag) + && (suppressArgumentsFlag) + && (suppressThisFlag) + && (suppressParentFlag) + && usedRegisters.isEmpty()) { + ret.add(0, new ActionDefineFunction(functionName, paramNames, len, SWF.DEFAULT_VERSION)); + } else { + ret.add(0, new ActionDefineFunction2(functionName, + preloadParentFlag, + preloadRootFlag, + suppressParentFlag, + preloadSuperFlag, + suppressArgumentsFlag, + preloadArgumentsFlag, + suppressThisFlag, + preloadThisFlag, + preloadGlobalFlag, + usedRegisters.isEmpty() ? 0 : (usedRegisters.last() + 1), len, SWF.DEFAULT_VERSION, paramNames, paramRegs)); + } + return ret; + } + + @Override + public boolean hasReturnValue() { + return false; //function actually returns itself, but here is false for generator to not add Pop + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/GetMemberTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/GetMemberTreeItem.java index 009745dd7..6c171ab58 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/GetMemberTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/GetMemberTreeItem.java @@ -16,8 +16,10 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.swf5.ActionGetMember; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; import java.util.List; public class GetMemberTreeItem extends TreeItem { @@ -73,4 +75,14 @@ public class GetMemberTreeItem extends TreeItem { } return true; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, object, memberName, new ActionGetMember()); + } + + @Override + public boolean hasReturnValue() { + return true; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/GetPropertyTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/GetPropertyTreeItem.java index 795878ce3..74510774c 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/GetPropertyTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/GetPropertyTreeItem.java @@ -17,8 +17,11 @@ package com.jpexs.decompiler.flash.action.treemodel; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.swf4.ActionGetProperty; +import com.jpexs.decompiler.flash.action.swf4.ActionPush; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; import java.util.List; public class GetPropertyTreeItem extends TreeItem { @@ -46,4 +49,14 @@ public class GetPropertyTreeItem extends TreeItem { ret.addAll(target.getNeededSources()); return ret; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, target, new ActionPush((Long) (long) propertyIndex), new ActionGetProperty()); + } + + @Override + public boolean hasReturnValue() { + return true; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/GetTimeTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/GetTimeTreeItem.java index c2642fdde..c95309a61 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/GetTimeTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/GetTimeTreeItem.java @@ -16,7 +16,10 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.swf4.ActionGetTime; import com.jpexs.decompiler.flash.graph.GraphSourceItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.List; import java.util.Random; public class GetTimeTreeItem extends TreeItem { @@ -39,4 +42,14 @@ public class GetTimeTreeItem extends TreeItem { public Object getResult() { return (Double) (double) new Random().nextInt(10000) + 1000; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, new ActionGetTime()); + } + + @Override + public boolean hasReturnValue() { + return true; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/GetURL2TreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/GetURL2TreeItem.java index 52a1e858b..2a71fa02f 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/GetURL2TreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/GetURL2TreeItem.java @@ -16,8 +16,10 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.swf4.ActionGetURL2; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; import java.util.List; public class GetURL2TreeItem extends TreeItem { @@ -53,4 +55,14 @@ public class GetURL2TreeItem extends TreeItem { ret.addAll(targetString.getNeededSources()); return ret; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, urlString, targetString, new ActionGetURL2(sendVarsMethod, false, false)); + } + + @Override + public boolean hasReturnValue() { + return false; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/GetURLTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/GetURLTreeItem.java index 7396f9889..0aeda1c96 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/GetURLTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/GetURLTreeItem.java @@ -16,8 +16,11 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.swf3.ActionGetURL; import com.jpexs.decompiler.flash.graph.GraphSourceItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; import com.jpexs.decompiler.flash.helpers.Helper; +import java.util.List; public class GetURLTreeItem extends TreeItem { @@ -34,4 +37,14 @@ public class GetURLTreeItem extends TreeItem { this.urlString = urlString; this.targetString = targetString; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, new ActionGetURL(urlString, targetString)); + } + + @Override + public boolean hasReturnValue() { + return false; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/GetVariableTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/GetVariableTreeItem.java index eee15fe34..01447c3c7 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/GetVariableTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/GetVariableTreeItem.java @@ -16,9 +16,11 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.swf4.ActionGetVariable; 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.graph.SourceGenerator; import java.util.List; public class GetVariableTreeItem extends TreeItem { @@ -99,4 +101,14 @@ public class GetVariableTreeItem extends TreeItem { } return true; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, name, new ActionGetVariable()); + } + + @Override + public boolean hasReturnValue() { + return true; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/GetVersionTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/GetVersionTreeItem.java index 510794bae..76048ad3d 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/GetVersionTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/GetVersionTreeItem.java @@ -16,7 +16,11 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.swf4.ActionGetVariable; +import com.jpexs.decompiler.flash.action.swf4.ActionPush; import com.jpexs.decompiler.flash.graph.GraphSourceItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.List; /** * @@ -32,4 +36,14 @@ public class GetVersionTreeItem extends TreeItem { public String toString(ConstantPool constants) { return hilight("getVersion()"); } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, new ActionPush("/:$version"), new ActionGetVariable()); + } + + @Override + public boolean hasReturnValue() { + return true; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/GotoFrame2TreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/GotoFrame2TreeItem.java index 49c5fa066..64f560de7 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/GotoFrame2TreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/GotoFrame2TreeItem.java @@ -16,8 +16,10 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.swf4.ActionGotoFrame2; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; import java.util.List; public class GotoFrame2TreeItem extends TreeItem { @@ -50,4 +52,14 @@ public class GotoFrame2TreeItem extends TreeItem { ret.addAll(frame.getNeededSources()); return ret; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, frame, new ActionGotoFrame2(playFlag, sceneBiasFlag, sceneBias)); + } + + @Override + public boolean hasReturnValue() { + return false; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/GotoFrameTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/GotoFrameTreeItem.java index f4ad673bd..9b4f8a47b 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/GotoFrameTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/GotoFrameTreeItem.java @@ -16,7 +16,10 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.swf3.ActionGotoFrame; import com.jpexs.decompiler.flash.graph.GraphSourceItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.List; public class GotoFrameTreeItem extends TreeItem { @@ -29,6 +32,16 @@ public class GotoFrameTreeItem extends TreeItem { @Override public String toString(ConstantPool constants) { - return hilight("gotoAndStop(") + frame + hilight(")"); + return hilight("gotoAndStop(") + (frame + 1) + hilight(")"); + } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, new ActionGotoFrame(frame)); + } + + @Override + public boolean hasReturnValue() { + return false; } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/GotoLabelTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/GotoLabelTreeItem.java index d05f6fba0..59e3da066 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/GotoLabelTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/GotoLabelTreeItem.java @@ -16,8 +16,11 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.swf3.ActionGoToLabel; import com.jpexs.decompiler.flash.graph.GraphSourceItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; import com.jpexs.decompiler.flash.helpers.Helper; +import java.util.List; public class GotoLabelTreeItem extends TreeItem { @@ -32,4 +35,14 @@ public class GotoLabelTreeItem extends TreeItem { public String toString(ConstantPool constants) { return hilight("gotoAndStop(\"") + Helper.escapeString(label) + hilight("\")"); } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, new ActionGoToLabel(label)); + } + + @Override + public boolean hasReturnValue() { + return false; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/ImplementsOpTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/ImplementsOpTreeItem.java index eb2c0a43f..74379d9a9 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/ImplementsOpTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/ImplementsOpTreeItem.java @@ -53,4 +53,9 @@ public class ImplementsOpTreeItem extends TreeItem { } return ret; } + + @Override + public boolean hasReturnValue() { + return true; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/IncrementTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/IncrementTreeItem.java index 32b94e5c7..0db9c45a9 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/IncrementTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/IncrementTreeItem.java @@ -16,9 +16,11 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.swf5.ActionIncrement; 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.SourceGenerator; import java.util.List; public class IncrementTreeItem extends TreeItem { @@ -51,4 +53,14 @@ public class IncrementTreeItem extends TreeItem { ret.addAll(object.getNeededSources()); return ret; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, object, new ActionIncrement()); + } + + @Override + public boolean hasReturnValue() { + return true; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/InitArrayTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/InitArrayTreeItem.java index e27469b1c..f7a9a457e 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/InitArrayTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/InitArrayTreeItem.java @@ -16,9 +16,11 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.swf5.ActionInitArray; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphSourceItemPos; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; import java.util.List; public class InitArrayTreeItem extends TreeItem { @@ -50,4 +52,14 @@ public class InitArrayTreeItem extends TreeItem { } return ret; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, toSourceCall(localData, generator, values), new ActionInitArray()); + } + + @Override + public boolean hasReturnValue() { + return true; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/InitObjectTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/InitObjectTreeItem.java index ab9dd7526..3e847cec8 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/InitObjectTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/InitObjectTreeItem.java @@ -16,9 +16,12 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.swf4.ActionPush; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; import com.jpexs.decompiler.flash.graph.TernarOpItem; +import java.util.ArrayList; import java.util.List; public class InitObjectTreeItem extends TreeItem { @@ -59,4 +62,20 @@ public class InitObjectTreeItem extends TreeItem { } return ret; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + List ret = new ArrayList<>(); + for (int i = values.size() - 1; i >= 0; i--) { + ret.addAll(names.get(i).toSource(localData, generator)); + ret.addAll(values.get(i).toSource(localData, generator)); + } + ret.add(new ActionPush((Long) (long) values.size())); + return ret; + } + + @Override + public boolean hasReturnValue() { + return true; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/LoadMovieNumTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/LoadMovieNumTreeItem.java index e16697d3c..ad30a5a56 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/LoadMovieNumTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/LoadMovieNumTreeItem.java @@ -16,8 +16,13 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.parser.script.ActionScriptSourceGenerator; +import com.jpexs.decompiler.flash.action.swf4.ActionGetURL2; +import com.jpexs.decompiler.flash.action.treemodel.operations.AddTreeItem; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.List; /** * @@ -26,10 +31,10 @@ import com.jpexs.decompiler.flash.graph.GraphTargetItem; public class LoadMovieNumTreeItem extends TreeItem { private GraphTargetItem urlString; - private int num; + private GraphTargetItem num; private int method; - public LoadMovieNumTreeItem(GraphSourceItem instruction, GraphTargetItem urlString, int num, int method) { + public LoadMovieNumTreeItem(GraphSourceItem instruction, GraphTargetItem urlString, GraphTargetItem num, int method) { super(instruction, PRECEDENCE_PRIMARY); this.urlString = urlString; this.num = num; @@ -47,4 +52,15 @@ public class LoadMovieNumTreeItem extends TreeItem { } return hilight("loadMovieNum(") + urlString.toString(constants) + hilight(",") + num + hilight(methodStr + ")"); } + + @Override + public List toSource(List localData, SourceGenerator generator) { + ActionScriptSourceGenerator asGenerator = (ActionScriptSourceGenerator) generator; + return toSourceMerge(localData, generator, urlString, new AddTreeItem(src, asGenerator.pushConstTargetItem("_level"), num, true), new ActionGetURL2(method, false, false)); + } + + @Override + public boolean hasReturnValue() { + return false; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/LoadMovieTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/LoadMovieTreeItem.java index 2ea6d0852..c73427836 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/LoadMovieTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/LoadMovieTreeItem.java @@ -16,8 +16,11 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.swf4.ActionGetURL2; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.List; /** * @@ -47,4 +50,14 @@ public class LoadMovieTreeItem extends TreeItem { } return hilight("loadMovie(") + urlString.toString(constants) + hilight(",") + targetString.toString(constants) + hilight(methodStr + ")"); } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, urlString, targetString, new ActionGetURL2(method, true, false)); + } + + @Override + public boolean hasReturnValue() { + return false; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/LoadVariablesNumTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/LoadVariablesNumTreeItem.java index c30eadb67..7a7eee5c8 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/LoadVariablesNumTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/LoadVariablesNumTreeItem.java @@ -16,8 +16,13 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.parser.script.ActionScriptSourceGenerator; +import com.jpexs.decompiler.flash.action.swf4.ActionGetURL2; +import com.jpexs.decompiler.flash.action.treemodel.operations.AddTreeItem; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.List; /** * @@ -26,10 +31,10 @@ import com.jpexs.decompiler.flash.graph.GraphTargetItem; public class LoadVariablesNumTreeItem extends TreeItem { private GraphTargetItem urlString; - private int num; + private GraphTargetItem num; private int method; - public LoadVariablesNumTreeItem(GraphSourceItem instruction, GraphTargetItem urlString, int num, int method) { + public LoadVariablesNumTreeItem(GraphSourceItem instruction, GraphTargetItem urlString, GraphTargetItem num, int method) { super(instruction, PRECEDENCE_PRIMARY); this.urlString = urlString; this.num = num; @@ -47,4 +52,15 @@ public class LoadVariablesNumTreeItem extends TreeItem { } return hilight("loadVariablesNum(") + urlString.toString(constants) + hilight(",") + num + hilight(methodStr + ")"); } + + @Override + public List toSource(List localData, SourceGenerator generator) { + ActionScriptSourceGenerator asGenerator = (ActionScriptSourceGenerator) generator; + return toSourceMerge(localData, generator, urlString, new AddTreeItem(src, asGenerator.pushConstTargetItem("_level"), num, true), new ActionGetURL2(method, false, true)); + } + + @Override + public boolean hasReturnValue() { + return false; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/LoadVariablesTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/LoadVariablesTreeItem.java index c8d4f76e1..31e6cbbb4 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/LoadVariablesTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/LoadVariablesTreeItem.java @@ -16,8 +16,11 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.swf4.ActionGetURL2; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.List; /** * @@ -47,4 +50,14 @@ public class LoadVariablesTreeItem extends TreeItem { } return hilight("loadVariables(") + urlString.toString(constants) + hilight(",") + targetString.toString(constants) + hilight(methodStr + ")"); } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, urlString, targetString, new ActionGetURL2(method, false, true)); + } + + @Override + public boolean hasReturnValue() { + return false; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/MBAsciiToCharTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/MBAsciiToCharTreeItem.java index 762d477d5..c08cfa809 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/MBAsciiToCharTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/MBAsciiToCharTreeItem.java @@ -16,8 +16,10 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.swf4.ActionMBAsciiToChar; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; import java.util.List; public class MBAsciiToCharTreeItem extends TreeItem { @@ -40,4 +42,14 @@ public class MBAsciiToCharTreeItem extends TreeItem { ret.addAll(value.getNeededSources()); return ret; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, value, new ActionMBAsciiToChar()); + } + + @Override + public boolean hasReturnValue() { + return true; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/MBCharToAsciiTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/MBCharToAsciiTreeItem.java index 9b12247b0..937e0faea 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/MBCharToAsciiTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/MBCharToAsciiTreeItem.java @@ -16,8 +16,10 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.swf4.ActionMBCharToAscii; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; import java.util.List; public class MBCharToAsciiTreeItem extends TreeItem { @@ -40,4 +42,14 @@ public class MBCharToAsciiTreeItem extends TreeItem { ret.addAll(value.getNeededSources()); return ret; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, value, new ActionMBCharToAscii()); + } + + @Override + public boolean hasReturnValue() { + return true; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/MBStringExtractTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/MBStringExtractTreeItem.java index f07b53c78..af9c87d06 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/MBStringExtractTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/MBStringExtractTreeItem.java @@ -16,8 +16,10 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.swf4.ActionMBStringExtract; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; import java.util.List; public class MBStringExtractTreeItem extends TreeItem { @@ -46,4 +48,14 @@ public class MBStringExtractTreeItem extends TreeItem { ret.addAll(count.getNeededSources()); return ret; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, value, index, count, new ActionMBStringExtract()); + } + + @Override + public boolean hasReturnValue() { + return true; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/MBStringLengthTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/MBStringLengthTreeItem.java index 40be92108..8f7050ff5 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/MBStringLengthTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/MBStringLengthTreeItem.java @@ -16,8 +16,10 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.swf4.ActionMBStringLength; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; import java.util.List; public class MBStringLengthTreeItem extends TreeItem { @@ -43,4 +45,14 @@ public class MBStringLengthTreeItem extends TreeItem { ret.addAll(value.getNeededSources()); return ret; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, value, new ActionMBStringLength()); + } + + @Override + public boolean hasReturnValue() { + return true; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/NewMethodTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/NewMethodTreeItem.java index 86699b1ab..ff5b2e13c 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/NewMethodTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/NewMethodTreeItem.java @@ -16,9 +16,11 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.swf5.ActionNewMethod; 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.graph.SourceGenerator; import java.util.List; public class NewMethodTreeItem extends TreeItem { @@ -75,4 +77,14 @@ public class NewMethodTreeItem extends TreeItem { } return ret; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, toSourceCall(localData, generator, arguments), scriptObject, methodName, new ActionNewMethod()); + } + + @Override + public boolean hasReturnValue() { + return true; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/NewObjectTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/NewObjectTreeItem.java index 249a21650..b224433aa 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/NewObjectTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/NewObjectTreeItem.java @@ -16,8 +16,10 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.swf5.ActionNewObject; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; import java.util.List; public class NewObjectTreeItem extends TreeItem { @@ -52,4 +54,14 @@ public class NewObjectTreeItem extends TreeItem { } return ret; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, toSourceCall(localData, generator, arguments), objectName, new ActionNewObject()); + } + + @Override + public boolean hasReturnValue() { + return true; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/NextFrameTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/NextFrameTreeItem.java new file mode 100644 index 000000000..8aa701757 --- /dev/null +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/NextFrameTreeItem.java @@ -0,0 +1,44 @@ +/* + * 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 . + */ +package com.jpexs.decompiler.flash.action.treemodel; + +import com.jpexs.decompiler.flash.action.swf3.ActionNextFrame; +import com.jpexs.decompiler.flash.graph.GraphSourceItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.List; + +public class NextFrameTreeItem extends TreeItem { + + @Override + public String toString(ConstantPool constants) { + return hilight("nextFrame()"); + } + + public NextFrameTreeItem(GraphSourceItem instruction) { + super(instruction, PRECEDENCE_PRIMARY); + } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, new ActionNextFrame()); + } + + @Override + public boolean hasReturnValue() { + return false; + } +} diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/WaitForFrameTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/PlayTreeItem.java similarity index 61% rename from trunk/src/com/jpexs/decompiler/flash/action/treemodel/WaitForFrameTreeItem.java rename to trunk/src/com/jpexs/decompiler/flash/action/treemodel/PlayTreeItem.java index 173523e56..59faa0fe7 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/WaitForFrameTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/PlayTreeItem.java @@ -16,21 +16,29 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.swf3.ActionPlay; import com.jpexs.decompiler.flash.graph.GraphSourceItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.List; -public class WaitForFrameTreeItem extends TreeItem { - - public int frame; - public int skipCount; - - public WaitForFrameTreeItem(GraphSourceItem instruction, int frame, int skipCount) { - super(instruction, PRECEDENCE_PRIMARY); - this.frame = frame; - this.skipCount = skipCount; - } +public class PlayTreeItem extends TreeItem { @Override public String toString(ConstantPool constants) { - return hilight("waitForFrame(") + frame + "," + skipCount + hilight(")"); + return hilight("play()"); + } + + public PlayTreeItem(GraphSourceItem instruction) { + super(instruction, PRECEDENCE_PRIMARY); + } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, new ActionPlay()); + } + + @Override + public boolean hasReturnValue() { + return false; } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/PopTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/PopTreeItem.java index 145743985..e526f94dc 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/PopTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/PopTreeItem.java @@ -16,7 +16,10 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.swf4.ActionPop; import com.jpexs.decompiler.flash.graph.GraphSourceItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.List; /** * @@ -42,4 +45,14 @@ public class PopTreeItem extends TreeItem { public boolean isEmpty() { return true; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, new ActionPop()); + } + + @Override + public boolean hasReturnValue() { + return false; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/PostDecrementTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/PostDecrementTreeItem.java index 88471e25c..2cf88ea53 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/PostDecrementTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/PostDecrementTreeItem.java @@ -16,9 +16,20 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.swf4.ActionPop; +import com.jpexs.decompiler.flash.action.swf4.ActionPush; +import com.jpexs.decompiler.flash.action.swf4.ActionSetProperty; +import com.jpexs.decompiler.flash.action.swf4.ActionSetVariable; +import com.jpexs.decompiler.flash.action.swf4.RegisterNumber; +import com.jpexs.decompiler.flash.action.swf5.ActionDecrement; +import com.jpexs.decompiler.flash.action.swf5.ActionSetMember; +import com.jpexs.decompiler.flash.action.swf5.ActionStoreRegister; import com.jpexs.decompiler.flash.action.treemodel.operations.SubtractTreeItem; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.ArrayList; +import java.util.List; public class PostDecrementTreeItem extends TreeItem implements SetTypeTreeItem { @@ -62,6 +73,51 @@ public class PostDecrementTreeItem extends TreeItem implements SetTypeTreeItem { @Override public void setValue(GraphTargetItem value) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public List toSourceIgnoreReturnValue(List localData, SourceGenerator generator) { + List ret = new ArrayList<>(); + + if (object instanceof GetVariableTreeItem) { + GetVariableTreeItem gv = (GetVariableTreeItem) object; + ret.addAll(gv.toSource(localData, generator)); + ret.remove(ret.size() - 1); //ActionGetVariable + ret.addAll(gv.toSource(localData, generator)); + ret.add(new ActionDecrement()); + ret.add(new ActionSetVariable()); + } else if (object instanceof GetMemberTreeItem) { + GetMemberTreeItem mem = (GetMemberTreeItem) object; + ret.addAll(mem.toSource(localData, generator)); + ret.remove(ret.size() - 1); //ActionGetMember + ret.addAll(mem.toSource(localData, generator)); + ret.add(new ActionDecrement()); + ret.add(new ActionSetMember()); + } else if ((object instanceof DirectValueTreeItem) && ((DirectValueTreeItem) object).value instanceof RegisterNumber) { + RegisterNumber rn = (RegisterNumber) ((DirectValueTreeItem) object).value; + ret.add(new ActionPush(new RegisterNumber(rn.number))); + ret.add(new ActionDecrement()); + ret.add(new ActionStoreRegister(rn.number)); + ret.add(new ActionPop()); + } else if (object instanceof GetPropertyTreeItem) { + GetPropertyTreeItem gp = (GetPropertyTreeItem) object; + ret.addAll(gp.toSource(localData, generator)); + ret.remove(ret.size() - 1); + ret.addAll(gp.toSource(localData, generator)); + ret.add(new ActionDecrement()); + ret.add(new ActionSetProperty()); + } + return ret; + } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, object.toSource(localData, generator), toSourceIgnoreReturnValue(localData, generator)); + } + + @Override + public boolean hasReturnValue() { + return true; } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/PostIncrementTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/PostIncrementTreeItem.java index fd365c98a..7b5f14210 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/PostIncrementTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/PostIncrementTreeItem.java @@ -16,9 +16,20 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.swf4.ActionPop; +import com.jpexs.decompiler.flash.action.swf4.ActionPush; +import com.jpexs.decompiler.flash.action.swf4.ActionSetProperty; +import com.jpexs.decompiler.flash.action.swf4.ActionSetVariable; +import com.jpexs.decompiler.flash.action.swf4.RegisterNumber; +import com.jpexs.decompiler.flash.action.swf5.ActionIncrement; +import com.jpexs.decompiler.flash.action.swf5.ActionSetMember; +import com.jpexs.decompiler.flash.action.swf5.ActionStoreRegister; import com.jpexs.decompiler.flash.action.treemodel.operations.AddTreeItem; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.ArrayList; +import java.util.List; public class PostIncrementTreeItem extends TreeItem implements SetTypeTreeItem { @@ -64,4 +75,49 @@ public class PostIncrementTreeItem extends TreeItem implements SetTypeTreeItem { public void setValue(GraphTargetItem value) { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } + + @Override + public List toSourceIgnoreReturnValue(List localData, SourceGenerator generator) { + List ret = new ArrayList<>(); + + if (object instanceof GetVariableTreeItem) { + GetVariableTreeItem gv = (GetVariableTreeItem) object; + ret.addAll(gv.toSource(localData, generator)); + ret.remove(ret.size() - 1); //ActionGetVariable + ret.addAll(gv.toSource(localData, generator)); + ret.add(new ActionIncrement()); + ret.add(new ActionSetVariable()); + } else if (object instanceof GetMemberTreeItem) { + GetMemberTreeItem mem = (GetMemberTreeItem) object; + ret.addAll(mem.toSource(localData, generator)); + ret.remove(ret.size() - 1); //ActionGetMember + ret.addAll(mem.toSource(localData, generator)); + ret.add(new ActionIncrement()); + ret.add(new ActionSetMember()); + } else if ((object instanceof DirectValueTreeItem) && ((DirectValueTreeItem) object).value instanceof RegisterNumber) { + RegisterNumber rn = (RegisterNumber) ((DirectValueTreeItem) object).value; + ret.add(new ActionPush(new RegisterNumber(rn.number))); + ret.add(new ActionIncrement()); + ret.add(new ActionStoreRegister(rn.number)); + ret.add(new ActionPop()); + } else if (object instanceof GetPropertyTreeItem) { + GetPropertyTreeItem gp = (GetPropertyTreeItem) object; + ret.addAll(gp.toSource(localData, generator)); + ret.remove(ret.size() - 1); + ret.addAll(gp.toSource(localData, generator)); + ret.add(new ActionIncrement()); + ret.add(new ActionSetProperty()); + } + return ret; + } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, object.toSource(localData, generator), toSourceIgnoreReturnValue(localData, generator)); + } + + @Override + public boolean hasReturnValue() { + return true; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/PrevFrameTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/PrevFrameTreeItem.java new file mode 100644 index 000000000..9025b3011 --- /dev/null +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/PrevFrameTreeItem.java @@ -0,0 +1,44 @@ +/* + * 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 . + */ +package com.jpexs.decompiler.flash.action.treemodel; + +import com.jpexs.decompiler.flash.action.swf3.ActionPrevFrame; +import com.jpexs.decompiler.flash.graph.GraphSourceItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.List; + +public class PrevFrameTreeItem extends TreeItem { + + @Override + public String toString(ConstantPool constants) { + return hilight("prevFrame()"); + } + + public PrevFrameTreeItem(GraphSourceItem instruction) { + super(instruction, PRECEDENCE_PRIMARY); + } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, new ActionPrevFrame()); + } + + @Override + public boolean hasReturnValue() { + return false; + } +} diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/PrintAsBitmapNumTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/PrintAsBitmapNumTreeItem.java index d69ca3607..68d5dbcba 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/PrintAsBitmapNumTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/PrintAsBitmapNumTreeItem.java @@ -16,8 +16,13 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.parser.script.ActionScriptSourceGenerator; +import com.jpexs.decompiler.flash.action.swf4.ActionGetURL2; +import com.jpexs.decompiler.flash.action.treemodel.operations.AddTreeItem; import com.jpexs.decompiler.flash.graph.GraphSourceItem; -import com.jpexs.decompiler.flash.helpers.Helper; +import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.List; /** * @@ -25,10 +30,10 @@ import com.jpexs.decompiler.flash.helpers.Helper; */ public class PrintAsBitmapNumTreeItem extends TreeItem { - private int num; - private String boundingBox; + private GraphTargetItem num; + private GraphTargetItem boundingBox; - public PrintAsBitmapNumTreeItem(GraphSourceItem instruction, int num, String boundingBox) { + public PrintAsBitmapNumTreeItem(GraphSourceItem instruction, GraphTargetItem num, GraphTargetItem boundingBox) { super(instruction, PRECEDENCE_PRIMARY); this.num = num; this.boundingBox = boundingBox; @@ -36,6 +41,18 @@ public class PrintAsBitmapNumTreeItem extends TreeItem { @Override public String toString(ConstantPool constants) { - return hilight("printAsBitmapNum(") + num + hilight(",") + "\"" + Helper.escapeString(boundingBox) + "\"" + hilight(")"); + return hilight("printAsBitmapNum(") + num.toString(constants) + hilight(",") + boundingBox.toString(constants) + hilight(")"); + } + + @Override + public List toSource(List localData, SourceGenerator generator) { + ActionScriptSourceGenerator asGenerator = (ActionScriptSourceGenerator) generator; + + return toSourceMerge(localData, generator, new AddTreeItem(src, asGenerator.pushConstTargetItem("printasbitmap:#"), boundingBox, true), new AddTreeItem(src, asGenerator.pushConstTargetItem("_level"), num, true), new ActionGetURL2(0, false, false)); + } + + @Override + public boolean hasReturnValue() { + return false; } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/PrintAsBitmapTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/PrintAsBitmapTreeItem.java index 08bcd1fbe..939d8839c 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/PrintAsBitmapTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/PrintAsBitmapTreeItem.java @@ -16,9 +16,14 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.parser.script.ActionScriptSourceGenerator; +import com.jpexs.decompiler.flash.action.swf4.ActionGetURL2; +import com.jpexs.decompiler.flash.action.treemodel.operations.AddTreeItem; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; -import com.jpexs.decompiler.flash.helpers.Helper; +import static com.jpexs.decompiler.flash.graph.GraphTargetItem.PRECEDENCE_PRIMARY; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.List; /** * @@ -27,9 +32,9 @@ import com.jpexs.decompiler.flash.helpers.Helper; public class PrintAsBitmapTreeItem extends TreeItem { private GraphTargetItem target; - private String boundingBox; + private GraphTargetItem boundingBox; - public PrintAsBitmapTreeItem(GraphSourceItem instruction, GraphTargetItem target, String boundingBox) { + public PrintAsBitmapTreeItem(GraphSourceItem instruction, GraphTargetItem target, GraphTargetItem boundingBox) { super(instruction, PRECEDENCE_PRIMARY); this.target = target; this.boundingBox = boundingBox; @@ -37,6 +42,17 @@ public class PrintAsBitmapTreeItem extends TreeItem { @Override public String toString(ConstantPool constants) { - return hilight("printAsBitmap(") + target.toString(constants) + hilight(",") + "\"" + Helper.escapeString(boundingBox) + "\"" + hilight(")"); + return hilight("printAsBitmap(") + target.toString(constants) + hilight(",") + boundingBox.toString(constants) + hilight(")"); + } + + @Override + public List toSource(List localData, SourceGenerator generator) { + ActionScriptSourceGenerator asGenerator = (ActionScriptSourceGenerator) generator; + return toSourceMerge(localData, generator, new AddTreeItem(src, asGenerator.pushConstTargetItem("printasbitmap:#"), boundingBox, true), target, new ActionGetURL2(0, false, false)); + } + + @Override + public boolean hasReturnValue() { + return false; } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/PrintNumTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/PrintNumTreeItem.java index 9ca2493fe..456eb7d38 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/PrintNumTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/PrintNumTreeItem.java @@ -16,8 +16,13 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.parser.script.ActionScriptSourceGenerator; +import com.jpexs.decompiler.flash.action.swf4.ActionGetURL2; +import com.jpexs.decompiler.flash.action.treemodel.operations.AddTreeItem; import com.jpexs.decompiler.flash.graph.GraphSourceItem; -import com.jpexs.decompiler.flash.helpers.Helper; +import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.List; /** * @@ -25,10 +30,10 @@ import com.jpexs.decompiler.flash.helpers.Helper; */ public class PrintNumTreeItem extends TreeItem { - private int num; - private String boundingBox; + private GraphTargetItem num; + private GraphTargetItem boundingBox; - public PrintNumTreeItem(GraphSourceItem instruction, int num, String boundingBox) { + public PrintNumTreeItem(GraphSourceItem instruction, GraphTargetItem num, GraphTargetItem boundingBox) { super(instruction, PRECEDENCE_PRIMARY); this.num = num; this.boundingBox = boundingBox; @@ -36,6 +41,17 @@ public class PrintNumTreeItem extends TreeItem { @Override public String toString(ConstantPool constants) { - return hilight("printNum(") + num + hilight(",") + "\"" + Helper.escapeString(boundingBox) + "\"" + hilight(")"); + return hilight("printNum(") + num.toString(constants) + hilight(",") + boundingBox.toString(constants) + hilight(")"); + } + + @Override + public List toSource(List localData, SourceGenerator generator) { + ActionScriptSourceGenerator asGenerator = (ActionScriptSourceGenerator) generator; + return toSourceMerge(localData, generator, new AddTreeItem(src, asGenerator.pushConstTargetItem("print:#"), boundingBox, true), new AddTreeItem(src, asGenerator.pushConstTargetItem("_level"), num, true), new ActionGetURL2(0, false, false)); + } + + @Override + public boolean hasReturnValue() { + return false; } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/PrintTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/PrintTreeItem.java index 118be95a7..b8452ce43 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/PrintTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/PrintTreeItem.java @@ -16,9 +16,13 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.parser.script.ActionScriptSourceGenerator; +import com.jpexs.decompiler.flash.action.swf4.ActionGetURL2; +import com.jpexs.decompiler.flash.action.treemodel.operations.AddTreeItem; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; -import com.jpexs.decompiler.flash.helpers.Helper; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.List; /** * @@ -27,9 +31,9 @@ import com.jpexs.decompiler.flash.helpers.Helper; public class PrintTreeItem extends TreeItem { private GraphTargetItem target; - private String boundingBox; + private GraphTargetItem boundingBox; - public PrintTreeItem(GraphSourceItem instruction, GraphTargetItem target, String boundingBox) { + public PrintTreeItem(GraphSourceItem instruction, GraphTargetItem target, GraphTargetItem boundingBox) { super(instruction, PRECEDENCE_PRIMARY); this.target = target; this.boundingBox = boundingBox; @@ -37,6 +41,17 @@ public class PrintTreeItem extends TreeItem { @Override public String toString(ConstantPool constants) { - return hilight("print(") + target.toString(constants) + hilight(",") + "\"" + Helper.escapeString(boundingBox) + "\"" + hilight(")"); + return hilight("print(") + target.toString(constants) + hilight(",") + boundingBox.toString(constants) + hilight(")"); + } + + @Override + public List toSource(List localData, SourceGenerator generator) { + ActionScriptSourceGenerator asGenerator = (ActionScriptSourceGenerator) generator; + return toSourceMerge(localData, generator, new AddTreeItem(src, asGenerator.pushConstTargetItem("print:#"), boundingBox, true), target, new ActionGetURL2(0, false, false)); + } + + @Override + public boolean hasReturnValue() { + return false; } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/RandomNumberTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/RandomNumberTreeItem.java index 9cb7e1565..3e9768919 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/RandomNumberTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/RandomNumberTreeItem.java @@ -16,8 +16,10 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.swf4.ActionRandomNumber; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; import java.util.List; public class RandomNumberTreeItem extends TreeItem { @@ -40,4 +42,14 @@ public class RandomNumberTreeItem extends TreeItem { ret.addAll(maximum.getNeededSources()); return ret; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, maximum, new ActionRandomNumber()); + } + + @Override + public boolean hasReturnValue() { + return true; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/RemoveSpriteTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/RemoveSpriteTreeItem.java index df2e7e18d..150a26fe7 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/RemoveSpriteTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/RemoveSpriteTreeItem.java @@ -16,8 +16,10 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.swf4.ActionRemoveSprite; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; import java.util.List; public class RemoveSpriteTreeItem extends TreeItem { @@ -40,4 +42,14 @@ public class RemoveSpriteTreeItem extends TreeItem { ret.addAll(target.getNeededSources()); return ret; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, target, new ActionRemoveSprite()); + } + + @Override + public boolean hasReturnValue() { + return false; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/ReturnTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/ReturnTreeItem.java index 78810f784..cfe8b561d 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/ReturnTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/ReturnTreeItem.java @@ -16,9 +16,21 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.SWF; +import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.parser.script.ActionScriptSourceGenerator; +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.swf5.ActionEquals2; +import com.jpexs.decompiler.flash.action.swf5.ActionReturn; +import com.jpexs.decompiler.flash.ecma.Null; +import com.jpexs.decompiler.flash.ecma.Undefined; import com.jpexs.decompiler.flash.graph.ExitItem; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.ArrayList; import java.util.List; public class ReturnTreeItem extends TreeItem implements ExitItem { @@ -45,4 +57,33 @@ public class ReturnTreeItem extends TreeItem implements ExitItem { public boolean isCompileTime() { return true; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + ActionScriptSourceGenerator asGenerator = (ActionScriptSourceGenerator) generator; + List ret = new ArrayList<>(); + int forinlevel = asGenerator.getForInLevel(localData); + for (int i = 0; i < forinlevel; i++) { //Must POP all remaining values from enumerations (for..in) + List forinret = new ArrayList<>(); + forinret.add(new ActionPush(new Null())); + forinret.add(new ActionEquals2()); + forinret.add(new ActionNot()); + ActionIf aforinif = new ActionIf(0); + forinret.add(aforinif); + aforinif.setJumpOffset(-Action.actionsToBytes(forinret, false, SWF.DEFAULT_VERSION).length); + ret.addAll(forinret); + } + if (value == null) { + ret.add(new ActionPush(new Undefined())); + } else { + ret.addAll(value.toSource(localData, generator)); + } + ret.add(new ActionReturn()); + return ret; + } + + @Override + public boolean hasReturnValue() { + return false; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/SetMemberTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/SetMemberTreeItem.java index 745cc7475..d6124d9c0 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/SetMemberTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/SetMemberTreeItem.java @@ -16,9 +16,15 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.parser.script.ActionScriptSourceGenerator; +import com.jpexs.decompiler.flash.action.swf4.ActionPush; +import com.jpexs.decompiler.flash.action.swf4.RegisterNumber; +import com.jpexs.decompiler.flash.action.swf5.ActionSetMember; +import com.jpexs.decompiler.flash.action.swf5.ActionStoreRegister; import com.jpexs.decompiler.flash.graph.GraphPart; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; import java.util.List; public class SetMemberTreeItem extends TreeItem implements SetTypeTreeItem { @@ -87,4 +93,21 @@ public class SetMemberTreeItem extends TreeItem implements SetTypeTreeItem { public boolean hasSideEffect() { return true; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + ActionScriptSourceGenerator asGenerator = (ActionScriptSourceGenerator) generator; + int tmpReg = asGenerator.getTempRegister(localData); + return toSourceMerge(localData, generator, object, objectName, value, new ActionStoreRegister(tmpReg), new ActionSetMember(), new ActionPush(new RegisterNumber(tmpReg))); + } + + @Override + public List toSourceIgnoreReturnValue(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, object, objectName, value, new ActionSetMember()); + } + + @Override + public boolean hasReturnValue() { + return false; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/SetPropertyTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/SetPropertyTreeItem.java index c4300454a..8c78e5847 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/SetPropertyTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/SetPropertyTreeItem.java @@ -17,9 +17,15 @@ package com.jpexs.decompiler.flash.action.treemodel; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.parser.script.ActionScriptSourceGenerator; +import com.jpexs.decompiler.flash.action.swf4.ActionPush; +import com.jpexs.decompiler.flash.action.swf4.ActionSetProperty; +import com.jpexs.decompiler.flash.action.swf4.RegisterNumber; +import com.jpexs.decompiler.flash.action.swf5.ActionStoreRegister; import com.jpexs.decompiler.flash.graph.GraphPart; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; import java.util.List; public class SetPropertyTreeItem extends TreeItem implements SetTypeTreeItem { @@ -86,4 +92,21 @@ public class SetPropertyTreeItem extends TreeItem implements SetTypeTreeItem { public boolean hasSideEffect() { return true; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + ActionScriptSourceGenerator asGenerator = (ActionScriptSourceGenerator) generator; + int tmpReg = asGenerator.getTempRegister(localData); + return toSourceMerge(localData, generator, target, new ActionPush((Long) (long) propertyIndex), value, new ActionStoreRegister(tmpReg), new ActionSetProperty(), new ActionPush(new RegisterNumber(tmpReg))); + } + + @Override + public List toSourceIgnoreReturnValue(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, target, new ActionPush((Long) (long) propertyIndex), value, new ActionSetProperty()); + } + + @Override + public boolean hasReturnValue() { + return false; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/SetTarget2TreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/SetTarget2TreeItem.java index a48b13062..9e4da8275 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/SetTarget2TreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/SetTarget2TreeItem.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.action.treemodel; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; import java.util.List; public class SetTarget2TreeItem extends TreeItem { @@ -40,4 +41,14 @@ public class SetTarget2TreeItem extends TreeItem { ret.addAll(target.getNeededSources()); return ret; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean hasReturnValue() { + return false; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/SetTargetTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/SetTargetTreeItem.java index 5108e300e..b67b806e1 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/SetTargetTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/SetTargetTreeItem.java @@ -17,7 +17,9 @@ package com.jpexs.decompiler.flash.action.treemodel; import com.jpexs.decompiler.flash.graph.GraphSourceItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; import com.jpexs.decompiler.flash.helpers.Helper; +import java.util.List; public class SetTargetTreeItem extends TreeItem { @@ -32,4 +34,14 @@ public class SetTargetTreeItem extends TreeItem { public String toString(ConstantPool constants) { return hilight("tellTarget(\"") + Helper.escapeString(target) + hilight("\")"); } + + @Override + public List toSource(List localData, SourceGenerator generator) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean hasReturnValue() { + return false; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/SetVariableTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/SetVariableTreeItem.java index 31d84fbc2..f01fee433 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/SetVariableTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/SetVariableTreeItem.java @@ -16,9 +16,15 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.parser.script.ActionScriptSourceGenerator; +import com.jpexs.decompiler.flash.action.swf4.ActionPush; +import com.jpexs.decompiler.flash.action.swf4.ActionSetVariable; +import com.jpexs.decompiler.flash.action.swf4.RegisterNumber; +import com.jpexs.decompiler.flash.action.swf5.ActionStoreRegister; import com.jpexs.decompiler.flash.graph.GraphPart; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; import java.util.List; public class SetVariableTreeItem extends TreeItem implements SetTypeTreeItem { @@ -89,4 +95,21 @@ public class SetVariableTreeItem extends TreeItem implements SetTypeTreeItem { public boolean hasSideEffect() { return true; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + ActionScriptSourceGenerator asGenerator = (ActionScriptSourceGenerator) generator; + int tmpReg = asGenerator.getTempRegister(localData); + return toSourceMerge(localData, generator, name, value, new ActionStoreRegister(tmpReg), new ActionSetVariable(), new ActionPush(new RegisterNumber(tmpReg))); + } + + @Override + public List toSourceIgnoreReturnValue(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, name, value, new ActionSetVariable()); + } + + @Override + public boolean hasReturnValue() { + return false; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/StartDragTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/StartDragTreeItem.java index 3ee1c5a19..338f4f64e 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/StartDragTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/StartDragTreeItem.java @@ -16,9 +16,11 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.swf4.ActionStartDrag; 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.SourceGenerator; import java.util.List; public class StartDragTreeItem extends TreeItem { @@ -64,4 +66,24 @@ public class StartDragTreeItem extends TreeItem { ret.addAll(y2.getNeededSources()); return ret; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + boolean hasConstrains = true; + if (constrain instanceof DirectValueTreeItem) { + if (Double.compare(EcmaScript.toNumber(constrain.getResult()), 0) == 0) { + hasConstrains = false; + } + } + if (hasConstrains) { + return toSourceMerge(localData, generator, x1, y1, x2, y2, constrain, lockCenter, target, new ActionStartDrag()); + } else { + return toSourceMerge(localData, generator, constrain, lockCenter, target, new ActionStartDrag()); + } + } + + @Override + public boolean hasReturnValue() { + return false; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/StopAllSoundsTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/StopAllSoundsTreeItem.java new file mode 100644 index 000000000..00f853059 --- /dev/null +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/StopAllSoundsTreeItem.java @@ -0,0 +1,44 @@ +/* + * 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 . + */ +package com.jpexs.decompiler.flash.action.treemodel; + +import com.jpexs.decompiler.flash.action.swf3.ActionStopSounds; +import com.jpexs.decompiler.flash.graph.GraphSourceItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.List; + +public class StopAllSoundsTreeItem extends TreeItem { + + @Override + public String toString(ConstantPool constants) { + return hilight("stopAllSounds()"); + } + + public StopAllSoundsTreeItem(GraphSourceItem instruction) { + super(instruction, PRECEDENCE_PRIMARY); + } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, new ActionStopSounds()); + } + + @Override + public boolean hasReturnValue() { + return false; + } +} diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/VoidTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/StopDragTreeItem.java similarity index 61% rename from trunk/src/com/jpexs/decompiler/flash/action/treemodel/VoidTreeItem.java rename to trunk/src/com/jpexs/decompiler/flash/action/treemodel/StopDragTreeItem.java index 2def3e7ee..c9f3dee29 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/VoidTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/StopDragTreeItem.java @@ -16,19 +16,29 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.swf4.ActionEndDrag; import com.jpexs.decompiler.flash.graph.GraphSourceItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.List; -public class VoidTreeItem extends TreeItem { - - public TreeItem value; - - public VoidTreeItem(GraphSourceItem instruction, TreeItem value) { - super(instruction, PRECEDENCE_PRIMARY); - this.value = value; - } +public class StopDragTreeItem extends TreeItem { @Override public String toString(ConstantPool constants) { - return value.toString(constants); + return hilight("stopDrag()"); + } + + public StopDragTreeItem(GraphSourceItem instruction) { + super(instruction, PRECEDENCE_PRIMARY); + } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, new ActionEndDrag()); + } + + @Override + public boolean hasReturnValue() { + return false; } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/SimpleActionTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/StopTreeItem.java similarity index 61% rename from trunk/src/com/jpexs/decompiler/flash/action/treemodel/SimpleActionTreeItem.java rename to trunk/src/com/jpexs/decompiler/flash/action/treemodel/StopTreeItem.java index 52256df4f..78b611c41 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/SimpleActionTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/StopTreeItem.java @@ -16,19 +16,29 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.swf3.ActionStop; import com.jpexs.decompiler.flash.graph.GraphSourceItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.List; -public class SimpleActionTreeItem extends TreeItem { - - private String actionString; +public class StopTreeItem extends TreeItem { @Override public String toString(ConstantPool constants) { - return hilight(actionString); + return hilight("stop()"); } - public SimpleActionTreeItem(GraphSourceItem instruction, String actionString) { + public StopTreeItem(GraphSourceItem instruction) { super(instruction, PRECEDENCE_PRIMARY); - this.actionString = actionString; + } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, new ActionStop()); + } + + @Override + public boolean hasReturnValue() { + return false; } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/StoreRegisterTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/StoreRegisterTreeItem.java index b6078b743..2cb69c178 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/StoreRegisterTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/StoreRegisterTreeItem.java @@ -17,9 +17,11 @@ package com.jpexs.decompiler.flash.action.treemodel; import com.jpexs.decompiler.flash.action.swf4.RegisterNumber; +import com.jpexs.decompiler.flash.action.swf5.ActionStoreRegister; import com.jpexs.decompiler.flash.graph.GraphPart; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; import java.util.List; public class StoreRegisterTreeItem extends TreeItem implements SetTypeTreeItem { @@ -77,4 +79,14 @@ public class StoreRegisterTreeItem extends TreeItem implements SetTypeTreeItem { ret.addAll(value.getNeededSources()); return ret; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, value, new ActionStoreRegister(register.number)); + } + + @Override + public boolean hasReturnValue() { + return true; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/StrictModeTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/StrictModeTreeItem.java index 08c359362..79ad834e1 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/StrictModeTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/StrictModeTreeItem.java @@ -31,4 +31,9 @@ public class StrictModeTreeItem extends TreeItem { public String toString(ConstantPool constants) { return "StrictMode(" + mode + ");"; //I still don't know how AS source of Strict Mode instruction looks like, assuming this... } + + @Override + public boolean hasReturnValue() { + return false; //FIXME ? + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/StringExtractTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/StringExtractTreeItem.java index 6bb355bb4..84b4406be 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/StringExtractTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/StringExtractTreeItem.java @@ -16,8 +16,10 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.swf4.ActionStringExtract; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; import java.util.List; public class StringExtractTreeItem extends TreeItem { @@ -46,4 +48,14 @@ public class StringExtractTreeItem extends TreeItem { ret.addAll(count.getNeededSources()); return ret; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, value, index, count, new ActionStringExtract()); + } + + @Override + public boolean hasReturnValue() { + return true; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/StringLengthTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/StringLengthTreeItem.java similarity index 71% rename from trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/StringLengthTreeItem.java rename to trunk/src/com/jpexs/decompiler/flash/action/treemodel/StringLengthTreeItem.java index 4464978f6..14c4a772f 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/StringLengthTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/StringLengthTreeItem.java @@ -14,12 +14,13 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package com.jpexs.decompiler.flash.action.treemodel.operations; +package com.jpexs.decompiler.flash.action.treemodel; -import com.jpexs.decompiler.flash.action.treemodel.ConstantPool; -import com.jpexs.decompiler.flash.action.treemodel.TreeItem; +import com.jpexs.decompiler.flash.action.swf4.ActionStringLength; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.List; public class StringLengthTreeItem extends TreeItem { @@ -38,4 +39,14 @@ public class StringLengthTreeItem extends TreeItem { public boolean isCompileTime() { return false; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, value, new ActionStringLength()); + } + + @Override + public boolean hasReturnValue() { + return true; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/TargetPathTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/TargetPathTreeItem.java index 02b3dc5df..ff5b964bc 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/TargetPathTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/TargetPathTreeItem.java @@ -16,8 +16,10 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.swf5.ActionTargetPath; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; import java.util.List; public class TargetPathTreeItem extends TreeItem { @@ -40,4 +42,14 @@ public class TargetPathTreeItem extends TreeItem { ret.addAll(object.getNeededSources()); return ret; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, object, new ActionTargetPath()); + } + + @Override + public boolean hasReturnValue() { + return true; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/ThrowTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/ThrowTreeItem.java index 3552ba47a..14de134b0 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/ThrowTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/ThrowTreeItem.java @@ -16,9 +16,11 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.swf7.ActionThrow; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphSourceItemPos; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; import com.jpexs.decompiler.flash.helpers.Helper; import java.util.List; @@ -42,4 +44,14 @@ public class ThrowTreeItem extends TreeItem { ret.addAll(object.getNeededSources()); return ret; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, object, new ActionThrow()); + } + + @Override + public boolean hasReturnValue() { + return false; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/ToIntegerTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/ToIntegerTreeItem.java index 7e1b07f97..40c615c2c 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/ToIntegerTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/ToIntegerTreeItem.java @@ -16,8 +16,10 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.swf4.ActionToInteger; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; import java.util.List; public class ToIntegerTreeItem extends TreeItem { @@ -40,4 +42,14 @@ public class ToIntegerTreeItem extends TreeItem { ret.addAll(value.getNeededSources()); return ret; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, value, new ActionToInteger()); + } + + @Override + public boolean hasReturnValue() { + return true; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/ToNumberTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/ToNumberTreeItem.java index fe780ee2f..46f83fa30 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/ToNumberTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/ToNumberTreeItem.java @@ -16,8 +16,10 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.swf5.ActionToNumber; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; import com.jpexs.decompiler.flash.helpers.Helper; import java.util.List; @@ -41,4 +43,14 @@ public class ToNumberTreeItem extends TreeItem { ret.addAll(value.getNeededSources()); return ret; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, value, new ActionToNumber()); + } + + @Override + public boolean hasReturnValue() { + return true; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/ToStringTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/ToStringTreeItem.java index 2c1bfa547..5bb4ee4a2 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/ToStringTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/ToStringTreeItem.java @@ -16,8 +16,10 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.swf5.ActionToString; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; import com.jpexs.decompiler.flash.helpers.Helper; import java.util.List; @@ -41,4 +43,14 @@ public class ToStringTreeItem extends TreeItem { ret.addAll(value.getNeededSources()); return ret; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, value, new ActionToString()); + } + + @Override + public boolean hasReturnValue() { + return true; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/ToggleHighQualityTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/ToggleHighQualityTreeItem.java new file mode 100644 index 000000000..54b828f3f --- /dev/null +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/ToggleHighQualityTreeItem.java @@ -0,0 +1,44 @@ +/* + * 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 . + */ +package com.jpexs.decompiler.flash.action.treemodel; + +import com.jpexs.decompiler.flash.action.swf3.ActionToggleQuality; +import com.jpexs.decompiler.flash.graph.GraphSourceItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.List; + +public class ToggleHighQualityTreeItem extends TreeItem { + + @Override + public String toString(ConstantPool constants) { + return hilight("toggleHighQuality()"); + } + + public ToggleHighQualityTreeItem(GraphSourceItem instruction) { + super(instruction, PRECEDENCE_PRIMARY); + } + + @Override + public boolean hasReturnValue() { + return false; + } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, new ActionToggleQuality()); + } +} diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/TraceTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/TraceTreeItem.java index 2b5d0f095..ecff3e7f7 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/TraceTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/TraceTreeItem.java @@ -16,8 +16,10 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.swf4.ActionTrace; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; import java.util.List; public class TraceTreeItem extends TreeItem { @@ -40,4 +42,14 @@ public class TraceTreeItem extends TreeItem { ret.addAll(value.getNeededSources()); return ret; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, value, new ActionTrace()); + } + + @Override + public boolean hasReturnValue() { + return false; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/TreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/TreeItem.java index ddb10f312..d31c87d13 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/TreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/TreeItem.java @@ -16,8 +16,12 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.swf4.ActionPop; +import com.jpexs.decompiler.flash.action.swf4.ActionPush; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.ArrayList; import java.util.List; public abstract class TreeItem extends GraphTargetItem { @@ -67,4 +71,22 @@ public abstract class TreeItem extends GraphTargetItem { } return toString((ConstantPool) localData.get(0)); } + + protected List toSourceCall(List localData, SourceGenerator gen, List list) { + List ret = new ArrayList<>(); + for (int i = 0; i < list.size(); i++) { + ret.addAll(0, list.get(i).toSource(localData, gen)); + } + ret.add(new ActionPush((Long) (long) list.size())); + return ret; + } + + @Override + public List toSourceIgnoreReturnValue(List localData, SourceGenerator generator) { + List ret = toSource(localData, generator); + if (hasReturnValue()) { + ret.add(new ActionPop()); + } + return ret; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/TypeOfTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/TypeOfTreeItem.java index 7cf8d48ec..5a17847f7 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/TypeOfTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/TypeOfTreeItem.java @@ -16,10 +16,12 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.swf5.ActionTypeOf; 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.graph.SourceGenerator; import com.jpexs.decompiler.flash.helpers.Helper; import java.util.List; @@ -70,4 +72,14 @@ public class TypeOfTreeItem extends TreeItem { public boolean isCompileTime() { return value.isCompileTime(); } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, value, new ActionTypeOf()); + } + + @Override + public boolean hasReturnValue() { + return true; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/UnLoadMovieNumTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/UnLoadMovieNumTreeItem.java index 3f7b69b35..e11c293b9 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/UnLoadMovieNumTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/UnLoadMovieNumTreeItem.java @@ -16,7 +16,14 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.parser.script.ActionScriptSourceGenerator; +import com.jpexs.decompiler.flash.action.swf4.ActionGetURL2; +import com.jpexs.decompiler.flash.action.swf4.ActionPush; +import com.jpexs.decompiler.flash.action.treemodel.operations.AddTreeItem; import com.jpexs.decompiler.flash.graph.GraphSourceItem; +import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.List; /** * @@ -24,9 +31,9 @@ import com.jpexs.decompiler.flash.graph.GraphSourceItem; */ public class UnLoadMovieNumTreeItem extends TreeItem { - private int num; + private GraphTargetItem num; - public UnLoadMovieNumTreeItem(GraphSourceItem instruction, int num) { + public UnLoadMovieNumTreeItem(GraphSourceItem instruction, GraphTargetItem num) { super(instruction, PRECEDENCE_PRIMARY); this.num = num; } @@ -35,4 +42,15 @@ public class UnLoadMovieNumTreeItem extends TreeItem { public String toString(ConstantPool constants) { return hilight("unloadMovieNum(") + num + hilight(")"); } + + @Override + public List toSource(List localData, SourceGenerator generator) { + ActionScriptSourceGenerator asGenerator = (ActionScriptSourceGenerator) generator; + return toSourceMerge(localData, generator, new ActionPush(""), new AddTreeItem(src, asGenerator.pushConstTargetItem("_level"), num, true), new ActionGetURL2(0, true, false)); + } + + @Override + public boolean hasReturnValue() { + return false; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/UnLoadMovieTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/UnLoadMovieTreeItem.java index d4c6916f1..fc0ea8ecd 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/UnLoadMovieTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/UnLoadMovieTreeItem.java @@ -16,8 +16,12 @@ */ package com.jpexs.decompiler.flash.action.treemodel; +import com.jpexs.decompiler.flash.action.swf4.ActionGetURL2; +import com.jpexs.decompiler.flash.action.swf4.ActionPush; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.List; /** * @@ -36,4 +40,14 @@ public class UnLoadMovieTreeItem extends TreeItem { public String toString(ConstantPool constants) { return hilight("unloadMovie(") + targetString.toString(constants) + hilight(")"); } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, new ActionPush(""), targetString, new ActionGetURL2(0, true, false)); + } + + @Override + public boolean hasReturnValue() { + return false; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/UnsupportedTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/UnsupportedTreeItem.java index f67065af6..69d005f6f 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/UnsupportedTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/UnsupportedTreeItem.java @@ -31,4 +31,9 @@ public class UnsupportedTreeItem extends TreeItem { public String toString(ConstantPool constants) { return "//Unsupported by decompiler:" + value; } + + @Override + public boolean hasReturnValue() { + return false; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/WaitForFrame2TreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/WaitForFrame2TreeItem.java deleted file mode 100644 index 8b8e74387..000000000 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/WaitForFrame2TreeItem.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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 . - */ -package com.jpexs.decompiler.flash.action.treemodel; - -import com.jpexs.decompiler.flash.graph.GraphSourceItem; -import com.jpexs.decompiler.flash.graph.GraphTargetItem; -import java.util.List; - -public class WaitForFrame2TreeItem extends TreeItem { - - public GraphTargetItem frame; - public int skipCount; - - public WaitForFrame2TreeItem(GraphSourceItem instruction, GraphTargetItem frame, int skipCount) { - super(instruction, PRECEDENCE_PRIMARY); - this.frame = frame; - this.skipCount = skipCount; - } - - @Override - public String toString(ConstantPool constants) { - return hilight("waitForFrame2(") + frame.toString(constants) + "," + skipCount + hilight(")"); - } - - @Override - public List getNeededSources() { - List ret = super.getNeededSources(); - ret.addAll(frame.getNeededSources()); - return ret; - } -} diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/clauses/ClassTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/clauses/ClassTreeItem.java index 51ba8eda7..63927a2d3 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/clauses/ClassTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/clauses/ClassTreeItem.java @@ -17,11 +17,14 @@ package com.jpexs.decompiler.flash.action.treemodel.clauses; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.parser.script.ActionScriptSourceGenerator; import com.jpexs.decompiler.flash.action.treemodel.ConstantPool; import com.jpexs.decompiler.flash.action.treemodel.TreeItem; import com.jpexs.decompiler.flash.graph.Block; import com.jpexs.decompiler.flash.graph.ContinueItem; +import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; import com.jpexs.decompiler.flash.helpers.Helper; import com.jpexs.decompiler.flash.helpers.collections.MyEntry; import java.util.ArrayList; @@ -34,6 +37,7 @@ public class ClassTreeItem extends TreeItem implements Block { public GraphTargetItem extendsOp; public List implementsOp; public GraphTargetItem className; + public GraphTargetItem constructor; public List> vars; public List> staticVars; @@ -45,7 +49,7 @@ public class ClassTreeItem extends TreeItem implements Block { return ret; } - public ClassTreeItem(GraphTargetItem className, GraphTargetItem extendsOp, List implementsOp, List functions, List> vars, List staticFunctions, List> staticVars) { + public ClassTreeItem(GraphTargetItem className, GraphTargetItem extendsOp, List implementsOp, GraphTargetItem constructor, List functions, List> vars, List staticFunctions, List> staticVars) { super(null, NOPRECEDENCE); this.className = className; this.functions = functions; @@ -54,6 +58,7 @@ public class ClassTreeItem extends TreeItem implements Block { this.implementsOp = implementsOp; this.staticFunctions = staticFunctions; this.staticVars = staticVars; + this.constructor = constructor; } @Override @@ -101,4 +106,20 @@ public class ClassTreeItem extends TreeItem implements Block { public boolean needsSemicolon() { return false; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + List ret = new ArrayList<>(); + ActionScriptSourceGenerator asGenerator = (ActionScriptSourceGenerator) generator; + @SuppressWarnings("unchecked") + List localData2 = (List) Helper.deepCopy(localData); + asGenerator.setInMethod(localData2, true); + ret.addAll(asGenerator.generateTraits(localData2, false, className, extendsOp, implementsOp, constructor, functions, vars, staticFunctions, staticVars)); + return ret; + } + + @Override + public boolean hasReturnValue() { + return false; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/clauses/ForInTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/clauses/ForInTreeItem.java index 0cba01322..2574eecd2 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/clauses/ForInTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/clauses/ForInTreeItem.java @@ -16,15 +16,29 @@ */ package com.jpexs.decompiler.flash.action.treemodel.clauses; +import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.parser.script.ActionScriptSourceGenerator; +import com.jpexs.decompiler.flash.action.swf4.ActionIf; +import com.jpexs.decompiler.flash.action.swf4.ActionJump; +import com.jpexs.decompiler.flash.action.swf4.ActionPop; +import com.jpexs.decompiler.flash.action.swf4.ActionPush; +import com.jpexs.decompiler.flash.action.swf4.ActionSetVariable; import com.jpexs.decompiler.flash.action.swf4.RegisterNumber; +import com.jpexs.decompiler.flash.action.swf5.ActionEquals2; +import com.jpexs.decompiler.flash.action.swf5.ActionStoreRegister; +import com.jpexs.decompiler.flash.action.swf6.ActionEnumerate2; import com.jpexs.decompiler.flash.action.treemodel.ConstantPool; import com.jpexs.decompiler.flash.action.treemodel.DirectValueTreeItem; +import com.jpexs.decompiler.flash.ecma.Null; import com.jpexs.decompiler.flash.graph.Block; import com.jpexs.decompiler.flash.graph.ContinueItem; +import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; import com.jpexs.decompiler.flash.graph.Loop; +import com.jpexs.decompiler.flash.graph.SourceGenerator; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; public class ForInTreeItem extends LoopTreeItem implements Block { @@ -73,4 +87,56 @@ public class ForInTreeItem extends LoopTreeItem implements Block { } return ret; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + List ret = new ArrayList<>(); + ActionScriptSourceGenerator asGenerator = (ActionScriptSourceGenerator) generator; + HashMap registerVars = asGenerator.getRegisterVars(localData); + ret.addAll(enumVariable.toSource(localData, generator)); + ret.add(new ActionEnumerate2()); + + List loopExpr = new ArrayList<>(); + int exprReg = 0; + for (int i = 0; i < 256; i++) { + if (!registerVars.containsValue(i)) { + registerVars.put("__forin" + asGenerator.uniqId(), i); + exprReg = i; + break; + } + } + int innerExprReg = asGenerator.getTempRegister(localData); + loopExpr.add(new ActionStoreRegister(exprReg)); + loopExpr.add(new ActionPush(new Null())); + loopExpr.add(new ActionEquals2()); + ActionIf forInEndIf = new ActionIf(0); + loopExpr.add(forInEndIf); + List loopBody = new ArrayList<>(); + loopBody.add(new ActionPush(new RegisterNumber(exprReg))); + if (asGenerator.isInFunction(localData)) { + loopBody.add(new ActionStoreRegister(innerExprReg)); + loopBody.add(new ActionPop()); + } else { + loopBody.addAll(0, asGenerator.toActionList(variableName.toSource(localData, generator))); + loopBody.add(new ActionSetVariable()); + } + int oldForIn = asGenerator.getForInLevel(localData); + asGenerator.setForInLevel(localData, oldForIn + 1); + loopBody.addAll(asGenerator.toActionList(asGenerator.generate(localData, commands))); + asGenerator.setForInLevel(localData, oldForIn); + ActionJump forinJmpBack = new ActionJump(0); + loopBody.add(forinJmpBack); + int bodyLen = Action.actionsToBytes(loopBody, false, SWF.DEFAULT_VERSION).length; + int exprLen = Action.actionsToBytes(loopExpr, false, SWF.DEFAULT_VERSION).length; + forinJmpBack.setJumpOffset(-bodyLen - exprLen); + forInEndIf.setJumpOffset(bodyLen); + ret.addAll(loopExpr); + ret.addAll(loopBody); + return ret; + } + + @Override + public boolean hasReturnValue() { + return false; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/clauses/IfFrameLoadedTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/clauses/IfFrameLoadedTreeItem.java index 73060eb01..1f9df7f1c 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/clauses/IfFrameLoadedTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/clauses/IfFrameLoadedTreeItem.java @@ -16,6 +16,7 @@ */ package com.jpexs.decompiler.flash.action.treemodel.clauses; +import com.jpexs.decompiler.flash.action.swf4.ActionWaitForFrame2; import com.jpexs.decompiler.flash.action.treemodel.ConstantPool; import com.jpexs.decompiler.flash.action.treemodel.TreeItem; import com.jpexs.decompiler.flash.graph.Block; @@ -23,6 +24,7 @@ import com.jpexs.decompiler.flash.graph.ContinueItem; import com.jpexs.decompiler.flash.graph.Graph; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; import java.util.ArrayList; import java.util.List; @@ -62,4 +64,15 @@ public class IfFrameLoadedTreeItem extends TreeItem implements Block { ret.add(actions); return ret; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + List body = generator.generate(localData, actions); + return toSourceMerge(localData, generator, frame, new ActionWaitForFrame2(body.size()), body); + } + + @Override + public boolean hasReturnValue() { + return false; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/clauses/InterfaceTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/clauses/InterfaceTreeItem.java index 2ce9a17e5..3eed70f39 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/clauses/InterfaceTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/clauses/InterfaceTreeItem.java @@ -17,9 +17,13 @@ package com.jpexs.decompiler.flash.action.treemodel.clauses; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.parser.script.ActionScriptSourceGenerator; import com.jpexs.decompiler.flash.action.treemodel.ConstantPool; import com.jpexs.decompiler.flash.action.treemodel.TreeItem; +import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.ArrayList; import java.util.List; /** @@ -60,4 +64,17 @@ public class InterfaceTreeItem extends TreeItem { public boolean needsSemicolon() { return false; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + List ret = new ArrayList<>(); + ActionScriptSourceGenerator asGenerator = (ActionScriptSourceGenerator) generator; + ret.addAll(asGenerator.generateTraits(localData, true, name, null, superInterfaces, null, null, null, null, null)); + return ret; + } + + @Override + public boolean hasReturnValue() { + return false; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/clauses/TellTargetTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/clauses/TellTargetTreeItem.java new file mode 100644 index 000000000..e78c6046b --- /dev/null +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/clauses/TellTargetTreeItem.java @@ -0,0 +1,70 @@ +/* + * 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 . + */ +package com.jpexs.decompiler.flash.action.treemodel.clauses; + +import com.jpexs.decompiler.flash.action.swf3.ActionSetTarget; +import com.jpexs.decompiler.flash.action.swf4.ActionSetTarget2; +import com.jpexs.decompiler.flash.action.treemodel.*; +import com.jpexs.decompiler.flash.graph.GraphSourceItem; +import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.ArrayList; +import java.util.List; + +public class TellTargetTreeItem extends TreeItem { + + public List commands; + public GraphTargetItem target; + + public TellTargetTreeItem(GraphSourceItem instruction, GraphTargetItem target, List commands) { + super(instruction, PRECEDENCE_PRIMARY); + this.target = target; + this.commands = commands; + } + + @Override + public String toString(ConstantPool constants) { + String ret = hilight("tellTarget(") + target.toString(constants) + hilight(")\r\n{\r\n"); + for (GraphTargetItem ti : commands) { + ret += ti.toString(constants) + "\r\n"; + } + ret += hilight("}"); + return ret; + } + + @Override + public List getNeededSources() { + List ret = super.getNeededSources(); + ret.addAll(target.getNeededSources()); + return ret; + } + + @Override + public List toSource(List localData, SourceGenerator generator) { + List ret = new ArrayList<>(); + ret.addAll(target.toSource(localData, generator)); + ret.add(new ActionSetTarget2()); + ret.addAll(generator.generate(localData, commands)); + ret.add(new ActionSetTarget("")); + return ret; + } + + @Override + public boolean hasReturnValue() { + return false; + } +} diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/clauses/TryTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/clauses/TryTreeItem.java index a1d58272c..72809c045 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/clauses/TryTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/clauses/TryTreeItem.java @@ -16,11 +16,18 @@ */ package com.jpexs.decompiler.flash.action.treemodel.clauses; +import com.jpexs.decompiler.flash.SWF; +import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.parser.script.ActionScriptSourceGenerator; +import com.jpexs.decompiler.flash.action.swf4.ActionJump; +import com.jpexs.decompiler.flash.action.swf7.ActionTry; import com.jpexs.decompiler.flash.action.treemodel.ConstantPool; import com.jpexs.decompiler.flash.action.treemodel.TreeItem; import com.jpexs.decompiler.flash.graph.Block; import com.jpexs.decompiler.flash.graph.ContinueItem; +import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; import java.util.ArrayList; import java.util.List; @@ -61,7 +68,7 @@ public class TryTreeItem extends TreeItem implements Block { } ret += "}"; for (int e = 0; e < catchExceptions.size(); e++) { - ret += "\r\ncatch(" + catchExceptions.get(e).toStringNoQuotes(localData) + ")\r\n{\r\n"; + ret += "\r\ncatch(" + catchExceptions.get(e).toString(localData) + ")\r\n{\r\n"; List commands = catchCommands.get(e); for (GraphTargetItem ti : commands) { if (!ti.isEmpty()) { @@ -120,4 +127,45 @@ public class TryTreeItem extends TreeItem implements Block { public boolean needsSemicolon() { return false; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + List ret = new ArrayList<>(); + ActionScriptSourceGenerator asGenerator = (ActionScriptSourceGenerator) generator; + List tryCommandsA = asGenerator.toActionList(asGenerator.generate(localData, tryCommands)); + List finallyCommandsA = finallyCommands == null ? null : asGenerator.toActionList(asGenerator.generate(localData, finallyCommands)); + List catchCommandsA = null; + String catchName = null; + if (catchExceptions != null) { + if (!catchExceptions.isEmpty()) { + catchName = catchExceptions.get(0).toStringNoQuotes(new ConstantPool(asGenerator.getConstantPool())); + } + + } + int catchSize = 0; + if (catchCommands != null && !catchCommands.isEmpty()) { + catchCommandsA = asGenerator.toActionList(asGenerator.generate(localData, catchCommands.get(0))); + catchSize = Action.actionsToBytes(catchCommandsA, false, SWF.DEFAULT_VERSION).length; + tryCommandsA.add(new ActionJump(catchSize)); + } + int finallySize = 0; + if (finallyCommandsA != null) { + finallySize = Action.actionsToBytes(finallyCommandsA, false, SWF.DEFAULT_VERSION).length; + } + int trySize = Action.actionsToBytes(tryCommandsA, false, SWF.DEFAULT_VERSION).length; + ret.add(new ActionTry(false, finallyCommands != null, catchCommands != null, catchName, 0, trySize, catchSize, finallySize, SWF.DEFAULT_VERSION)); + ret.addAll(tryCommandsA); + if (catchCommandsA != null) { + ret.addAll(catchCommandsA); + } + if (finallyCommandsA != null) { + ret.addAll(finallyCommandsA); + } + return ret; + } + + @Override + public boolean hasReturnValue() { + return false; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/clauses/WithTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/clauses/WithTreeItem.java index aff273bfd..433f373bd 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/clauses/WithTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/clauses/WithTreeItem.java @@ -16,10 +16,14 @@ */ package com.jpexs.decompiler.flash.action.treemodel.clauses; +import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.swf5.ActionWith; import com.jpexs.decompiler.flash.action.treemodel.ConstantPool; import com.jpexs.decompiler.flash.action.treemodel.TreeItem; +import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; import java.util.ArrayList; import java.util.List; @@ -52,4 +56,22 @@ public class WithTreeItem extends TreeItem { ret += hilight("}"); return ret; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + List data = generator.generate(localData, items); + List dataA = new ArrayList<>(); + for (GraphSourceItem s : data) { + if (s instanceof Action) { + dataA.add((Action) s); + } + } + int codeLen = Action.actionsToBytes(dataA, false, SWF.DEFAULT_VERSION).length; + return toSourceMerge(localData, generator, scope, new ActionWith(codeLen), data); + } + + @Override + public boolean hasReturnValue() { + return false; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/AddTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/AddTreeItem.java index d44d6f66b..0be94c5d1 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/AddTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/AddTreeItem.java @@ -17,10 +17,13 @@ package com.jpexs.decompiler.flash.action.treemodel.operations; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.swf5.ActionAdd2; 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; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.List; public class AddTreeItem extends BinaryOpItem { @@ -42,4 +45,9 @@ public class AddTreeItem extends BinaryOpItem { return Action.toFloatPoint(leftSide.getResult()) + Action.toFloatPoint(rightSide.getResult()); } } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, leftSide, rightSide, new ActionAdd2()); + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/AndTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/AndTreeItem.java index ddea13997..86219d34d 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/AndTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/AndTreeItem.java @@ -16,10 +16,13 @@ */ package com.jpexs.decompiler.flash.action.treemodel.operations; +import com.jpexs.decompiler.flash.action.swf4.ActionAnd; 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; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.List; public class AndTreeItem extends BinaryOpItem { @@ -31,4 +34,9 @@ public class AndTreeItem extends BinaryOpItem { public Object getResult() { return EcmaScript.toBoolean(leftSide.getResult()) && EcmaScript.toBoolean(rightSide.getResult()); } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, leftSide, rightSide, new ActionAnd()); + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/AsTypeTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/AsTypeTreeItem.java deleted file mode 100644 index 65bbb5ccd..000000000 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/AsTypeTreeItem.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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 . - */ -package com.jpexs.decompiler.flash.action.treemodel.operations; - -import com.jpexs.decompiler.flash.action.treemodel.TreeItem; -import com.jpexs.decompiler.flash.graph.BinaryOpItem; -import com.jpexs.decompiler.flash.graph.GraphSourceItem; - -public class AsTypeTreeItem extends BinaryOpItem { - - public AsTypeTreeItem(GraphSourceItem instruction, TreeItem value, TreeItem type) { - super(instruction, PRECEDENCE_RELATIONAL, value, type, " as "); - } - - @Override - public boolean isCompileTime() { - return false; - } -} diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/BitAndTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/BitAndTreeItem.java index 0f95cd8ea..c8dad68f7 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/BitAndTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/BitAndTreeItem.java @@ -16,10 +16,13 @@ */ package com.jpexs.decompiler.flash.action.treemodel.operations; +import com.jpexs.decompiler.flash.action.swf5.ActionBitAnd; 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; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.List; public class BitAndTreeItem extends BinaryOpItem { @@ -31,4 +34,9 @@ public class BitAndTreeItem extends BinaryOpItem { public Object getResult() { return ((long) (double) EcmaScript.toNumber(leftSide.getResult())) & ((long) (double) EcmaScript.toNumber(rightSide.getResult())); } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, leftSide, rightSide, new ActionBitAnd()); + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/BitNotTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/BitNotTreeItem.java deleted file mode 100644 index b92a74aa3..000000000 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/BitNotTreeItem.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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 . - */ -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; - -public class BitNotTreeItem extends UnaryOpItem { - - public BitNotTreeItem(GraphSourceItem instruction, TreeItem value) { - super(instruction, PRECEDENCE_UNARY, value, "~"); - } - - @Override - public Object getResult() { - return ~((long) (double) EcmaScript.toNumber(value.getResult())); - } -} diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/BitOrTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/BitOrTreeItem.java index cb28493ef..4c4b1ac67 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/BitOrTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/BitOrTreeItem.java @@ -16,10 +16,13 @@ */ package com.jpexs.decompiler.flash.action.treemodel.operations; +import com.jpexs.decompiler.flash.action.swf5.ActionBitOr; 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; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.List; public class BitOrTreeItem extends BinaryOpItem { @@ -31,4 +34,9 @@ public class BitOrTreeItem extends BinaryOpItem { public Object getResult() { return ((long) (double) EcmaScript.toNumber(leftSide.getResult())) | ((long) (double) EcmaScript.toNumber(rightSide.getResult())); } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, leftSide, rightSide, new ActionBitOr()); + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/BitXorTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/BitXorTreeItem.java index 817c8cb39..99ab35cf1 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/BitXorTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/BitXorTreeItem.java @@ -16,10 +16,13 @@ */ package com.jpexs.decompiler.flash.action.treemodel.operations; +import com.jpexs.decompiler.flash.action.swf5.ActionBitXor; 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; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.List; public class BitXorTreeItem extends BinaryOpItem { @@ -31,4 +34,9 @@ public class BitXorTreeItem extends BinaryOpItem { public Object getResult() { return ((long) (double) EcmaScript.toNumber(leftSide.getResult())) ^ ((long) (double) EcmaScript.toNumber(rightSide.getResult())); } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, leftSide, rightSide, new ActionBitXor()); + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/DivideTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/DivideTreeItem.java index eceae0140..04a2e52f8 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/DivideTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/DivideTreeItem.java @@ -16,10 +16,13 @@ */ package com.jpexs.decompiler.flash.action.treemodel.operations; +import com.jpexs.decompiler.flash.action.swf4.ActionDivide; 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; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.List; public class DivideTreeItem extends BinaryOpItem { @@ -34,4 +37,9 @@ public class DivideTreeItem extends BinaryOpItem { } return (EcmaScript.toNumber(leftSide.getResult())) / (EcmaScript.toNumber(rightSide.getResult())); } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, leftSide, rightSide, new ActionDivide()); + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/EqTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/EqTreeItem.java index 8b9feaa4c..300b94627 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/EqTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/EqTreeItem.java @@ -17,11 +17,14 @@ package com.jpexs.decompiler.flash.action.treemodel.operations; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.swf5.ActionEquals2; 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; import com.jpexs.decompiler.flash.graph.LogicalOpItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.List; public class EqTreeItem extends BinaryOpItem implements LogicalOpItem { @@ -46,4 +49,9 @@ public class EqTreeItem extends BinaryOpItem implements LogicalOpItem { public GraphTargetItem invert() { return new NeqTreeItem(src, leftSide, rightSide, version2); } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, leftSide, rightSide, new ActionEquals2()); + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/GeTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/GeTreeItem.java index e59bd2ec6..d634476cf 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/GeTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/GeTreeItem.java @@ -17,13 +17,17 @@ package com.jpexs.decompiler.flash.action.treemodel.operations; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.swf4.ActionNot; +import com.jpexs.decompiler.flash.action.swf5.ActionLess2; 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; import com.jpexs.decompiler.flash.graph.LogicalOpItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.List; -public class GeTreeItem extends BinaryOpItem implements LogicalOpItem { +public class GeTreeItem extends BinaryOpItem implements LogicalOpItem, Inverted { boolean version2; @@ -53,4 +57,9 @@ public class GeTreeItem extends BinaryOpItem implements LogicalOpItem { public GraphTargetItem invert() { return new LtTreeItem(src, leftSide, rightSide, version2); } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, leftSide, rightSide, new ActionLess2(), new ActionNot()); + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/GtTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/GtTreeItem.java index 5dfcc17a0..fbb2554ce 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/GtTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/GtTreeItem.java @@ -16,11 +16,14 @@ */ package com.jpexs.decompiler.flash.action.treemodel.operations; +import com.jpexs.decompiler.flash.action.swf6.ActionGreater; 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; import com.jpexs.decompiler.flash.graph.LogicalOpItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.List; public class GtTreeItem extends BinaryOpItem implements LogicalOpItem { @@ -37,4 +40,9 @@ public class GtTreeItem extends BinaryOpItem implements LogicalOpItem { public GraphTargetItem invert() { return new LeTreeItem(src, leftSide, rightSide); } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, leftSide, rightSide, new ActionGreater()); + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/InstanceOfTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/InstanceOfTreeItem.java index fbf5b48a4..1513a8eaf 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/InstanceOfTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/InstanceOfTreeItem.java @@ -16,9 +16,12 @@ */ package com.jpexs.decompiler.flash.action.treemodel.operations; +import com.jpexs.decompiler.flash.action.swf6.ActionInstanceOf; import com.jpexs.decompiler.flash.graph.BinaryOpItem; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.List; public class InstanceOfTreeItem extends BinaryOpItem { @@ -30,4 +33,9 @@ public class InstanceOfTreeItem extends BinaryOpItem { public boolean isCompileTime() { return false; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, leftSide, rightSide, new ActionInstanceOf()); + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/Inverted.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/Inverted.java new file mode 100644 index 000000000..573b7e1dd --- /dev/null +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/Inverted.java @@ -0,0 +1,28 @@ +/* + * 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 . + */ +package com.jpexs.decompiler.flash.action.treemodel.operations; + +import com.jpexs.decompiler.flash.graph.GraphTargetItem; + +/** + * + * @author JPEXS + */ +public interface Inverted { + + public GraphTargetItem invert(); +} diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/IsTypeTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/IsTypeTreeItem.java deleted file mode 100644 index 14c726af2..000000000 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/IsTypeTreeItem.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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 . - */ -package com.jpexs.decompiler.flash.action.treemodel.operations; - -import com.jpexs.decompiler.flash.action.treemodel.TreeItem; -import com.jpexs.decompiler.flash.graph.BinaryOpItem; -import com.jpexs.decompiler.flash.graph.GraphSourceItem; - -public class IsTypeTreeItem extends BinaryOpItem { - - public IsTypeTreeItem(GraphSourceItem instruction, TreeItem value, TreeItem type) { - super(instruction, PRECEDENCE_RELATIONAL, value, type, " is "); - } - - @Override - public boolean isCompileTime() { - return false; - } -} diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/LShiftTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/LShiftTreeItem.java index cdef78d2b..33f31c499 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/LShiftTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/LShiftTreeItem.java @@ -16,10 +16,13 @@ */ package com.jpexs.decompiler.flash.action.treemodel.operations; +import com.jpexs.decompiler.flash.action.swf5.ActionBitLShift; 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; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.List; public class LShiftTreeItem extends BinaryOpItem { @@ -31,4 +34,9 @@ public class LShiftTreeItem extends BinaryOpItem { public Object getResult() { return ((int) (double) EcmaScript.toNumber(leftSide.getResult())) << ((int) (double) EcmaScript.toNumber(rightSide.getResult())); } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, leftSide, rightSide, new ActionBitLShift()); + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/LeTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/LeTreeItem.java index d4d75023b..d399cf861 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/LeTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/LeTreeItem.java @@ -16,13 +16,17 @@ */ package com.jpexs.decompiler.flash.action.treemodel.operations; +import com.jpexs.decompiler.flash.action.swf4.ActionNot; +import com.jpexs.decompiler.flash.action.swf6.ActionGreater; 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; import com.jpexs.decompiler.flash.graph.LogicalOpItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.List; -public class LeTreeItem extends BinaryOpItem implements LogicalOpItem { +public class LeTreeItem extends BinaryOpItem implements LogicalOpItem, Inverted { public LeTreeItem(GraphSourceItem instruction, GraphTargetItem leftSide, GraphTargetItem rightSide) { super(instruction, PRECEDENCE_RELATIONAL, leftSide, rightSide, "<="); @@ -44,4 +48,9 @@ public class LeTreeItem extends BinaryOpItem implements LogicalOpItem { public GraphTargetItem invert() { return new GtTreeItem(src, leftSide, rightSide); } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, leftSide, rightSide, new ActionGreater(), new ActionNot()); + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/LtTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/LtTreeItem.java index dbac54153..557865960 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/LtTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/LtTreeItem.java @@ -17,11 +17,14 @@ package com.jpexs.decompiler.flash.action.treemodel.operations; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.swf5.ActionLess2; 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; import com.jpexs.decompiler.flash.graph.LogicalOpItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.List; public class LtTreeItem extends BinaryOpItem implements LogicalOpItem { @@ -46,4 +49,9 @@ public class LtTreeItem extends BinaryOpItem implements LogicalOpItem { public GraphTargetItem invert() { return new GeTreeItem(src, leftSide, rightSide, version2); } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, leftSide, rightSide, new ActionLess2()); + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/ModuloTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/ModuloTreeItem.java index e2195085e..8e991e032 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/ModuloTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/ModuloTreeItem.java @@ -16,10 +16,13 @@ */ package com.jpexs.decompiler.flash.action.treemodel.operations; +import com.jpexs.decompiler.flash.action.swf5.ActionModulo; 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; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.List; public class ModuloTreeItem extends BinaryOpItem { @@ -34,4 +37,9 @@ public class ModuloTreeItem extends BinaryOpItem { } return ((long) (double) EcmaScript.toNumber(leftSide.getResult())) % ((long) (double) EcmaScript.toNumber(rightSide.getResult())); } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, leftSide, rightSide, new ActionModulo()); + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/MultiplyTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/MultiplyTreeItem.java index ca47d05be..52dc422dd 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/MultiplyTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/MultiplyTreeItem.java @@ -16,10 +16,13 @@ */ package com.jpexs.decompiler.flash.action.treemodel.operations; +import com.jpexs.decompiler.flash.action.swf4.ActionMultiply; 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; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.List; public class MultiplyTreeItem extends BinaryOpItem { @@ -31,4 +34,9 @@ public class MultiplyTreeItem extends BinaryOpItem { public Object getResult() { return (EcmaScript.toNumber(leftSide.getResult())) * (EcmaScript.toNumber(rightSide.getResult())); } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, leftSide, rightSide, new ActionMultiply()); + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/NegTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/NegTreeItem.java deleted file mode 100644 index e1638f0f8..000000000 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/NegTreeItem.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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 . - */ -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; - -public class NegTreeItem extends UnaryOpItem { - - public NegTreeItem(GraphSourceItem instruction, TreeItem value) { - super(instruction, PRECEDENCE_UNARY, value, "-"); - } - - @Override - public Object getResult() { - return -EcmaScript.toNumber(value.getResult()); - } -} diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/NeqTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/NeqTreeItem.java index 5a479b78d..50cd959c1 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/NeqTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/NeqTreeItem.java @@ -17,13 +17,17 @@ package com.jpexs.decompiler.flash.action.treemodel.operations; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.swf4.ActionNot; +import com.jpexs.decompiler.flash.action.swf5.ActionEquals2; 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; import com.jpexs.decompiler.flash.graph.LogicalOpItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.List; -public class NeqTreeItem extends BinaryOpItem implements LogicalOpItem { +public class NeqTreeItem extends BinaryOpItem implements LogicalOpItem, Inverted { boolean version2; @@ -46,4 +50,9 @@ public class NeqTreeItem extends BinaryOpItem implements LogicalOpItem { public GraphTargetItem invert() { return new EqTreeItem(src, leftSide, rightSide, version2); } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, leftSide, rightSide, new ActionEquals2(), new ActionNot()); + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/OrTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/OrTreeItem.java index da7dbf84b..149356522 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/OrTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/OrTreeItem.java @@ -16,10 +16,13 @@ */ package com.jpexs.decompiler.flash.action.treemodel.operations; +import com.jpexs.decompiler.flash.action.swf4.ActionOr; 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; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.List; public class OrTreeItem extends BinaryOpItem { @@ -31,4 +34,9 @@ public class OrTreeItem extends BinaryOpItem { public Object getResult() { return EcmaScript.toBoolean(leftSide.getResult()) || EcmaScript.toBoolean(rightSide.getResult()); } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, leftSide, rightSide, new ActionOr()); + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/PreDecrementTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/PreDecrementTreeItem.java index 6bf222430..278c80cb8 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/PreDecrementTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/PreDecrementTreeItem.java @@ -16,10 +16,25 @@ */ package com.jpexs.decompiler.flash.action.treemodel.operations; +import com.jpexs.decompiler.flash.action.parser.script.ActionScriptSourceGenerator; +import com.jpexs.decompiler.flash.action.swf4.ActionPush; +import com.jpexs.decompiler.flash.action.swf4.ActionSetProperty; +import com.jpexs.decompiler.flash.action.swf4.ActionSetVariable; +import com.jpexs.decompiler.flash.action.swf4.RegisterNumber; +import com.jpexs.decompiler.flash.action.swf5.ActionDecrement; +import com.jpexs.decompiler.flash.action.swf5.ActionSetMember; +import com.jpexs.decompiler.flash.action.swf5.ActionStoreRegister; +import com.jpexs.decompiler.flash.action.treemodel.DirectValueTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.GetMemberTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.GetPropertyTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.GetVariableTreeItem; 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.SourceGenerator; import com.jpexs.decompiler.flash.graph.UnaryOpItem; +import java.util.ArrayList; +import java.util.List; public class PreDecrementTreeItem extends UnaryOpItem { @@ -31,4 +46,46 @@ public class PreDecrementTreeItem extends UnaryOpItem { public Object getResult() { return EcmaScript.toNumber(value.getResult()) - 1; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + ActionScriptSourceGenerator asGenerator = (ActionScriptSourceGenerator) generator; + List ret = new ArrayList<>(); + + if (value instanceof GetVariableTreeItem) { + GetVariableTreeItem gv = (GetVariableTreeItem) value; + ret.addAll(gv.toSource(localData, generator)); + ret.remove(ret.size() - 1); //ActionGetVariable + ret.addAll(gv.toSource(localData, generator)); + ret.add(new ActionDecrement()); + int tmpReg = asGenerator.getTempRegister(localData); + ret.add(new ActionStoreRegister(tmpReg)); + ret.add(new ActionSetVariable()); + ret.add(new ActionPush(new RegisterNumber(tmpReg))); + } else if (value instanceof GetMemberTreeItem) { + GetMemberTreeItem mem = (GetMemberTreeItem) value; + ret.addAll(mem.toSource(localData, generator)); + ret.remove(ret.size() - 1); //ActionGetMember + ret.addAll(mem.toSource(localData, generator)); + ret.add(new ActionDecrement()); + int tmpReg = asGenerator.getTempRegister(localData); + ret.add(new ActionStoreRegister(tmpReg)); + ret.add(new ActionSetMember()); + ret.add(new ActionPush(new RegisterNumber(tmpReg))); + } else if ((value instanceof DirectValueTreeItem) && ((DirectValueTreeItem) value).value instanceof RegisterNumber) { + RegisterNumber rn = (RegisterNumber) ((DirectValueTreeItem) value).value; + ret.add(new ActionPush(new RegisterNumber(rn.number))); + ret.add(new ActionDecrement()); + ret.add(new ActionStoreRegister(rn.number)); + } else if (value instanceof GetPropertyTreeItem) { + GetPropertyTreeItem gp = (GetPropertyTreeItem) value; + ret.addAll(gp.toSource(localData, generator)); // old value + ret.addAll(gp.toSource(localData, generator)); + ret.remove(ret.size() - 1); + ret.addAll(gp.toSource(localData, generator)); + ret.add(new ActionDecrement()); + ret.add(new ActionSetProperty()); + } + return ret; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/PreIncrementTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/PreIncrementTreeItem.java index 5163cde88..3c13cb4a0 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/PreIncrementTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/PreIncrementTreeItem.java @@ -16,10 +16,25 @@ */ package com.jpexs.decompiler.flash.action.treemodel.operations; +import com.jpexs.decompiler.flash.action.parser.script.ActionScriptSourceGenerator; +import com.jpexs.decompiler.flash.action.swf4.ActionPush; +import com.jpexs.decompiler.flash.action.swf4.ActionSetProperty; +import com.jpexs.decompiler.flash.action.swf4.ActionSetVariable; +import com.jpexs.decompiler.flash.action.swf4.RegisterNumber; +import com.jpexs.decompiler.flash.action.swf5.ActionIncrement; +import com.jpexs.decompiler.flash.action.swf5.ActionSetMember; +import com.jpexs.decompiler.flash.action.swf5.ActionStoreRegister; +import com.jpexs.decompiler.flash.action.treemodel.DirectValueTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.GetMemberTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.GetPropertyTreeItem; +import com.jpexs.decompiler.flash.action.treemodel.GetVariableTreeItem; 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.SourceGenerator; import com.jpexs.decompiler.flash.graph.UnaryOpItem; +import java.util.ArrayList; +import java.util.List; public class PreIncrementTreeItem extends UnaryOpItem { @@ -31,4 +46,46 @@ public class PreIncrementTreeItem extends UnaryOpItem { public Object getResult() { return EcmaScript.toNumber(value.getResult()) + 1; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + ActionScriptSourceGenerator asGenerator = (ActionScriptSourceGenerator) generator; + List ret = new ArrayList<>(); + + if (value instanceof GetVariableTreeItem) { + GetVariableTreeItem gv = (GetVariableTreeItem) value; + ret.addAll(gv.toSource(localData, generator)); + ret.remove(ret.size() - 1); //ActionGetVariable + ret.addAll(gv.toSource(localData, generator)); + ret.add(new ActionIncrement()); + int tmpReg = asGenerator.getTempRegister(localData); + ret.add(new ActionStoreRegister(tmpReg)); + ret.add(new ActionSetVariable()); + ret.add(new ActionPush(new RegisterNumber(tmpReg))); + } else if (value instanceof GetMemberTreeItem) { + GetMemberTreeItem mem = (GetMemberTreeItem) value; + ret.addAll(mem.toSource(localData, generator)); + ret.remove(ret.size() - 1); //ActionGetMember + ret.addAll(mem.toSource(localData, generator)); + ret.add(new ActionIncrement()); + int tmpReg = asGenerator.getTempRegister(localData); + ret.add(new ActionStoreRegister(tmpReg)); + ret.add(new ActionSetMember()); + ret.add(new ActionPush(new RegisterNumber(tmpReg))); + } else if ((value instanceof DirectValueTreeItem) && ((DirectValueTreeItem) value).value instanceof RegisterNumber) { + RegisterNumber rn = (RegisterNumber) ((DirectValueTreeItem) value).value; + ret.add(new ActionPush(new RegisterNumber(rn.number))); + ret.add(new ActionIncrement()); + ret.add(new ActionStoreRegister(rn.number)); + } else if (value instanceof GetPropertyTreeItem) { + GetPropertyTreeItem gp = (GetPropertyTreeItem) value; + ret.addAll(gp.toSource(localData, generator)); // old value + ret.addAll(gp.toSource(localData, generator)); + ret.remove(ret.size() - 1); + ret.addAll(gp.toSource(localData, generator)); + ret.add(new ActionIncrement()); + ret.add(new ActionSetProperty()); + } + return ret; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/RShiftTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/RShiftTreeItem.java index b4c7ee37c..80d787273 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/RShiftTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/RShiftTreeItem.java @@ -16,10 +16,13 @@ */ package com.jpexs.decompiler.flash.action.treemodel.operations; +import com.jpexs.decompiler.flash.action.swf5.ActionBitRShift; 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; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.List; public class RShiftTreeItem extends BinaryOpItem { @@ -31,4 +34,9 @@ public class RShiftTreeItem extends BinaryOpItem { public Object getResult() { return ((long) (double) EcmaScript.toNumber(leftSide.getResult())) >> ((long) (double) EcmaScript.toNumber(rightSide.getResult())); } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, leftSide, rightSide, new ActionBitRShift()); + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/StrictEqTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/StrictEqTreeItem.java index f1f7dbc23..ce40b6a11 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/StrictEqTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/StrictEqTreeItem.java @@ -16,11 +16,14 @@ */ package com.jpexs.decompiler.flash.action.treemodel.operations; +import com.jpexs.decompiler.flash.action.swf6.ActionStrictEquals; 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; import com.jpexs.decompiler.flash.graph.LogicalOpItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.List; public class StrictEqTreeItem extends BinaryOpItem implements LogicalOpItem { @@ -40,4 +43,9 @@ public class StrictEqTreeItem extends BinaryOpItem implements LogicalOpItem { public GraphTargetItem invert() { return new StrictNeqTreeItem(src, leftSide, rightSide); } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, leftSide, rightSide, new ActionStrictEquals()); + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/StrictNeqTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/StrictNeqTreeItem.java index 6bc6b968d..ac313c90d 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/StrictNeqTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/StrictNeqTreeItem.java @@ -16,11 +16,15 @@ */ package com.jpexs.decompiler.flash.action.treemodel.operations; +import com.jpexs.decompiler.flash.action.swf4.ActionNot; +import com.jpexs.decompiler.flash.action.swf6.ActionStrictEquals; 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; import com.jpexs.decompiler.flash.graph.LogicalOpItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.List; public class StrictNeqTreeItem extends BinaryOpItem implements LogicalOpItem { @@ -40,4 +44,9 @@ public class StrictNeqTreeItem extends BinaryOpItem implements LogicalOpItem { public GraphTargetItem invert() { return new StrictEqTreeItem(src, leftSide, rightSide); } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, leftSide, rightSide, new ActionStrictEquals(), new ActionNot()); + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/StringAddTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/StringAddTreeItem.java index 857b26cf1..fe3c9ffbc 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/StringAddTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/StringAddTreeItem.java @@ -16,9 +16,12 @@ */ package com.jpexs.decompiler.flash.action.treemodel.operations; +import com.jpexs.decompiler.flash.action.swf4.ActionStringAdd; import com.jpexs.decompiler.flash.graph.BinaryOpItem; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.List; public class StringAddTreeItem extends BinaryOpItem { @@ -30,4 +33,9 @@ public class StringAddTreeItem extends BinaryOpItem { public boolean isCompileTime() { return false; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, leftSide, rightSide, new ActionStringAdd()); + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/StringEqTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/StringEqTreeItem.java index 6646bcc99..aaeddd2c0 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/StringEqTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/StringEqTreeItem.java @@ -16,9 +16,12 @@ */ package com.jpexs.decompiler.flash.action.treemodel.operations; +import com.jpexs.decompiler.flash.action.swf4.ActionStringEquals; import com.jpexs.decompiler.flash.graph.BinaryOpItem; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.List; public class StringEqTreeItem extends BinaryOpItem { @@ -30,4 +33,9 @@ public class StringEqTreeItem extends BinaryOpItem { public boolean isCompileTime() { return false; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, leftSide, rightSide, new ActionStringEquals()); + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/StringLtTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/StringLtTreeItem.java index c28420e3d..a3ca56799 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/StringLtTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/StringLtTreeItem.java @@ -16,9 +16,12 @@ */ package com.jpexs.decompiler.flash.action.treemodel.operations; +import com.jpexs.decompiler.flash.action.swf4.ActionStringLess; import com.jpexs.decompiler.flash.graph.BinaryOpItem; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.List; public class StringLtTreeItem extends BinaryOpItem { @@ -30,4 +33,9 @@ public class StringLtTreeItem extends BinaryOpItem { public boolean isCompileTime() { return false; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, leftSide, rightSide, new ActionStringLess()); + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/SubtractTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/SubtractTreeItem.java index 6ef2a0fb8..b423abb06 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/SubtractTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/SubtractTreeItem.java @@ -16,10 +16,13 @@ */ package com.jpexs.decompiler.flash.action.treemodel.operations; +import com.jpexs.decompiler.flash.action.swf4.ActionSubtract; +import com.jpexs.decompiler.flash.action.treemodel.DirectValueTreeItem; 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; +import com.jpexs.decompiler.flash.graph.SourceGenerator; import java.util.List; public class SubtractTreeItem extends BinaryOpItem { @@ -35,7 +38,7 @@ public class SubtractTreeItem extends BinaryOpItem { @Override public String toString(List localData) { - if (!(getLeftMostItem(rightSide) instanceof NegTreeItem)) { // a - (-b*c*d) + if (rightSide instanceof DirectValueTreeItem) { return super.toString(localData); } String ret = ""; @@ -48,4 +51,9 @@ public class SubtractTreeItem extends BinaryOpItem { ret += "(" + rightSide.toString(localData) + ")"; return ret; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, leftSide, rightSide, new ActionSubtract()); + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/URShiftTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/URShiftTreeItem.java index 4d8852d76..dd98ef3a1 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/URShiftTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/operations/URShiftTreeItem.java @@ -16,10 +16,13 @@ */ package com.jpexs.decompiler.flash.action.treemodel.operations; +import com.jpexs.decompiler.flash.action.swf5.ActionBitURShift; 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; +import com.jpexs.decompiler.flash.graph.SourceGenerator; +import java.util.List; public class URShiftTreeItem extends BinaryOpItem { @@ -31,4 +34,9 @@ public class URShiftTreeItem extends BinaryOpItem { public Object getResult() { return ((long) (double) EcmaScript.toNumber(leftSide.getResult())) >>> ((long) (double) EcmaScript.toNumber(rightSide.getResult())); } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return toSourceMerge(localData, generator, leftSide, rightSide, new ActionBitURShift()); + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/graph/AndItem.java b/trunk/src/com/jpexs/decompiler/flash/graph/AndItem.java index a685abc9f..4e84bef31 100644 --- a/trunk/src/com/jpexs/decompiler/flash/graph/AndItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/graph/AndItem.java @@ -33,4 +33,14 @@ public class AndItem extends BinaryOpItem { this.leftSide = leftSide; this.rightSide = rightSide; } + + @Override + public boolean hasReturnValue() { + return true; + } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return generator.generate(localData, this); + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/graph/BinaryOp.java b/trunk/src/com/jpexs/decompiler/flash/graph/BinaryOp.java new file mode 100644 index 000000000..8771570c9 --- /dev/null +++ b/trunk/src/com/jpexs/decompiler/flash/graph/BinaryOp.java @@ -0,0 +1,34 @@ +/* + * 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 . + */ +package com.jpexs.decompiler.flash.graph; + +/** + * + * @author JPEXS + */ +public interface BinaryOp { + + public GraphTargetItem getLeftSide(); + + public GraphTargetItem getRightSide(); + + public void setLeftSide(GraphTargetItem value); + + public void setRightSide(GraphTargetItem value); + + public int getPrecedence(); +} diff --git a/trunk/src/com/jpexs/decompiler/flash/graph/BinaryOpItem.java b/trunk/src/com/jpexs/decompiler/flash/graph/BinaryOpItem.java index 42f6e3196..f67086141 100644 --- a/trunk/src/com/jpexs/decompiler/flash/graph/BinaryOpItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/graph/BinaryOpItem.java @@ -18,7 +18,7 @@ package com.jpexs.decompiler.flash.graph; import java.util.List; -public abstract class BinaryOpItem extends GraphTargetItem { +public abstract class BinaryOpItem extends GraphTargetItem implements BinaryOp { public GraphTargetItem leftSide; public GraphTargetItem rightSide; @@ -138,4 +138,33 @@ public abstract class BinaryOpItem extends GraphTargetItem { } return true; }*/ + @Override + public GraphTargetItem getLeftSide() { + return leftSide; + } + + @Override + public GraphTargetItem getRightSide() { + return rightSide; + } + + @Override + public void setLeftSide(GraphTargetItem value) { + leftSide = value; + } + + @Override + public void setRightSide(GraphTargetItem value) { + rightSide = value; + } + + @Override + public int getPrecedence() { + return precedence; + } + + @Override + public boolean hasReturnValue() { + return true; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/graph/BlockItem.java b/trunk/src/com/jpexs/decompiler/flash/graph/BlockItem.java new file mode 100644 index 000000000..ff158c5cf --- /dev/null +++ b/trunk/src/com/jpexs/decompiler/flash/graph/BlockItem.java @@ -0,0 +1,48 @@ +/* + * 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 . + */ +package com.jpexs.decompiler.flash.graph; + +import java.util.List; + +/** + * + * @author JPEXS + */ +public class BlockItem extends GraphTargetItem { + + List commands; + + public BlockItem(GraphSourceItem src, List commands) { + super(src, PRECEDENCE_PRIMARY); + this.commands = commands; + } + + @Override + public String toString(List localData) { + return "{\r\n" + Graph.graphToString(commands, localData) + "\r\n}"; + } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return generator.generate(localData, commands); + } + + @Override + public boolean hasReturnValue() { + return false; + } +} diff --git a/trunk/src/com/jpexs/decompiler/flash/graph/BreakItem.java b/trunk/src/com/jpexs/decompiler/flash/graph/BreakItem.java index 8ed3e4621..2df621791 100644 --- a/trunk/src/com/jpexs/decompiler/flash/graph/BreakItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/graph/BreakItem.java @@ -19,4 +19,14 @@ public class BreakItem extends GraphTargetItem { public String toString(List localData) { return hilight("break") + " " + "loop" + loopId; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return generator.generate(localData, this); + } + + @Override + public boolean hasReturnValue() { + return false; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/graph/CommaExpressionItem.java b/trunk/src/com/jpexs/decompiler/flash/graph/CommaExpressionItem.java new file mode 100644 index 000000000..ce810604f --- /dev/null +++ b/trunk/src/com/jpexs/decompiler/flash/graph/CommaExpressionItem.java @@ -0,0 +1,57 @@ +/* + * 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 . + */ +package com.jpexs.decompiler.flash.graph; + +import java.util.List; + +/** + * + * @author JPEXS + */ +public class CommaExpressionItem extends GraphTargetItem { + + public List commands; + + public CommaExpressionItem(GraphSourceItem src, List commands) { + super(src, PRECEDENCE_PRIMARY); + this.commands = commands; + } + + @Override + public String toString(List localData) { + String ret = ""; + boolean first = true; + for (GraphTargetItem t : commands) { + if (!first) { + ret += ", "; + } + ret += t.toString(localData); + first = false; + } + return ret; + } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return generator.generate(localData, this); + } + + @Override + public boolean hasReturnValue() { + return false; + } +} diff --git a/trunk/src/com/jpexs/decompiler/flash/graph/CommentItem.java b/trunk/src/com/jpexs/decompiler/flash/graph/CommentItem.java index 9f04c81c1..08c10de18 100644 --- a/trunk/src/com/jpexs/decompiler/flash/graph/CommentItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/graph/CommentItem.java @@ -49,4 +49,9 @@ public class CommentItem extends GraphTargetItem { public boolean needsSemicolon() { return false; } + + @Override + public boolean hasReturnValue() { + return false; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/graph/ContinueItem.java b/trunk/src/com/jpexs/decompiler/flash/graph/ContinueItem.java index 02dc4c6ba..a969a0b31 100644 --- a/trunk/src/com/jpexs/decompiler/flash/graph/ContinueItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/graph/ContinueItem.java @@ -19,4 +19,14 @@ public class ContinueItem extends GraphTargetItem { public String toString(List localData) { return hilight("continue") + " " + "loop" + loopId; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return generator.generate(localData, this); + } + + @Override + public boolean hasReturnValue() { + return false; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/graph/DoWhileItem.java b/trunk/src/com/jpexs/decompiler/flash/graph/DoWhileItem.java index badc39d45..c7cfb6764 100644 --- a/trunk/src/com/jpexs/decompiler/flash/graph/DoWhileItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/graph/DoWhileItem.java @@ -81,4 +81,14 @@ public class DoWhileItem extends LoopItem implements Block { } return ret; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return generator.generate(localData, this); + } + + @Override + public boolean hasReturnValue() { + return false; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/graph/DuplicateItem.java b/trunk/src/com/jpexs/decompiler/flash/graph/DuplicateItem.java index 01aaee34f..7c890db06 100644 --- a/trunk/src/com/jpexs/decompiler/flash/graph/DuplicateItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/graph/DuplicateItem.java @@ -63,4 +63,14 @@ public class DuplicateItem extends GraphTargetItem { public boolean isVariableComputed() { return value.isVariableComputed(); } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return generator.generate(localData, this); + } + + @Override + public boolean hasReturnValue() { + return true; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/graph/ForTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/graph/ForItem.java similarity index 84% rename from trunk/src/com/jpexs/decompiler/flash/graph/ForTreeItem.java rename to trunk/src/com/jpexs/decompiler/flash/graph/ForItem.java index 5a6747d0c..ff06f7158 100644 --- a/trunk/src/com/jpexs/decompiler/flash/graph/ForTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/graph/ForItem.java @@ -19,7 +19,7 @@ package com.jpexs.decompiler.flash.graph; import java.util.ArrayList; import java.util.List; -public class ForTreeItem extends LoopItem implements Block { +public class ForItem extends LoopItem implements Block { public List firstCommands; public GraphTargetItem expression; @@ -35,7 +35,7 @@ public class ForTreeItem extends LoopItem implements Block { return ret; } - public ForTreeItem(GraphSourceItem src, Loop loop, List firstCommands, GraphTargetItem expression, List finalCommands, List commands) { + public ForItem(GraphSourceItem src, Loop loop, List firstCommands, GraphTargetItem expression, List finalCommands, List commands) { super(src, loop); this.firstCommands = firstCommands; this.expression = expression; @@ -110,4 +110,14 @@ public class ForTreeItem extends LoopItem implements Block { } return ret; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return generator.generate(localData, this); + } + + @Override + public boolean hasReturnValue() { + return false; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/graph/Graph.java b/trunk/src/com/jpexs/decompiler/flash/graph/Graph.java index 88266278a..69835d11f 100644 --- a/trunk/src/com/jpexs/decompiler/flash/graph/Graph.java +++ b/trunk/src/com/jpexs/decompiler/flash/graph/Graph.java @@ -1792,7 +1792,7 @@ public class Graph { checkContinueAtTheEnd(finalComm, currentLoop); } if (!finalComm.isEmpty()) { - ret.add(index, li = new ForTreeItem(null, currentLoop, new ArrayList(), exprList.get(exprList.size() - 1), finalComm, commands)); + ret.add(index, li = new ForItem(null, currentLoop, new ArrayList(), exprList.get(exprList.size() - 1), finalComm, commands)); } else { ret.add(index, li = new WhileItem(null, currentLoop, exprList, commands)); } diff --git a/trunk/src/com/jpexs/decompiler/flash/graph/GraphTargetItem.java b/trunk/src/com/jpexs/decompiler/flash/graph/GraphTargetItem.java index ad5e6d9a9..c1d475b2b 100644 --- a/trunk/src/com/jpexs/decompiler/flash/graph/GraphTargetItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/graph/GraphTargetItem.java @@ -188,4 +188,41 @@ public abstract class GraphTargetItem { public boolean valueEquals(GraphTargetItem target) { return equals(target); } + + public List toSource(List localData, SourceGenerator generator) { + return new ArrayList<>(); + } + + public List toSourceIgnoreReturnValue(List localData, SourceGenerator generator) { + return toSource(localData, generator); + } + + protected List toSourceBinary(BinaryOp op, GraphSourceItem action) { + List ret = new ArrayList<>(); + + return ret; + } + + protected List toSourceMerge(List localData, SourceGenerator gen, Object... tar) { + List ret = new ArrayList<>(); + for (Object o : tar) { + if (o instanceof GraphTargetItem) { + ret.addAll(((GraphTargetItem) o).toSource(localData, gen)); + } + if (o instanceof GraphSourceItem) { + ret.add((GraphSourceItem) o); + } + if (o instanceof List) { + List l = (List) o; + for (Object o2 : l) { + if (o2 instanceof GraphSourceItem) { + ret.add((GraphSourceItem) o2); + } + } + } + } + return ret; + } + + public abstract boolean hasReturnValue(); } diff --git a/trunk/src/com/jpexs/decompiler/flash/graph/IfItem.java b/trunk/src/com/jpexs/decompiler/flash/graph/IfItem.java index e6ba6ac48..82cb77f53 100644 --- a/trunk/src/com/jpexs/decompiler/flash/graph/IfItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/graph/IfItem.java @@ -111,4 +111,14 @@ public class IfItem extends GraphTargetItem implements Block { } return ret; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return generator.generate(localData, this); + } + + @Override + public boolean hasReturnValue() { + return false; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/graph/IntegerValueItem.java b/trunk/src/com/jpexs/decompiler/flash/graph/IntegerValueItem.java index abf4fe124..2e0dc440a 100644 --- a/trunk/src/com/jpexs/decompiler/flash/graph/IntegerValueItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/graph/IntegerValueItem.java @@ -45,4 +45,9 @@ public class IntegerValueItem extends GraphTargetItem { public Object getResult() { return Double.valueOf(intValue); } + + @Override + public boolean hasReturnValue() { + return true; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/graph/MarkItem.java b/trunk/src/com/jpexs/decompiler/flash/graph/MarkItem.java index 87fb369c6..bced86fef 100644 --- a/trunk/src/com/jpexs/decompiler/flash/graph/MarkItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/graph/MarkItem.java @@ -44,4 +44,9 @@ public class MarkItem extends GraphTargetItem { public boolean isEmpty() { return true; } + + @Override + public boolean hasReturnValue() { + return false; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/graph/NotItem.java b/trunk/src/com/jpexs/decompiler/flash/graph/NotItem.java index 3e04994d5..34cb2f9c1 100644 --- a/trunk/src/com/jpexs/decompiler/flash/graph/NotItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/graph/NotItem.java @@ -1,12 +1,14 @@ package com.jpexs.decompiler.flash.graph; +import com.jpexs.decompiler.flash.action.treemodel.operations.Inverted; import com.jpexs.decompiler.flash.ecma.EcmaScript; +import java.util.List; /** * * @author JPEXS */ -public class NotItem extends UnaryOpItem implements LogicalOpItem { +public class NotItem extends UnaryOpItem implements LogicalOpItem, Inverted { public NotItem(GraphSourceItem instruction, GraphTargetItem value) { super(instruction, PRECEDENCE_UNARY, value, "!"); @@ -37,4 +39,14 @@ public class NotItem extends UnaryOpItem implements LogicalOpItem { public GraphTargetItem getOriginal() { return value; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return generator.generate(localData, this); + } + + @Override + public boolean hasReturnValue() { + return true; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/graph/OrItem.java b/trunk/src/com/jpexs/decompiler/flash/graph/OrItem.java index 08a75ee27..e7fc679bc 100644 --- a/trunk/src/com/jpexs/decompiler/flash/graph/OrItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/graph/OrItem.java @@ -33,4 +33,14 @@ public class OrItem extends BinaryOpItem { ret.addAll(rightSide.getNeededSources()); return ret; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return generator.generate(localData, this); + } + + @Override + public boolean hasReturnValue() { + return true; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/graph/ParenthesisItem.java b/trunk/src/com/jpexs/decompiler/flash/graph/ParenthesisItem.java new file mode 100644 index 000000000..2ec7a074e --- /dev/null +++ b/trunk/src/com/jpexs/decompiler/flash/graph/ParenthesisItem.java @@ -0,0 +1,46 @@ +/* + * 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 . + */ +package com.jpexs.decompiler.flash.graph; + +import java.util.List; + +/** + * + * @author JPEXS + */ +public class ParenthesisItem extends GraphTargetItem { + + public ParenthesisItem(GraphSourceItem src, GraphTargetItem value) { + super(src, PRECEDENCE_PRIMARY); + this.value = value; + } + + @Override + public String toString(List localData) { + return "(" + value.toString(localData) + ")"; + } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return value.toSource(localData, generator); + } + + @Override + public boolean hasReturnValue() { + return value.hasReturnValue(); + } +} diff --git a/trunk/src/com/jpexs/decompiler/flash/graph/ScriptEndItem.java b/trunk/src/com/jpexs/decompiler/flash/graph/ScriptEndItem.java index 8ea1c69c5..abc57f53b 100644 --- a/trunk/src/com/jpexs/decompiler/flash/graph/ScriptEndItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/graph/ScriptEndItem.java @@ -42,4 +42,9 @@ public class ScriptEndItem extends GraphTargetItem implements ExitItem { public boolean isEmpty() { return true; } + + @Override + public boolean hasReturnValue() { + return false; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/graph/SourceGenerator.java b/trunk/src/com/jpexs/decompiler/flash/graph/SourceGenerator.java new file mode 100644 index 000000000..30232b2ce --- /dev/null +++ b/trunk/src/com/jpexs/decompiler/flash/graph/SourceGenerator.java @@ -0,0 +1,54 @@ +/* + * 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 . + */ +package com.jpexs.decompiler.flash.graph; + +import java.util.List; + +/** + * + * @author JPEXS + */ +public interface SourceGenerator { + + public List generate(List localData, AndItem item); + + public List generate(List localData, OrItem item); + + public List generate(List localData, IfItem item); + + public List generate(List localData, TernarOpItem item); + + public List generate(List localData, WhileItem item); + + public List generate(List localData, DoWhileItem item); + + public List generate(List localData, ForItem item); + + public List generate(List localData, SwitchItem item); + + public List generate(List localData, NotItem item); + + public List generate(List localData, DuplicateItem item); + + public List generate(List localData, BreakItem item); + + public List generate(List localData, ContinueItem item); + + public List generate(List localData, List commands); + + public List generate(List localData, CommaExpressionItem item); +} diff --git a/trunk/src/com/jpexs/decompiler/flash/graph/SwitchItem.java b/trunk/src/com/jpexs/decompiler/flash/graph/SwitchItem.java index 40358af35..b59cab0a9 100644 --- a/trunk/src/com/jpexs/decompiler/flash/graph/SwitchItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/graph/SwitchItem.java @@ -47,7 +47,7 @@ public class SwitchItem extends LoopItem implements Block { @Override public String toString(List localData) { String ret = ""; - ret += "loop" + loop.id + ":\r\n"; + ret += "loopswitch" + loop.id + ":\r\n"; ret += hilight("switch(") + switchedObject.toString(localData) + hilight(")") + "\r\n{\r\n"; for (int i = 0; i < caseCommands.size(); i++) { for (int k = 0; k < valuesMapping.size(); k++) { @@ -106,4 +106,14 @@ public class SwitchItem extends LoopItem implements Block { } return ret; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return generator.generate(localData, this); + } + + @Override + public boolean hasReturnValue() { + return false; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/graph/TernarOpItem.java b/trunk/src/com/jpexs/decompiler/flash/graph/TernarOpItem.java index 62f75ff04..ce1979916 100644 --- a/trunk/src/com/jpexs/decompiler/flash/graph/TernarOpItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/graph/TernarOpItem.java @@ -35,4 +35,14 @@ public class TernarOpItem extends GraphTargetItem { public String toString(List localData) { return expression.toString(localData) + hilight("?") + onTrue.toString(localData) + hilight(":") + onFalse.toString(localData); } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return generator.generate(localData, this); + } + + @Override + public boolean hasReturnValue() { + return true; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/graph/TrueItem.java b/trunk/src/com/jpexs/decompiler/flash/graph/TrueItem.java index 8c074a94d..fcb9a18e7 100644 --- a/trunk/src/com/jpexs/decompiler/flash/graph/TrueItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/graph/TrueItem.java @@ -16,4 +16,9 @@ public class TrueItem extends GraphTargetItem { public String toString(List localData) { return "true"; } + + @Override + public boolean hasReturnValue() { + return true; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/graph/UnaryOp.java b/trunk/src/com/jpexs/decompiler/flash/graph/UnaryOp.java new file mode 100644 index 000000000..3107c21e4 --- /dev/null +++ b/trunk/src/com/jpexs/decompiler/flash/graph/UnaryOp.java @@ -0,0 +1,28 @@ +/* + * 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 . + */ +package com.jpexs.decompiler.flash.graph; + +/** + * + * @author JPEXS + */ +public interface UnaryOp { + + public GraphTargetItem getValue(); + + public int getPrecedence(); +} diff --git a/trunk/src/com/jpexs/decompiler/flash/graph/UnaryOpItem.java b/trunk/src/com/jpexs/decompiler/flash/graph/UnaryOpItem.java index d496d54a5..9af66790a 100644 --- a/trunk/src/com/jpexs/decompiler/flash/graph/UnaryOpItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/graph/UnaryOpItem.java @@ -18,7 +18,7 @@ package com.jpexs.decompiler.flash.graph; import java.util.List; -public abstract class UnaryOpItem extends GraphTargetItem { +public abstract class UnaryOpItem extends GraphTargetItem implements UnaryOp { public GraphTargetItem value; public String operator; @@ -61,4 +61,19 @@ public abstract class UnaryOpItem extends GraphTargetItem { public boolean hasSideEffect() { return value.hasSideEffect(); } + + @Override + public int getPrecedence() { + return precedence; + } + + @Override + public GraphTargetItem getValue() { + return value; + } + + @Override + public boolean hasReturnValue() { + return true; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/graph/UniversalLoopItem.java b/trunk/src/com/jpexs/decompiler/flash/graph/UniversalLoopItem.java index 055a43d8a..38d229794 100644 --- a/trunk/src/com/jpexs/decompiler/flash/graph/UniversalLoopItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/graph/UniversalLoopItem.java @@ -67,4 +67,9 @@ public class UniversalLoopItem extends LoopItem implements Block { ret.add(commands); return ret; } + + @Override + public boolean hasReturnValue() { + return false; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/graph/WhileItem.java b/trunk/src/com/jpexs/decompiler/flash/graph/WhileItem.java index 6ee9d60c2..b930864b2 100644 --- a/trunk/src/com/jpexs/decompiler/flash/graph/WhileItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/graph/WhileItem.java @@ -80,4 +80,14 @@ public class WhileItem extends LoopItem implements Block { public boolean needsSemicolon() { return false; } + + @Override + public List toSource(List localData, SourceGenerator generator) { + return generator.generate(localData, this); + } + + @Override + public boolean hasReturnValue() { + return false; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java b/trunk/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java index bdf737387..19db00247 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java @@ -55,6 +55,8 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.logging.Level; +import java.util.logging.Logger; import java.util.regex.Pattern; import javax.swing.BoxLayout; import javax.swing.JButton; @@ -655,11 +657,12 @@ public class ActionPanel extends JPanel implements ActionListener { } else if (e.getActionCommand().equals("SAVEDECOMPILED")) { try { ActionScriptParser par = new ActionScriptParser(); - src.setActions(par.parse(decompiledEditor.getText()), SWF.DEFAULT_VERSION); + src.setActions(par.actionsFromString(decompiledEditor.getText()), SWF.DEFAULT_VERSION); setSource(this.src, false); JOptionPane.showMessageDialog(this, translate("message.action.saved")); setDecompiledEditMode(false); } catch (IOException ex) { + Logger.getLogger(ActionPanel.class.getName()).log(Level.SEVERE, "IOException during action compiling", ex); } catch (ParseException ex) { JOptionPane.showMessageDialog(this, translate("error.action.save").replace("%error%", ex.text).replace("%line%", "" + ex.line), translate("error"), JOptionPane.ERROR_MESSAGE); }