From acbaa19dac6c8bccc1d7e897e35bc3e2768430ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=F8=EDk?= Date: Sat, 25 May 2013 19:53:04 +0200 Subject: [PATCH] better duplicate handling --- .../localregs/SetLocalTypeIns.java | 8 +-- .../instructions/other/SetPropertyIns.java | 24 +++---- .../avm2/instructions/other/SetSlotIns.java | 12 ++-- .../abc/avm2/instructions/stack/DupIns.java | 6 +- .../abc/avm2/treemodel/CoerceTreeItem.java | 2 +- .../abc/avm2/treemodel/ConvertTreeItem.java | 2 +- .../avm2/treemodel/FullMultinameTreeItem.java | 20 ++++-- .../flash/action/swf4/ActionSetProperty.java | 8 +-- .../flash/action/swf4/ActionSetVariable.java | 2 +- .../flash/action/swf5/ActionSetMember.java | 2 +- .../decompiler/flash/graph/DuplicateItem.java | 71 +++++++++++++++++++ .../jpexs/decompiler/flash/graph/Graph.java | 9 +-- .../flash/graph/GraphTargetItem.java | 4 ++ 13 files changed, 129 insertions(+), 41 deletions(-) create mode 100644 trunk/src/com/jpexs/decompiler/flash/graph/DuplicateItem.java diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocalTypeIns.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocalTypeIns.java index b99f35025..cbddf76c1 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocalTypeIns.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocalTypeIns.java @@ -61,11 +61,11 @@ public abstract class SetLocalTypeIns extends InstructionDefinition implements S return; } if (value.getNotCoerced() instanceof IncrementTreeItem) { - GraphTargetItem inside = ((IncrementTreeItem) value.getNotCoerced()).object.getNotCoerced(); + GraphTargetItem inside = ((IncrementTreeItem) value.getNotCoerced()).object.getNotCoerced().getThroughDuplicate(); if (inside instanceof LocalRegTreeItem) { if (((LocalRegTreeItem) inside).regIndex == regId) { if (stack.size() > 0) { - GraphTargetItem top = stack.peek().getNotCoerced(); + GraphTargetItem top = stack.peek().getNotCoerced().getThroughDuplicate(); if (top == inside) { stack.pop(); stack.push(new PostIncrementTreeItem(ins, inside)); @@ -84,11 +84,11 @@ public abstract class SetLocalTypeIns extends InstructionDefinition implements S } if (value.getNotCoerced() instanceof DecrementTreeItem) { - GraphTargetItem inside = ((DecrementTreeItem) value.getNotCoerced()).object.getNotCoerced(); + GraphTargetItem inside = ((DecrementTreeItem) value.getNotCoerced()).object.getNotCoerced().getThroughDuplicate(); if (inside instanceof LocalRegTreeItem) { if (((LocalRegTreeItem) inside).regIndex == regId) { if (stack.size() > 0) { - GraphTargetItem top = stack.peek().getNotCoerced(); + GraphTargetItem top = stack.peek().getNotCoerced().getThroughDuplicate(); if (top == inside) { stack.pop(); stack.push(new PostDecrementTreeItem(ins, inside)); diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/SetPropertyIns.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/SetPropertyIns.java index 6943cec06..0a16c366c 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/SetPropertyIns.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/SetPropertyIns.java @@ -51,18 +51,18 @@ public class SetPropertyIns extends InstructionDefinition implements SetTypeIns GraphTargetItem value = (GraphTargetItem) stack.pop(); FullMultinameTreeItem multiname = resolveMultiname(stack, constants, multinameIndex, ins); GraphTargetItem obj = (GraphTargetItem) stack.pop(); - if (value.getThroughRegister() instanceof IncrementTreeItem) { - GraphTargetItem inside = ((IncrementTreeItem) value.getThroughRegister()).object.getThroughRegister().getNotCoerced(); + if (value.getThroughDuplicate().getThroughRegister().getThroughDuplicate() instanceof IncrementTreeItem) { + GraphTargetItem inside = ((IncrementTreeItem) value.getThroughDuplicate().getThroughRegister().getThroughDuplicate()).object.getThroughRegister().getNotCoerced().getThroughDuplicate(); if (inside instanceof GetPropertyTreeItem) { GetPropertyTreeItem insideProp = ((GetPropertyTreeItem) inside); if (insideProp.propertyName.compareSame(multiname)) { - GraphTargetItem insideObj = obj; + GraphTargetItem insideObj = obj.getThroughDuplicate(); if (insideObj instanceof LocalRegTreeItem) { - insideObj = ((LocalRegTreeItem) insideObj).computedValue.getThroughNotCompilable(); + insideObj = ((LocalRegTreeItem) insideObj).computedValue.getThroughNotCompilable().getThroughDuplicate(); } - if (insideProp.object == insideObj) { + if (insideProp.object.getThroughDuplicate() == insideObj) { if (stack.size() > 0) { - GraphTargetItem top = stack.peek().getNotCoerced(); + GraphTargetItem top = stack.peek().getNotCoerced().getThroughDuplicate(); if (top == insideProp) { stack.pop(); stack.push(new PostIncrementTreeItem(ins, insideProp)); @@ -81,18 +81,18 @@ public class SetPropertyIns extends InstructionDefinition implements SetTypeIns } } - if (value.getThroughRegister() instanceof DecrementTreeItem) { - GraphTargetItem inside = ((DecrementTreeItem) value.getThroughRegister()).object.getThroughRegister().getNotCoerced(); + if (value.getThroughDuplicate().getThroughRegister().getThroughDuplicate() instanceof DecrementTreeItem) { + GraphTargetItem inside = ((DecrementTreeItem) value.getThroughDuplicate().getThroughRegister().getThroughDuplicate()).object.getThroughRegister().getNotCoerced().getThroughDuplicate(); if (inside instanceof GetPropertyTreeItem) { GetPropertyTreeItem insideProp = ((GetPropertyTreeItem) inside); if (insideProp.propertyName.compareSame(multiname)) { - GraphTargetItem insideObj = obj; + GraphTargetItem insideObj = obj.getThroughDuplicate(); if (insideObj instanceof LocalRegTreeItem) { - insideObj = ((LocalRegTreeItem) insideObj).computedValue.getThroughNotCompilable(); + insideObj = ((LocalRegTreeItem) insideObj).computedValue.getThroughNotCompilable().getThroughDuplicate(); } - if (insideProp.object == insideObj) { + if (insideProp.object.getThroughDuplicate() == insideObj) { if (stack.size() > 0) { - GraphTargetItem top = stack.peek().getNotCoerced(); + GraphTargetItem top = stack.peek().getNotCoerced().getThroughDuplicate(); if (top == insideProp) { stack.pop(); stack.push(new PostDecrementTreeItem(ins, insideProp)); diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/SetSlotIns.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/SetSlotIns.java index d94b4c812..562f88520 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/SetSlotIns.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/SetSlotIns.java @@ -96,14 +96,14 @@ public class SetSlotIns extends InstructionDefinition implements SetTypeIns { }; } - if (value.getNotCoerced() instanceof IncrementTreeItem) { - GraphTargetItem inside = ((IncrementTreeItem) value.getNotCoerced()).object.getThroughRegister().getNotCoerced(); + if (value.getNotCoerced().getThroughDuplicate() instanceof IncrementTreeItem) { + GraphTargetItem inside = ((IncrementTreeItem) value.getNotCoerced()).object.getThroughRegister().getNotCoerced().getThroughDuplicate(); if (inside instanceof GetSlotTreeItem) { GetSlotTreeItem slotItem = (GetSlotTreeItem) inside; if ((slotItem.scope.getThroughRegister() == obj.getThroughRegister()) && (slotItem.slotName == slotname)) { if (stack.size() > 0) { - GraphTargetItem top = stack.peek().getNotCoerced(); + GraphTargetItem top = stack.peek().getNotCoerced().getThroughDuplicate(); if (top == inside) { stack.pop(); stack.push(new PostIncrementTreeItem(ins, inside)); @@ -121,14 +121,14 @@ public class SetSlotIns extends InstructionDefinition implements SetTypeIns { } } - if (value.getNotCoerced() instanceof DecrementTreeItem) { - GraphTargetItem inside = ((DecrementTreeItem) value.getNotCoerced()).object.getThroughRegister().getNotCoerced(); + if (value.getNotCoerced().getThroughDuplicate() instanceof DecrementTreeItem) { + GraphTargetItem inside = ((DecrementTreeItem) value.getNotCoerced()).object.getThroughRegister().getNotCoerced().getThroughDuplicate(); if (inside instanceof GetSlotTreeItem) { GetSlotTreeItem slotItem = (GetSlotTreeItem) inside; if ((slotItem.scope.getThroughRegister() == obj.getThroughRegister()) && (slotItem.slotName == slotname)) { if (stack.size() > 0) { - GraphTargetItem top = stack.peek().getNotCoerced(); + GraphTargetItem top = stack.peek().getNotCoerced().getThroughDuplicate(); if (top == inside) { stack.pop(); stack.push(new PostDecrementTreeItem(ins, inside)); diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/DupIns.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/DupIns.java index 35cec189e..592ec7982 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/DupIns.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/DupIns.java @@ -22,7 +22,7 @@ import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; import com.jpexs.decompiler.flash.abc.types.MethodInfo; -import com.jpexs.decompiler.flash.graph.GraphSourceItemPos; +import com.jpexs.decompiler.flash.graph.DuplicateItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; import java.util.HashMap; import java.util.List; @@ -45,8 +45,8 @@ public class DupIns extends InstructionDefinition { public void translate(boolean isStatic, int scriptIndex, int classIndex, java.util.HashMap localRegs, Stack stack, java.util.Stack scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap localRegNames, List fullyQualifiedNames) { GraphTargetItem v = stack.pop(); stack.push(v); - stack.push(v); - v.moreSrc.add(new GraphSourceItemPos(ins, 0)); + stack.push(new DuplicateItem(ins, v)); + //v.moreSrc.add(new GraphSourceItemPos(ins, 0)); } diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/treemodel/CoerceTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/treemodel/CoerceTreeItem.java index 8e5463158..a7275fcd9 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/treemodel/CoerceTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/treemodel/CoerceTreeItem.java @@ -41,6 +41,6 @@ public class CoerceTreeItem extends TreeItem { @Override public GraphTargetItem getNotCoerced() { - return value; + return value.getNotCoerced(); } } diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/treemodel/ConvertTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/treemodel/ConvertTreeItem.java index b97919107..84db5131c 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/treemodel/ConvertTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/treemodel/ConvertTreeItem.java @@ -41,6 +41,6 @@ public class ConvertTreeItem extends TreeItem { @Override public GraphTargetItem getNotCoerced() { - return value; + return value.getNotCoerced(); } } diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/treemodel/FullMultinameTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/treemodel/FullMultinameTreeItem.java index 13df70855..8f0ce5de9 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/treemodel/FullMultinameTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/treemodel/FullMultinameTreeItem.java @@ -97,26 +97,38 @@ public class FullMultinameTreeItem extends TreeItem { return false; } GraphTargetItem tiName = name; + if (name != null) { + name = name.getThroughDuplicate(); + } while (tiName instanceof LocalRegTreeItem) { - tiName = ((LocalRegTreeItem) tiName).computedValue.getThroughNotCompilable(); + tiName = ((LocalRegTreeItem) tiName).computedValue.getThroughNotCompilable().getThroughDuplicate(); } GraphTargetItem tiName2 = other.name; + if (tiName2 != null) { + tiName2 = tiName2.getThroughDuplicate(); + } while (tiName2 instanceof LocalRegTreeItem) { - tiName2 = ((LocalRegTreeItem) tiName2).computedValue.getThroughNotCompilable(); + tiName2 = ((LocalRegTreeItem) tiName2).computedValue.getThroughNotCompilable().getThroughDuplicate(); } if (tiName != tiName2) { return false; } GraphTargetItem tiNameSpace = namespace; + if (tiNameSpace != null) { + tiNameSpace = tiNameSpace.getThroughDuplicate(); + } while (tiNameSpace instanceof LocalRegTreeItem) { - tiNameSpace = ((LocalRegTreeItem) tiNameSpace).computedValue.getThroughNotCompilable(); + tiNameSpace = ((LocalRegTreeItem) tiNameSpace).computedValue.getThroughNotCompilable().getThroughDuplicate(); } GraphTargetItem tiNameSpace2 = other.namespace; + if (tiNameSpace2 != null) { + tiNameSpace2 = tiNameSpace2.getThroughDuplicate(); + } while (tiNameSpace2 instanceof LocalRegTreeItem) { - tiNameSpace2 = ((LocalRegTreeItem) tiNameSpace2).computedValue.getThroughNotCompilable(); + tiNameSpace2 = ((LocalRegTreeItem) tiNameSpace2).computedValue.getThroughNotCompilable().getThroughDuplicate(); } if (tiNameSpace != tiNameSpace2) { return false; diff --git a/trunk/src/com/jpexs/decompiler/flash/action/swf4/ActionSetProperty.java b/trunk/src/com/jpexs/decompiler/flash/action/swf4/ActionSetProperty.java index d5fe374d7..c0e2cdf85 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/swf4/ActionSetProperty.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/swf4/ActionSetProperty.java @@ -42,16 +42,16 @@ public class ActionSetProperty extends Action { @Override public void translate(Stack stack, List output, java.util.HashMap regNames, HashMap variables, HashMap functions) { - GraphTargetItem value = stack.pop(); - GraphTargetItem index = stack.pop(); - GraphTargetItem target = stack.pop(); + GraphTargetItem value = stack.pop().getThroughDuplicate(); + GraphTargetItem index = stack.pop().getThroughDuplicate(); + GraphTargetItem target = stack.pop().getThroughDuplicate(); int indexInt = 0; if (index instanceof DirectValueTreeItem) { if (((DirectValueTreeItem) index).value instanceof Long) { indexInt = (int) (long) (Long) ((DirectValueTreeItem) index).value; } } - if (value instanceof IncrementTreeItem) { + if (value.getThroughDuplicate() instanceof IncrementTreeItem) { GraphTargetItem obj = ((IncrementTreeItem) value).object; if (!stack.isEmpty()) { if (stack.peek().equals(obj)) { diff --git a/trunk/src/com/jpexs/decompiler/flash/action/swf4/ActionSetVariable.java b/trunk/src/com/jpexs/decompiler/flash/action/swf4/ActionSetVariable.java index dbce2bd95..0305524eb 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/swf4/ActionSetVariable.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/swf4/ActionSetVariable.java @@ -44,7 +44,7 @@ public class ActionSetVariable extends Action { @Override public void translate(Stack stack, List output, java.util.HashMap regNames, HashMap variables, HashMap functions) { - GraphTargetItem value = stack.pop(); + GraphTargetItem value = stack.pop().getThroughDuplicate(); GraphTargetItem name = stack.pop(); variables.put(Highlighting.stripHilights(name.toStringNoQuotes((ConstantPool) null)), value); if (value instanceof IncrementTreeItem) { diff --git a/trunk/src/com/jpexs/decompiler/flash/action/swf5/ActionSetMember.java b/trunk/src/com/jpexs/decompiler/flash/action/swf5/ActionSetMember.java index 149b4100b..445b1f4c7 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/swf5/ActionSetMember.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/swf5/ActionSetMember.java @@ -42,7 +42,7 @@ public class ActionSetMember extends Action { @Override public void translate(Stack stack, List output, java.util.HashMap regNames, HashMap variables, HashMap functions) { - GraphTargetItem value = stack.pop(); + GraphTargetItem value = stack.pop().getThroughDuplicate(); GraphTargetItem memberName = stack.pop(); GraphTargetItem object = stack.pop(); if (value instanceof IncrementTreeItem) { diff --git a/trunk/src/com/jpexs/decompiler/flash/graph/DuplicateItem.java b/trunk/src/com/jpexs/decompiler/flash/graph/DuplicateItem.java new file mode 100644 index 000000000..550e07739 --- /dev/null +++ b/trunk/src/com/jpexs/decompiler/flash/graph/DuplicateItem.java @@ -0,0 +1,71 @@ +/* + * 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 DuplicateItem extends GraphTargetItem { + + public DuplicateItem(GraphSourceItem src, GraphTargetItem value) { + super(src, value.precedence); + this.value = value; + } + + @Override + public boolean toBoolean() { + return value.toBoolean(); + } + + @Override + public double toNumber() { + return value.toNumber(); + } + + @Override + public String toString(List localData) { + return value.toString(localData); + } + + @Override + public GraphTargetItem getNotCoerced() { + return value.getNotCoerced(); + } + + @Override + public GraphTargetItem getThroughRegister() { + return value.getThroughRegister(); + } + + @Override + public GraphTargetItem getThroughDuplicate() { + return value.getThroughDuplicate(); + } + + @Override + public boolean isCompileTime() { + return value.isCompileTime(); + } + + @Override + public boolean isVariableComputed() { + return value.isVariableComputed(); + } +} diff --git a/trunk/src/com/jpexs/decompiler/flash/graph/Graph.java b/trunk/src/com/jpexs/decompiler/flash/graph/Graph.java index cd77e142e..200135741 100644 --- a/trunk/src/com/jpexs/decompiler/flash/graph/Graph.java +++ b/trunk/src/com/jpexs/decompiler/flash/graph/Graph.java @@ -594,9 +594,10 @@ public class Graph { if ((ti = checkLoop(next, stopPart, loops)) != null) { ret.add(ti); } else { + GraphTargetItem first = stack.pop(); printGraph(visited, localData, stack, allParts, parent, next, reversed ? sp1 : sp0, loops, forFinalCommands); GraphTargetItem second = stack.pop(); - GraphTargetItem first = stack.pop(); + if (!reversed) { AndItem a = new AndItem(null, first, second); stack.push(a); @@ -642,10 +643,10 @@ public class Graph { if ((ti = checkLoop(next, stopPart, loops)) != null) { ret.add(ti); } else { - printGraph(visited, localData, stack, allParts, parent, next, reversed ? sp1 : sp0, loops, forFinalCommands); - - GraphTargetItem second = stack.pop(); GraphTargetItem first = stack.pop(); + printGraph(visited, localData, stack, allParts, parent, next, reversed ? sp1 : sp0, loops, forFinalCommands); + GraphTargetItem second = stack.pop(); + if (reversed) { AndItem a = new AndItem(null, first, second); diff --git a/trunk/src/com/jpexs/decompiler/flash/graph/GraphTargetItem.java b/trunk/src/com/jpexs/decompiler/flash/graph/GraphTargetItem.java index 96f25f0a2..7423442c9 100644 --- a/trunk/src/com/jpexs/decompiler/flash/graph/GraphTargetItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/graph/GraphTargetItem.java @@ -158,4 +158,8 @@ public abstract class GraphTargetItem { public GraphTargetItem getThroughNotCompilable() { return this; } + + public GraphTargetItem getThroughDuplicate() { + return this; + } }