From de784d1684726aef21d015ba9b5f2917aa379351 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=F8=EDk?= Date: Mon, 31 Dec 2012 07:10:21 +0100 Subject: [PATCH] AS3: XML filters --- .../com/jpexs/asdec/abc/avm2/AVM2Code.java | 58 ++++++++++++++----- .../avm2/instructions/xml/CheckFilterIns.java | 3 + .../avm2/treemodel/FilteredCheckTreeItem.java | 42 ++++++++++++++ .../abc/avm2/treemodel/LocalRegTreeItem.java | 4 ++ .../abc/avm2/treemodel/UnparsedTreeItem.java | 2 +- .../treemodel/clauses/FilterTreeItem.java | 44 ++++++++++++++ .../com/jpexs/asdec/abc/types/Multiname.java | 2 +- 7 files changed, 140 insertions(+), 15 deletions(-) create mode 100644 trunk/src/com/jpexs/asdec/abc/avm2/treemodel/FilteredCheckTreeItem.java create mode 100644 trunk/src/com/jpexs/asdec/abc/avm2/treemodel/clauses/FilterTreeItem.java diff --git a/trunk/src/com/jpexs/asdec/abc/avm2/AVM2Code.java b/trunk/src/com/jpexs/asdec/abc/avm2/AVM2Code.java index b3d642b2a..80ca5872a 100644 --- a/trunk/src/com/jpexs/asdec/abc/avm2/AVM2Code.java +++ b/trunk/src/com/jpexs/asdec/abc/avm2/AVM2Code.java @@ -1418,22 +1418,54 @@ public class AVM2Code { output.add(new DoWhileTreeItem(ins, currentLoop.loopBreak, currentLoop.loopContinue, loopBody, expression)); } else { if (expression instanceof InTreeItem) { - boolean found = false; - for (int g = ip + 1; g < jumpPos; g++) { - if (code.get(g).definition instanceof NextValueIns) { - output.add(new ForEachInTreeItem(ins, currentLoop.loopBreak, currentLoop.loopContinue, (InTreeItem) expression, loopBody)); - found = true; - break; + TreeItem gti=((InTreeItem) expression).collection.getNotCoerced().getThroughRegister(); + if (gti instanceof FilteredCheckTreeItem) { + boolean found = false; + if (loopBody.size() == 1) { + TreeItem ft = loopBody.get(0); + if (ft instanceof WithTreeItem) { + if (((WithTreeItem) ft).items.size() == 1) { + ft = ((WithTreeItem) ft).items.get(0); + if (ft instanceof IfTreeItem) { + IfTreeItem ift = (IfTreeItem) ft; + if (ift.onTrue.size() > 0) { + ft = ift.onTrue.get(0); + if (ft instanceof SetPropertyTreeItem) { + SetPropertyTreeItem spt = (SetPropertyTreeItem) ft; + if (spt.object instanceof LocalRegTreeItem) { + int regIndex = ((LocalRegTreeItem) spt.object).regIndex; + InTreeItem iti=(InTreeItem) expression; + localRegs.put(regIndex, new FilterTreeItem(ins,iti.collection.getThroughRegister(),ift.expression)); + found = true; + } + } + } + } + } + } } - if (code.get(g).definition instanceof NextNameIns) { - output.add(new ForInTreeItem(ins, currentLoop.loopBreak, currentLoop.loopContinue, (InTreeItem) expression, loopBody)); - found = true; - break; + if (!found) { + throw new ConvertException("Unknown pattern: bad filter loop", ip); + } + } else { + boolean found = false; + for (int g = ip + 1; g < jumpPos; g++) { + if (code.get(g).definition instanceof NextValueIns) { + output.add(new ForEachInTreeItem(ins, currentLoop.loopBreak, currentLoop.loopContinue, (InTreeItem) expression, loopBody)); + found = true; + break; + } + if (code.get(g).definition instanceof NextNameIns) { + output.add(new ForInTreeItem(ins, currentLoop.loopBreak, currentLoop.loopContinue, (InTreeItem) expression, loopBody)); + found = true; + break; + } + } + if (!found) { + throw new ConvertException("Unknown pattern: hasnext without nextvalue/nextname", ip); } } - if (!found) { - throw new ConvertException("Unknown pattern: hasnext without nextvalue/nextname", ip); - } + } else { output.add(new WhileTreeItem(ins, currentLoop.loopBreak, currentLoop.loopContinue, expression, loopBody)); diff --git a/trunk/src/com/jpexs/asdec/abc/avm2/instructions/xml/CheckFilterIns.java b/trunk/src/com/jpexs/asdec/abc/avm2/instructions/xml/CheckFilterIns.java index 157ee45ca..99b596a81 100644 --- a/trunk/src/com/jpexs/asdec/abc/avm2/instructions/xml/CheckFilterIns.java +++ b/trunk/src/com/jpexs/asdec/abc/avm2/instructions/xml/CheckFilterIns.java @@ -21,6 +21,7 @@ import com.jpexs.asdec.abc.avm2.ConstantPool; import com.jpexs.asdec.abc.avm2.LocalDataArea; import com.jpexs.asdec.abc.avm2.instructions.AVM2Instruction; import com.jpexs.asdec.abc.avm2.instructions.InstructionDefinition; +import com.jpexs.asdec.abc.avm2.treemodel.FilteredCheckTreeItem; import com.jpexs.asdec.abc.avm2.treemodel.TreeItem; import com.jpexs.asdec.abc.types.MethodInfo; import java.util.HashMap; @@ -40,6 +41,8 @@ public class CheckFilterIns extends InstructionDefinition { @Override public void translate(boolean isStatic, int classIndex, java.util.HashMap localRegs, Stack stack, java.util.Stack scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List output, com.jpexs.asdec.abc.types.MethodBody body, com.jpexs.asdec.abc.ABC abc, HashMap localRegNames, List fullyQualifiedNames) { + TreeItem obj=stack.pop(); + stack.push(new FilteredCheckTreeItem(ins, obj)); } @Override diff --git a/trunk/src/com/jpexs/asdec/abc/avm2/treemodel/FilteredCheckTreeItem.java b/trunk/src/com/jpexs/asdec/abc/avm2/treemodel/FilteredCheckTreeItem.java new file mode 100644 index 000000000..7d3e72afb --- /dev/null +++ b/trunk/src/com/jpexs/asdec/abc/avm2/treemodel/FilteredCheckTreeItem.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2012 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.asdec.abc.avm2.treemodel; + +import com.jpexs.asdec.abc.avm2.ConstantPool; +import com.jpexs.asdec.abc.avm2.instructions.AVM2Instruction; +import java.util.HashMap; +import java.util.List; + +/** + * + * @author JPEXS + */ +public class FilteredCheckTreeItem extends TreeItem { + + TreeItem object; + + public FilteredCheckTreeItem(AVM2Instruction instruction,TreeItem object) { + super(instruction, NOPRECEDENCE); + this.object=object; + } + + @Override + public String toString(ConstantPool constants, HashMap localRegNames, List fullyQualifiedNames) { + return object.toString(constants, localRegNames, fullyQualifiedNames); + } + +} diff --git a/trunk/src/com/jpexs/asdec/abc/avm2/treemodel/LocalRegTreeItem.java b/trunk/src/com/jpexs/asdec/abc/avm2/treemodel/LocalRegTreeItem.java index 643802baf..311e688ef 100644 --- a/trunk/src/com/jpexs/asdec/abc/avm2/treemodel/LocalRegTreeItem.java +++ b/trunk/src/com/jpexs/asdec/abc/avm2/treemodel/LocalRegTreeItem.java @@ -18,6 +18,7 @@ package com.jpexs.asdec.abc.avm2.treemodel; import com.jpexs.asdec.abc.avm2.ConstantPool; import com.jpexs.asdec.abc.avm2.instructions.AVM2Instruction; +import com.jpexs.asdec.abc.avm2.treemodel.clauses.FilterTreeItem; import java.util.HashMap; import java.util.List; @@ -37,6 +38,9 @@ public class LocalRegTreeItem extends TreeItem { @Override public String toString(ConstantPool constants, HashMap localRegNames, List fullyQualifiedNames) { + if(computedValue instanceof FilterTreeItem){ + return computedValue.toString(constants, localRegNames, fullyQualifiedNames); + } return hilight(localRegName(localRegNames, regIndex)); } diff --git a/trunk/src/com/jpexs/asdec/abc/avm2/treemodel/UnparsedTreeItem.java b/trunk/src/com/jpexs/asdec/abc/avm2/treemodel/UnparsedTreeItem.java index 41d84c7aa..3d398d1a0 100644 --- a/trunk/src/com/jpexs/asdec/abc/avm2/treemodel/UnparsedTreeItem.java +++ b/trunk/src/com/jpexs/asdec/abc/avm2/treemodel/UnparsedTreeItem.java @@ -32,6 +32,6 @@ public class UnparsedTreeItem extends TreeItem { @Override public String toString(ConstantPool constants, HashMap localRegNames, List fullyQualifiedNames) { - return hilight(value); + return value; } } diff --git a/trunk/src/com/jpexs/asdec/abc/avm2/treemodel/clauses/FilterTreeItem.java b/trunk/src/com/jpexs/asdec/abc/avm2/treemodel/clauses/FilterTreeItem.java new file mode 100644 index 000000000..f961d46a6 --- /dev/null +++ b/trunk/src/com/jpexs/asdec/abc/avm2/treemodel/clauses/FilterTreeItem.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2012 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.asdec.abc.avm2.treemodel.clauses; + +import com.jpexs.asdec.abc.avm2.ConstantPool; +import com.jpexs.asdec.abc.avm2.instructions.AVM2Instruction; +import com.jpexs.asdec.abc.avm2.treemodel.TreeItem; +import java.util.HashMap; +import java.util.List; + +/** + * + * @author JPEXS + */ +public class FilterTreeItem extends TreeItem { + + public TreeItem expression; + public TreeItem collection; + + public FilterTreeItem(AVM2Instruction instruction, TreeItem collection, TreeItem expression) { + super(instruction, NOPRECEDENCE); + this.expression = expression; + this.collection = collection; + } + + @Override + public String toString(ConstantPool constants, HashMap localRegNames, List fullyQualifiedNames) { + return collection.toString(constants, localRegNames, fullyQualifiedNames)+hilight(".(") + expression.toString(constants, localRegNames, fullyQualifiedNames) + hilight(")"); + } +} diff --git a/trunk/src/com/jpexs/asdec/abc/types/Multiname.java b/trunk/src/com/jpexs/asdec/abc/types/Multiname.java index 159f9ac30..1bb7bb1e8 100644 --- a/trunk/src/com/jpexs/asdec/abc/types/Multiname.java +++ b/trunk/src/com/jpexs/asdec/abc/types/Multiname.java @@ -198,7 +198,7 @@ public class Multiname { return ""; } if (name_index == 0) { - return "*"; + return (isAttribute() ? "@*" : "*"); } else { String name = constants.constant_string[name_index]; if ((fullyQualifiedNames != null) && fullyQualifiedNames.contains(name)) {