diff --git a/trunk/src/com/jpexs/asdec/abc/avm2/AVM2Code.java b/trunk/src/com/jpexs/asdec/abc/avm2/AVM2Code.java index 29a88373e..e1894468b 100644 --- a/trunk/src/com/jpexs/asdec/abc/avm2/AVM2Code.java +++ b/trunk/src/com/jpexs/asdec/abc/avm2/AVM2Code.java @@ -527,6 +527,8 @@ public class AVM2Code { }; //endoflist public static InstructionDefinition instructionSetByCode[] = buildInstructionSetByCode(); + + public boolean hideTemporaryRegisters=true; private static InstructionDefinition[] buildInstructionSetByCode() { InstructionDefinition result[] = new InstructionDefinition[256]; @@ -948,7 +950,7 @@ public class AVM2Code { return localRegNames; } - private void clearKilledAssigments(List output) { + private void clearTemporaryRegisters(List output) { for (int i = 0; i < output.size(); i++) { if (output.get(i) instanceof SetLocalTreeItem) { if (isKilled(((SetLocalTreeItem) output.get(i)).regIndex, 0, code.size() - 1)) { @@ -1471,148 +1473,6 @@ public class AVM2Code { } else if (insAfter.definition instanceof IfTrueIns) { //stack.add("(" + stack.pop() + ")||"); isAnd = false; - } else if ((insAfter.definition instanceof IncrementIIns) || ((insAfter.definition instanceof IncrementIns))) { - int np = -1; - if (((np = ipOfType(ip + 2, false, SetLocalTypeIns.class, CoerceOrConvertTypeIns.class, start, end)) > -1) - && (ipOfType(ip - 1, true, GetLocalTypeIns.class, CoerceOrConvertTypeIns.class, start, end) > -1)) { - stack.add(new PostIncrementTreeItem(insAfter, stack.pop())); - ip = np + 1; - addr = pos2adr(ip); - break; - } - if (((ip - 1 >= start) && (ip + 2 <= end)) - && (code.get(ip + 2).definition instanceof SetLocalTypeIns) - && (isKilled(((SetLocalTypeIns) code.get(ip + 2).definition).getRegisterId(code.get(ip + 2)), ip + 3, end))) { - int pos = -1; - for (int d = ip + 3; d <= end; d++) { - if (!((code.get(d).definition instanceof GetLocalTypeIns) - && (isKilled(((GetLocalTypeIns) code.get(d).definition).getRegisterId(code.get(d)), d + 1, end)))) { - pos = d; - break; - } - } - if (pos > -1) { - if (code.get(pos).definition instanceof SetTypeIns) { - stack.push(new PostIncrementTreeItem(insAfter, stack.pop())); - ip = pos + 1; - addr = pos2adr(ip); - break; - } - } - - } - ins.definition.translate(isStatic, classIndex, localRegs, stack, scopeStack, constants, ins, method_info, output, body, abc, localRegNames); - ip++; - addr = pos2adr(ip); - break; - } else if ((insAfter.definition instanceof DecrementIIns) || ((insAfter.definition instanceof DecrementIns))) { - int np = -1; - if (((np = ipOfType(ip + 2, false, SetLocalTypeIns.class, CoerceOrConvertTypeIns.class, start, end)) > -1) - && (ipOfType(ip - 1, true, GetLocalTypeIns.class, CoerceOrConvertTypeIns.class, start, end) > -1)) { - stack.add(new PostDecrementTreeItem(insAfter, stack.pop())); - ip = np + 1; - addr = pos2adr(ip); - break; - } - if (((ip - 1 >= start) && (ip + 2 <= end)) - && (code.get(ip + 2).definition instanceof SetLocalTypeIns) - && (isKilled(((SetLocalTypeIns) code.get(ip + 2).definition).getRegisterId(code.get(ip + 2)), ip + 3, end))) { - int pos = -1; - for (int d = ip + 3; d <= end; d++) { - if (!((code.get(d).definition instanceof GetLocalTypeIns) - && (isKilled(((GetLocalTypeIns) code.get(d).definition).getRegisterId(code.get(d)), d + 1, end)))) { - pos = d; - break; - } - } - if (pos > -1) { - if (code.get(pos).definition instanceof SetTypeIns) { - stack.push(new PostDecrementTreeItem(insAfter, stack.pop())); - ip = pos + 1; - addr = pos2adr(ip); - break; - } - } - - } - ins.definition.translate(isStatic, classIndex, localRegs, stack, scopeStack, constants, ins, method_info, output, body, abc, localRegNames); - ip++; - addr = pos2adr(ip); - break; - } else if ((insBefore.definition instanceof IncrementIIns) || ((insBefore.definition instanceof IncrementIns))) { - if (((ip - 2 >= start) && (ip + 2 <= end)) && (code.get(ip + 1).definition instanceof CoerceOrConvertTypeIns) && (code.get(ip + 2).definition instanceof SetLocalTypeIns) && (code.get(ip - 2).definition instanceof GetLocalTypeIns)) { - stack.pop(); - int regId = ((SetLocalTypeIns) code.get(ip + 2).definition).getRegisterId(code.get(ip + 2)); - stack.add(new PreIncrementTreeItem(insBefore, new LocalRegTreeItem(code.get(ip + 2), regId, localRegs.get(regId)))); - ip += 3; - addr = pos2adr(ip); - break; - } - if (((ip - 1 >= start) && (ip + 2 <= end)) - && (code.get(ip + 1).definition instanceof SetLocalTypeIns) - && (isKilled(((SetLocalTypeIns) code.get(ip + 1).definition).getRegisterId(code.get(ip + 1)), ip + 2, end))) { - int pos = -1; - for (int d = ip + 2; d <= end; d++) { - if (!((code.get(d).definition instanceof GetLocalTypeIns) - && (isKilled(((GetLocalTypeIns) code.get(d).definition).getRegisterId(code.get(d)), d + 1, end)))) { - pos = d; - break; - } - } - if (pos > -1) { - if (code.get(pos).definition instanceof SetTypeIns) { - TreeItem s = stack.pop(); - if (s instanceof IncrementTreeItem) { - stack.push(new PreIncrementTreeItem(insBefore, ((IncrementTreeItem) s).object)); - } - ip = pos + 1; - addr = pos2adr(ip); - break; - } - } - - } - ins.definition.translate(isStatic, classIndex, localRegs, stack, scopeStack, constants, ins, method_info, output, body, abc, localRegNames); - ip++; - addr = pos2adr(ip); - break; - } else if ((insBefore.definition instanceof DecrementIIns) || ((insBefore.definition instanceof DecrementIns))) { - if (((ip - 2 >= start) && (ip + 2 <= end)) && (code.get(ip + 1).definition instanceof CoerceOrConvertTypeIns) && (code.get(ip + 2).definition instanceof SetLocalTypeIns) && (code.get(ip - 2).definition instanceof GetLocalTypeIns)) { - stack.pop(); - int regId = ((SetLocalTypeIns) code.get(ip + 2).definition).getRegisterId(code.get(ip + 2)); - stack.add(new PreDecrementTreeItem(insBefore, new LocalRegTreeItem(code.get(ip + 2), regId, localRegs.get(regId)))); - ip += 3; - addr = pos2adr(ip); - break; - } - if (((ip - 1 >= start) && (ip + 2 <= end)) - && (code.get(ip + 1).definition instanceof SetLocalTypeIns) - && (isKilled(((SetLocalTypeIns) code.get(ip + 1).definition).getRegisterId(code.get(ip + 1)), ip + 2, end))) { - int pos = -1; - for (int d = ip + 2; d <= end; d++) { - if (!((code.get(d).definition instanceof GetLocalTypeIns) - && (isKilled(((GetLocalTypeIns) code.get(d).definition).getRegisterId(code.get(d)), d + 1, end)))) { - pos = d; - break; - } - } - if (pos > -1) { - if (code.get(pos).definition instanceof SetTypeIns) { - TreeItem s = stack.pop(); - if (s instanceof DecrementTreeItem) { - stack.push(new PreDecrementTreeItem(insBefore, ((DecrementTreeItem) s).object)); - } - ip = pos + 1; - addr = pos2adr(ip); - break; - } - } - - } - ins.definition.translate(isStatic, classIndex, localRegs, stack, scopeStack, constants, ins, method_info, output, body, abc, localRegNames); - ip++; - addr = pos2adr(ip); - break; } else if (insAfter.definition instanceof SetLocalTypeIns) { //chained assignments int reg = (((SetLocalTypeIns) insAfter.definition).getRegisterId(insAfter)); @@ -1728,7 +1588,10 @@ public class AVM2Code { if (debugMode) { System.out.println("CLOSE SubSource:" + start + "-" + end + " " + code.get(start).toString() + " to " + code.get(end).toString()); } - //clearKilledAssigments(output); + if(hideTemporaryRegisters) + { + clearTemporaryRegisters(output); + } return new ConvertOutput(stack, output); } catch (ConvertException cex) { throw cex; @@ -1736,6 +1599,7 @@ public class AVM2Code { if (ex instanceof UnknownJumpException) { throw (UnknownJumpException) ex; } + ex.printStackTrace(); throw new ConvertException(ex.getClass().getSimpleName(), ip); } } @@ -1813,6 +1677,7 @@ public class AVM2Code { list = toSource(isStatic, classIndex, localRegs, new Stack(), new Stack(), abc, constants, method_info, body, 0, code.size() - 1, localRegNames).output; s = listToString(list, constants, localRegNames); } catch (Exception ex) { + ex.printStackTrace(); s = "/*\r\n * Decompilation error\r\n * Code may be obfuscated\r\n * Error Message: " + ex.getMessage() + "\r\n */"; return s; } @@ -1842,7 +1707,7 @@ public class AVM2Code { } HashMap localRegTypes = getLocalRegTypes(constants); for (int i = paramCount + 1; i < regCount; i++) { - if ((!(localRegs.get(i) instanceof NewActivationTreeItem))/*&&(!isKilled(i, 0, code.size()-1))*/) { + if ((!(localRegs.get(i) instanceof NewActivationTreeItem)&&((!hideTemporaryRegisters)||(!isKilled(i, 0, code.size()-1))))) { sub += "var " + TreeItem.localRegName(localRegNames, i); if (localRegTypes.containsKey(i)) { sub += ":" + localRegTypes.get(i); diff --git a/trunk/src/com/jpexs/asdec/abc/avm2/instructions/localregs/SetLocal0Ins.java b/trunk/src/com/jpexs/asdec/abc/avm2/instructions/localregs/SetLocal0Ins.java index 0d3b0289a..4dd0989c6 100644 --- a/trunk/src/com/jpexs/asdec/abc/avm2/instructions/localregs/SetLocal0Ins.java +++ b/trunk/src/com/jpexs/asdec/abc/avm2/instructions/localregs/SetLocal0Ins.java @@ -31,42 +31,13 @@ import java.util.HashMap; import java.util.List; import java.util.Stack; -public class SetLocal0Ins extends InstructionDefinition implements SetTypeIns, SetLocalTypeIns { +public class SetLocal0Ins extends SetLocalTypeIns { public SetLocal0Ins() { super(0xd4, "setlocal_0", new int[]{}); } - - @Override - public void execute(LocalDataArea lda, ConstantPool constants, List arguments) { - lda.localRegisters.put(0, lda.operandStack.pop()); - } - - @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) { - TreeItem val = (TreeItem) stack.pop(); - localRegs.put(0, val); - if (val instanceof NewActivationTreeItem) { - return; - } - if (val instanceof FindPropertyTreeItem) { - return; - } - //if(val.startsWith("catchscope ")) return; - //if(val.startsWith("newactivation()")) return; - output.add(new SetLocalTreeItem(ins, 0, val)); - } - - public String getObject(Stack stack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List output, com.jpexs.asdec.abc.types.MethodBody body, HashMap localRegNames) { - return TreeItem.localRegName(localRegNames, 0); - } - + public int getRegisterId(AVM2Instruction ins) { return 0; } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -1; - } } diff --git a/trunk/src/com/jpexs/asdec/abc/avm2/instructions/localregs/SetLocal1Ins.java b/trunk/src/com/jpexs/asdec/abc/avm2/instructions/localregs/SetLocal1Ins.java index d965f5ea6..75e97a24b 100644 --- a/trunk/src/com/jpexs/asdec/abc/avm2/instructions/localregs/SetLocal1Ins.java +++ b/trunk/src/com/jpexs/asdec/abc/avm2/instructions/localregs/SetLocal1Ins.java @@ -31,42 +31,14 @@ import java.util.HashMap; import java.util.List; import java.util.Stack; -public class SetLocal1Ins extends InstructionDefinition implements SetTypeIns, SetLocalTypeIns { +public class SetLocal1Ins extends SetLocalTypeIns { public SetLocal1Ins() { super(0xd5, "setlocal_1", new int[]{}); } - @Override - public void execute(LocalDataArea lda, ConstantPool constants, List arguments) { - lda.localRegisters.put(1, lda.operandStack.pop()); - } - - @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) { - TreeItem val = (TreeItem) stack.pop(); - localRegs.put(1, val); - if (val instanceof NewActivationTreeItem) { - return; - } - if (val instanceof FindPropertyTreeItem) { - return; - } - //if(val.startsWith("catchscope ")) return; - //if(val.startsWith("newactivation()")) return; - output.add(new SetLocalTreeItem(ins, 1, val)); - } - - public String getObject(Stack stack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List output, com.jpexs.asdec.abc.types.MethodBody body, HashMap localRegNames) { - return TreeItem.localRegName(localRegNames, 1); - } - public int getRegisterId(AVM2Instruction ins) { return 1; } - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -1; - } } diff --git a/trunk/src/com/jpexs/asdec/abc/avm2/instructions/localregs/SetLocal2Ins.java b/trunk/src/com/jpexs/asdec/abc/avm2/instructions/localregs/SetLocal2Ins.java index 99de46fae..9fbef3e60 100644 --- a/trunk/src/com/jpexs/asdec/abc/avm2/instructions/localregs/SetLocal2Ins.java +++ b/trunk/src/com/jpexs/asdec/abc/avm2/instructions/localregs/SetLocal2Ins.java @@ -31,42 +31,13 @@ import java.util.HashMap; import java.util.List; import java.util.Stack; -public class SetLocal2Ins extends InstructionDefinition implements SetTypeIns, SetLocalTypeIns { +public class SetLocal2Ins extends SetLocalTypeIns { public SetLocal2Ins() { super(0xd6, "setlocal_2", new int[]{}); } - @Override - public void execute(LocalDataArea lda, ConstantPool constants, List arguments) { - lda.localRegisters.put(2, lda.operandStack.pop()); - } - - @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) { - TreeItem val = (TreeItem) stack.pop(); - localRegs.put(2, val); - if (val instanceof NewActivationTreeItem) { - return; - } - if (val instanceof FindPropertyTreeItem) { - return; - } - //if(val.startsWith("catchscope ")) return; - //if(val.startsWith("newactivation()")) return; - output.add(new SetLocalTreeItem(ins, 2, val)); - } - - public String getObject(Stack stack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List output, com.jpexs.asdec.abc.types.MethodBody body, HashMap localRegNames) { - return TreeItem.localRegName(localRegNames, 2); - } - public int getRegisterId(AVM2Instruction ins) { return 2; } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -1; - } } diff --git a/trunk/src/com/jpexs/asdec/abc/avm2/instructions/localregs/SetLocal3Ins.java b/trunk/src/com/jpexs/asdec/abc/avm2/instructions/localregs/SetLocal3Ins.java index fe49c6060..7c8d375cc 100644 --- a/trunk/src/com/jpexs/asdec/abc/avm2/instructions/localregs/SetLocal3Ins.java +++ b/trunk/src/com/jpexs/asdec/abc/avm2/instructions/localregs/SetLocal3Ins.java @@ -31,42 +31,13 @@ import java.util.HashMap; import java.util.List; import java.util.Stack; -public class SetLocal3Ins extends InstructionDefinition implements SetTypeIns, SetLocalTypeIns { +public class SetLocal3Ins extends SetLocalTypeIns { public SetLocal3Ins() { super(0xd7, "setlocal_3", new int[]{}); } - @Override - public void execute(LocalDataArea lda, ConstantPool constants, List arguments) { - lda.localRegisters.put(3, lda.operandStack.pop()); - } - - @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) { - TreeItem val = (TreeItem) stack.pop(); - localRegs.put(3, val); - if (val instanceof NewActivationTreeItem) { - return; - } - if (val instanceof FindPropertyTreeItem) { - return; - } - //if(val.startsWith("catchscope ")) return; - //if(val.startsWith("newactivation()")) return; - output.add(new SetLocalTreeItem(ins, 3, val)); - } - - public String getObject(Stack stack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List output, com.jpexs.asdec.abc.types.MethodBody body, HashMap localRegNames) { - return TreeItem.localRegName(localRegNames, 3); - } - public int getRegisterId(AVM2Instruction ins) { return 3; } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -1; - } } diff --git a/trunk/src/com/jpexs/asdec/abc/avm2/instructions/localregs/SetLocalIns.java b/trunk/src/com/jpexs/asdec/abc/avm2/instructions/localregs/SetLocalIns.java index 40360b85b..4a1882368 100644 --- a/trunk/src/com/jpexs/asdec/abc/avm2/instructions/localregs/SetLocalIns.java +++ b/trunk/src/com/jpexs/asdec/abc/avm2/instructions/localregs/SetLocalIns.java @@ -32,42 +32,13 @@ import java.util.HashMap; import java.util.List; import java.util.Stack; -public class SetLocalIns extends InstructionDefinition implements SetTypeIns, SetLocalTypeIns { +public class SetLocalIns extends SetLocalTypeIns { public SetLocalIns() { super(0x63, "setlocal", new int[]{AVM2Code.DAT_LOCAL_REG_INDEX}); } - @Override - public void execute(LocalDataArea lda, ConstantPool constants, List arguments) { - lda.localRegisters.put((int) (long) (Long) arguments.get(0), lda.operandStack.pop()); - } - - @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) { - TreeItem val = (TreeItem) stack.pop(); - localRegs.put(ins.operands[0], val); - if (val instanceof NewActivationTreeItem) { - return; - } - if (val instanceof FindPropertyTreeItem) { - return; - } - //if(val.startsWith("catchscope ")) return; - //if(val.startsWith("newactivation()")) return; - output.add(new SetLocalTreeItem(ins, ins.operands[0], val)); - } - - public String getObject(Stack stack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List output, com.jpexs.asdec.abc.types.MethodBody body, HashMap localRegNames) { - return TreeItem.localRegName(localRegNames, ins.operands[0]); - } - public int getRegisterId(AVM2Instruction ins) { return ins.operands[0]; } - - @Override - public int getStackDelta(AVM2Instruction ins, ABC abc) { - return -1; - } } diff --git a/trunk/src/com/jpexs/asdec/abc/avm2/instructions/localregs/SetLocalTypeIns.java b/trunk/src/com/jpexs/asdec/abc/avm2/instructions/localregs/SetLocalTypeIns.java index ea43a43c0..ff327a687 100644 --- a/trunk/src/com/jpexs/asdec/abc/avm2/instructions/localregs/SetLocalTypeIns.java +++ b/trunk/src/com/jpexs/asdec/abc/avm2/instructions/localregs/SetLocalTypeIns.java @@ -16,9 +16,104 @@ */ package com.jpexs.asdec.abc.avm2.instructions.localregs; +import com.jpexs.asdec.abc.ABC; +import com.jpexs.asdec.abc.avm2.ConstantPool; import com.jpexs.asdec.abc.avm2.instructions.AVM2Instruction; +import com.jpexs.asdec.abc.avm2.instructions.InstructionDefinition; +import com.jpexs.asdec.abc.avm2.instructions.SetTypeIns; +import com.jpexs.asdec.abc.avm2.treemodel.DecrementTreeItem; +import com.jpexs.asdec.abc.avm2.treemodel.FindPropertyTreeItem; +import com.jpexs.asdec.abc.avm2.treemodel.GetPropertyTreeItem; +import com.jpexs.asdec.abc.avm2.treemodel.IncrementTreeItem; +import com.jpexs.asdec.abc.avm2.treemodel.LocalRegTreeItem; +import com.jpexs.asdec.abc.avm2.treemodel.NewActivationTreeItem; +import com.jpexs.asdec.abc.avm2.treemodel.PostDecrementTreeItem; +import com.jpexs.asdec.abc.avm2.treemodel.PostIncrementTreeItem; +import com.jpexs.asdec.abc.avm2.treemodel.SetLocalTreeItem; +import com.jpexs.asdec.abc.avm2.treemodel.TreeItem; +import com.jpexs.asdec.abc.avm2.treemodel.operations.PreDecrementTreeItem; +import com.jpexs.asdec.abc.avm2.treemodel.operations.PreIncrementTreeItem; +import com.jpexs.asdec.abc.types.MethodInfo; +import java.util.HashMap; +import java.util.List; +import java.util.Stack; -public interface SetLocalTypeIns { +public abstract class SetLocalTypeIns extends InstructionDefinition implements SetTypeIns { + + public SetLocalTypeIns(int instructionCode, String instructionName, int[] operands) { + super(instructionCode, instructionName, operands); + } + + @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) { + int regId = getRegisterId(ins); + TreeItem value = (TreeItem) stack.pop(); + localRegs.put(regId, value); + if (value instanceof NewActivationTreeItem) { + return; + } + if (value instanceof FindPropertyTreeItem) { + return; + } + if (value.getNotCoerced() instanceof IncrementTreeItem) { + TreeItem inside = ((IncrementTreeItem) value.getNotCoerced()).object.getNotCoerced(); + if (inside instanceof LocalRegTreeItem) { + if (((LocalRegTreeItem) inside).regIndex == regId) { + if (stack.size() > 0) { + TreeItem top = stack.peek().getNotCoerced(); + if (top == inside) { + stack.pop(); + stack.push(new PostIncrementTreeItem(ins, inside)); + } else if ((top instanceof IncrementTreeItem) && (((IncrementTreeItem) top).object == inside)) { + stack.pop(); + stack.push(new PreIncrementTreeItem(ins, inside)); + } else { + output.add(new PostIncrementTreeItem(ins, inside)); + } + } else { + output.add(new PostIncrementTreeItem(ins, inside)); + } + return; + } + } + } + + if (value.getNotCoerced() instanceof DecrementTreeItem) { + TreeItem inside = ((DecrementTreeItem) value.getNotCoerced()).object.getNotCoerced(); + if (inside instanceof LocalRegTreeItem) { + if (((LocalRegTreeItem) inside).regIndex == regId) { + if (stack.size() > 0) { + TreeItem top = stack.peek().getNotCoerced(); + if (top == inside) { + stack.pop(); + stack.push(new PostDecrementTreeItem(ins, inside)); + } else if ((top instanceof DecrementTreeItem) && (((DecrementTreeItem) top).object == inside)) { + stack.pop(); + stack.push(new PreDecrementTreeItem(ins, inside)); + } else { + output.add(new PostDecrementTreeItem(ins, inside)); + } + } else { + output.add(new PostDecrementTreeItem(ins, inside)); + } + return; + } + } + } + + //if(val.startsWith("catchscope ")) return; + //if(val.startsWith("newactivation()")) return; + output.add(new SetLocalTreeItem(ins, regId, value)); + } + + public String getObject(Stack stack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List output, com.jpexs.asdec.abc.types.MethodBody body, HashMap localRegNames) { + return TreeItem.localRegName(localRegNames, getRegisterId(ins)); + } + + @Override + public int getStackDelta(AVM2Instruction ins, ABC abc) { + return -1; + } public abstract int getRegisterId(AVM2Instruction ins); } diff --git a/trunk/src/com/jpexs/asdec/abc/avm2/instructions/other/SetPropertyIns.java b/trunk/src/com/jpexs/asdec/abc/avm2/instructions/other/SetPropertyIns.java index 2a5c5e933..dcf881403 100644 --- a/trunk/src/com/jpexs/asdec/abc/avm2/instructions/other/SetPropertyIns.java +++ b/trunk/src/com/jpexs/asdec/abc/avm2/instructions/other/SetPropertyIns.java @@ -22,9 +22,17 @@ import com.jpexs.asdec.abc.avm2.ConstantPool; import com.jpexs.asdec.abc.avm2.instructions.AVM2Instruction; import com.jpexs.asdec.abc.avm2.instructions.InstructionDefinition; import com.jpexs.asdec.abc.avm2.instructions.SetTypeIns; +import com.jpexs.asdec.abc.avm2.treemodel.DecrementTreeItem; import com.jpexs.asdec.abc.avm2.treemodel.FullMultinameTreeItem; +import com.jpexs.asdec.abc.avm2.treemodel.GetPropertyTreeItem; +import com.jpexs.asdec.abc.avm2.treemodel.IncrementTreeItem; +import com.jpexs.asdec.abc.avm2.treemodel.LocalRegTreeItem; +import com.jpexs.asdec.abc.avm2.treemodel.PostDecrementTreeItem; +import com.jpexs.asdec.abc.avm2.treemodel.PostIncrementTreeItem; import com.jpexs.asdec.abc.avm2.treemodel.SetPropertyTreeItem; import com.jpexs.asdec.abc.avm2.treemodel.TreeItem; +import com.jpexs.asdec.abc.avm2.treemodel.operations.PreDecrementTreeItem; +import com.jpexs.asdec.abc.avm2.treemodel.operations.PreIncrementTreeItem; import com.jpexs.asdec.abc.types.MethodInfo; import java.util.HashMap; import java.util.List; @@ -42,6 +50,65 @@ public class SetPropertyIns extends InstructionDefinition implements SetTypeIns TreeItem value = (TreeItem) stack.pop(); FullMultinameTreeItem multiname = resolveMultiname(stack, constants, multinameIndex, ins); TreeItem obj = (TreeItem) stack.pop(); + if (value.getThroughRegister() instanceof IncrementTreeItem) { + TreeItem inside = ((IncrementTreeItem) value.getThroughRegister()).object.getThroughRegister().getNotCoerced(); + if (inside instanceof GetPropertyTreeItem) { + GetPropertyTreeItem insideProp = ((GetPropertyTreeItem) inside); + if (insideProp.propertyName.compareSame(multiname)) { + TreeItem insideObj = obj; + if (insideObj instanceof LocalRegTreeItem) { + insideObj = ((LocalRegTreeItem) insideObj).computedValue; + } + if (insideProp.object == insideObj) { + if (stack.size() > 0) { + TreeItem top = stack.peek().getNotCoerced(); + if (top == insideProp) { + stack.pop(); + stack.push(new PostIncrementTreeItem(ins, insideProp)); + } else if ((top instanceof IncrementTreeItem) && (((IncrementTreeItem) top).object == inside)) { + stack.pop(); + stack.push(new PreIncrementTreeItem(ins, insideProp)); + } else { + output.add(new PostIncrementTreeItem(ins, insideProp)); + } + } else { + output.add(new PostIncrementTreeItem(ins, insideProp)); + } + return; + } + } + } + } + + if (value.getThroughRegister() instanceof DecrementTreeItem) { + TreeItem inside = ((DecrementTreeItem) value.getThroughRegister()).object.getThroughRegister().getNotCoerced(); + if (inside instanceof GetPropertyTreeItem) { + GetPropertyTreeItem insideProp = ((GetPropertyTreeItem) inside); + if (insideProp.propertyName.compareSame(multiname)) { + TreeItem insideObj = obj; + if (insideObj instanceof LocalRegTreeItem) { + insideObj = ((LocalRegTreeItem) insideObj).computedValue; + } + if (insideProp.object == insideObj) { + if (stack.size() > 0) { + TreeItem top = stack.peek().getNotCoerced(); + if (top == insideProp) { + stack.pop(); + stack.push(new PostDecrementTreeItem(ins, insideProp)); + } else if ((top instanceof DecrementTreeItem) && (((DecrementTreeItem) top).object == inside)) { + stack.pop(); + stack.push(new PreDecrementTreeItem(ins, insideProp)); + } else { + output.add(new PostDecrementTreeItem(ins, insideProp)); + } + } else { + output.add(new PostDecrementTreeItem(ins, insideProp)); + } + return; + } + } + } + } output.add(new SetPropertyTreeItem(ins, obj, multiname, value)); } diff --git a/trunk/src/com/jpexs/asdec/abc/avm2/instructions/other/SetSlotIns.java b/trunk/src/com/jpexs/asdec/abc/avm2/instructions/other/SetSlotIns.java index 6a71fcfcc..92b010a27 100644 --- a/trunk/src/com/jpexs/asdec/abc/avm2/instructions/other/SetSlotIns.java +++ b/trunk/src/com/jpexs/asdec/abc/avm2/instructions/other/SetSlotIns.java @@ -22,10 +22,18 @@ import com.jpexs.asdec.abc.avm2.ConstantPool; import com.jpexs.asdec.abc.avm2.instructions.AVM2Instruction; import com.jpexs.asdec.abc.avm2.instructions.InstructionDefinition; import com.jpexs.asdec.abc.avm2.instructions.SetTypeIns; +import com.jpexs.asdec.abc.avm2.treemodel.DecrementTreeItem; +import com.jpexs.asdec.abc.avm2.treemodel.GetSlotTreeItem; +import com.jpexs.asdec.abc.avm2.treemodel.IncrementTreeItem; +import com.jpexs.asdec.abc.avm2.treemodel.LocalRegTreeItem; import com.jpexs.asdec.abc.avm2.treemodel.NewActivationTreeItem; +import com.jpexs.asdec.abc.avm2.treemodel.PostDecrementTreeItem; +import com.jpexs.asdec.abc.avm2.treemodel.PostIncrementTreeItem; import com.jpexs.asdec.abc.avm2.treemodel.SetSlotTreeItem; import com.jpexs.asdec.abc.avm2.treemodel.TreeItem; import com.jpexs.asdec.abc.avm2.treemodel.clauses.ExceptionTreeItem; +import com.jpexs.asdec.abc.avm2.treemodel.operations.PreDecrementTreeItem; +import com.jpexs.asdec.abc.avm2.treemodel.operations.PreIncrementTreeItem; import com.jpexs.asdec.abc.types.MethodInfo; import com.jpexs.asdec.abc.types.Multiname; import com.jpexs.asdec.abc.types.traits.TraitSlotConst; @@ -65,7 +73,59 @@ public class SetSlotIns extends InstructionDefinition implements SetTypeIns { return; } } - + + if (value.getNotCoerced() instanceof IncrementTreeItem) { + TreeItem inside = ((IncrementTreeItem) value.getNotCoerced()).object.getThroughRegister().getNotCoerced(); + if (inside instanceof GetSlotTreeItem) { + GetSlotTreeItem slotItem=(GetSlotTreeItem)inside; + if ((slotItem.scope.getThroughRegister()==obj.getThroughRegister()) + &&(slotItem.slotName==slotname)) + { + if (stack.size() > 0) { + TreeItem top = stack.peek().getNotCoerced(); + if (top == inside) { + stack.pop(); + stack.push(new PostIncrementTreeItem(ins, inside)); + } else if ((top instanceof IncrementTreeItem) && (((IncrementTreeItem) top).object == inside)) { + stack.pop(); + stack.push(new PreIncrementTreeItem(ins, inside)); + } else { + output.add(new PostIncrementTreeItem(ins, inside)); + } + } else { + output.add(new PostIncrementTreeItem(ins, inside)); + } + return; + } + } + } + + if (value.getNotCoerced() instanceof DecrementTreeItem) { + TreeItem inside = ((DecrementTreeItem) value.getNotCoerced()).object.getThroughRegister().getNotCoerced(); + if (inside instanceof GetSlotTreeItem) { + GetSlotTreeItem slotItem=(GetSlotTreeItem)inside; + if ((slotItem.scope.getThroughRegister()==obj.getThroughRegister()) + &&(slotItem.slotName==slotname)) + { + if (stack.size() > 0) { + TreeItem top = stack.peek().getNotCoerced(); + if (top == inside) { + stack.pop(); + stack.push(new PostDecrementTreeItem(ins, inside)); + } else if ((top instanceof DecrementTreeItem) && (((DecrementTreeItem) top).object == inside)) { + stack.pop(); + stack.push(new PreDecrementTreeItem(ins, inside)); + } else { + output.add(new PostDecrementTreeItem(ins, inside)); + } + } else { + output.add(new PostDecrementTreeItem(ins, inside)); + } + return; + } + } + } + output.add(new SetSlotTreeItem(ins, obj, slotname, value)); } diff --git a/trunk/src/com/jpexs/asdec/abc/avm2/instructions/stack/DupIns.java b/trunk/src/com/jpexs/asdec/abc/avm2/instructions/stack/DupIns.java index 4554e472d..098b14406 100644 --- a/trunk/src/com/jpexs/asdec/abc/avm2/instructions/stack/DupIns.java +++ b/trunk/src/com/jpexs/asdec/abc/avm2/instructions/stack/DupIns.java @@ -43,7 +43,7 @@ public class DupIns 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) { TreeItem v = (TreeItem) stack.pop(); - stack.push(v); + stack.push(v); stack.push(v); } diff --git a/trunk/src/com/jpexs/asdec/abc/avm2/treemodel/ConvertTreeItem.java b/trunk/src/com/jpexs/asdec/abc/avm2/treemodel/ConvertTreeItem.java index 23efa4fd9..a49f7e62c 100644 --- a/trunk/src/com/jpexs/asdec/abc/avm2/treemodel/ConvertTreeItem.java +++ b/trunk/src/com/jpexs/asdec/abc/avm2/treemodel/ConvertTreeItem.java @@ -36,4 +36,9 @@ public class ConvertTreeItem extends TreeItem { //return hilight("("+type+")")+ return value.toString(constants, localRegNames); } + + @Override + public TreeItem getNotCoerced() { + return value; + } } diff --git a/trunk/src/com/jpexs/asdec/abc/avm2/treemodel/FullMultinameTreeItem.java b/trunk/src/com/jpexs/asdec/abc/avm2/treemodel/FullMultinameTreeItem.java index 8de4ed25b..a6e84a720 100644 --- a/trunk/src/com/jpexs/asdec/abc/avm2/treemodel/FullMultinameTreeItem.java +++ b/trunk/src/com/jpexs/asdec/abc/avm2/treemodel/FullMultinameTreeItem.java @@ -24,8 +24,8 @@ public class FullMultinameTreeItem extends TreeItem { public int multinameIndex; public TreeItem name; - public TreeItem namespace; - + public TreeItem namespace; + public FullMultinameTreeItem(AVM2Instruction instruction, int multinameIndex, TreeItem name) { super(instruction, PRECEDENCE_PRIMARY); this.multinameIndex = multinameIndex; @@ -69,4 +69,37 @@ public class FullMultinameTreeItem extends TreeItem { } return ret; } + + public boolean compareSame(FullMultinameTreeItem other) + { + if(multinameIndex!=other.multinameIndex){ + return false; + } + TreeItem tiName=name; + while(tiName instanceof LocalRegTreeItem){ + tiName=((LocalRegTreeItem)tiName).computedValue; + } + + TreeItem tiName2=other.name; + while(tiName2 instanceof LocalRegTreeItem){ + tiName2=((LocalRegTreeItem)tiName2).computedValue; + } + if(tiName!=tiName2){ + return false; + } + + TreeItem tiNameSpace=namespace; + while(tiNameSpace instanceof LocalRegTreeItem){ + tiNameSpace=((LocalRegTreeItem)tiNameSpace).computedValue; + } + + TreeItem tiNameSpace2=other.namespace; + while(tiNameSpace2 instanceof LocalRegTreeItem){ + tiNameSpace2=((LocalRegTreeItem)tiNameSpace2).computedValue; + } + if(tiNameSpace!=tiNameSpace2){ + return false; + } + return true; + } } 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 f82309d8e..731272796 100644 --- a/trunk/src/com/jpexs/asdec/abc/avm2/treemodel/LocalRegTreeItem.java +++ b/trunk/src/com/jpexs/asdec/abc/avm2/treemodel/LocalRegTreeItem.java @@ -48,4 +48,11 @@ public class LocalRegTreeItem extends TreeItem { public boolean isTrue() { return computedValue.isTrue(); } + + @Override + public TreeItem getThroughRegister() { + return computedValue.getThroughRegister(); + } + + } diff --git a/trunk/src/com/jpexs/asdec/abc/avm2/treemodel/TreeItem.java b/trunk/src/com/jpexs/asdec/abc/avm2/treemodel/TreeItem.java index 498136ac6..e307fecda 100644 --- a/trunk/src/com/jpexs/asdec/abc/avm2/treemodel/TreeItem.java +++ b/trunk/src/com/jpexs/asdec/abc/avm2/treemodel/TreeItem.java @@ -42,13 +42,17 @@ public abstract class TreeItem { public static final int NOPRECEDENCE = 16; public int precedence = NOPRECEDENCE; public AVM2Instruction instruction; - + public TreeItem(AVM2Instruction instruction, int precedence) { this.instruction = instruction; this.precedence = precedence; } public abstract String toString(ConstantPool constants, HashMap localRegNames); + + public String toStringNoH(ConstantPool constants, HashMap localRegNames){ + return Highlighting.stripHilights(toString(constants,localRegNames)); + } public String toStringSemicoloned(ConstantPool constants, HashMap localRegNames) { return toString(constants, localRegNames) + (needsSemicolon() ? ";" : ""); @@ -104,6 +108,10 @@ public abstract class TreeItem { public TreeItem getNotCoerced() { return this; } + + public TreeItem getThroughRegister() { + return this; + } public static String localRegName(HashMap localRegNames, int reg) { if (localRegNames.containsKey(reg)) {