diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java index 36ae75e87..fb52d5af5 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java @@ -226,7 +226,7 @@ public class AVM2Code implements Serializable { new EqualsIns(), new EscXAttrIns(), new EscXElemIns(), - new InstructionDefinition(0x5f, "finddef", new int[]{AVM2Code.DAT_MULTINAME_INDEX}), + new FindDefIns(), /* //Duplicate OPCODE with deldescendants. Prefering deldescendants (found in FLEX compiler) new InstructionDefinition(0x5b,"findpropglobalstrict",new int[]{AVM2Code.DAT_MULTINAME_INDEX}){ diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/FindDefIns.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/FindDefIns.java new file mode 100644 index 000000000..0f53c6250 --- /dev/null +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/FindDefIns.java @@ -0,0 +1,50 @@ +/* + * 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.abc.avm2.instructions.other; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.FindDefAVM2Item; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.flash.abc.types.Multiname; +import com.jpexs.decompiler.graph.GraphTargetItem; +import java.util.HashMap; +import java.util.List; +import java.util.Stack; + +public class FindDefIns extends InstructionDefinition { + + public FindDefIns() { + super(0x5f, "finddef", new int[]{AVM2Code.DAT_MULTINAME_INDEX}); + } + + @Override + 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, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { + int multinameIndex = ins.operands[0]; + Multiname multiname = constants.getMultiname(multinameIndex); + stack.push(new FindDefAVM2Item(ins, multiname)); + } + + @Override + public int getScopeStackDelta(AVM2Instruction ins, ABC abc) { + return 1; //multiname may not be runtime + } +} diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/FindDefAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/FindDefAVM2Item.java new file mode 100644 index 000000000..13f0d068f --- /dev/null +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/FindDefAVM2Item.java @@ -0,0 +1,37 @@ +/* + * 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.abc.avm2.model; + +import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; +import com.jpexs.decompiler.flash.abc.types.Multiname; +import com.jpexs.decompiler.flash.helpers.GraphTextWriter; +import com.jpexs.decompiler.graph.model.LocalData; + +public class FindDefAVM2Item extends AVM2Item { + + public Multiname propertyName; + + public FindDefAVM2Item(AVM2Instruction instruction, Multiname propertyName) { + super(instruction, PRECEDENCE_PRIMARY); + this.propertyName = propertyName; + } + + @Override + protected GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) { + return writer.append(propertyName.getNamespace(localData.constantsAvm2).getName(localData.constantsAvm2)); + } +} diff --git a/trunk/src/com/jpexs/decompiler/graph/Graph.java b/trunk/src/com/jpexs/decompiler/graph/Graph.java index aa04faaf4..7b3862289 100644 --- a/trunk/src/com/jpexs/decompiler/graph/Graph.java +++ b/trunk/src/com/jpexs/decompiler/graph/Graph.java @@ -1769,13 +1769,24 @@ public class Graph { if (!isEmpty) { onFalse = printGraph(visited, prepareBranchLocalData(localData), falseStack, allParts, part, nps.get(0), stopPart2, loops, staticOperation, path); } - if (isEmpty(onTrue) && isEmpty(onFalse) && (trueStack.size() > trueStackSizeBefore) && (falseStack.size() > falseStackSizeBefore)) { + if (isEmpty(onTrue) && isEmpty(onFalse) && (trueStack.size() == trueStackSizeBefore + 1) && (falseStack.size() == falseStackSizeBefore + 1)) { stack.push(new TernarOpItem(null, expr, trueStack.pop(), falseStack.pop())); } else { currentRet.add(new IfItem(null, expr, onTrue, onFalse)); } if (next != null) { - printGraph(visited, localData, stack, allParts, part, next, stopPart, loops, currentRet, staticOperation, path); + if (trueStack.size() != trueStackSizeBefore || falseStack.size() != falseStackSizeBefore) { + // it's a hack, because duplicates all instructions in the next part, but better than EmptyStackException + onTrue = printGraph(visited, localData, trueStack, allParts, part, next, stopPart, loops, null, staticOperation, path); + onFalse = printGraph(visited, localData, falseStack, allParts, part, next, stopPart, loops, null, staticOperation, path); + if (isEmpty(onTrue) && isEmpty(onFalse) && (trueStack.size() == trueStackSizeBefore + 1) && (falseStack.size() == falseStackSizeBefore + 1)) { + stack.push(new TernarOpItem(null, expr, trueStack.pop(), falseStack.pop())); + } else { + currentRet.add(new IfItem(null, expr, onTrue, onFalse)); + } + } else { + printGraph(visited, localData, stack, allParts, part, next, stopPart, loops, currentRet, staticOperation, path); + } //currentRet.addAll(); } }