diff --git a/trunk/src/com/jpexs/asdec/abc/avm2/AVM2Code.java b/trunk/src/com/jpexs/asdec/abc/avm2/AVM2Code.java index e1894468b..2c1387f43 100644 --- a/trunk/src/com/jpexs/asdec/abc/avm2/AVM2Code.java +++ b/trunk/src/com/jpexs/asdec/abc/avm2/AVM2Code.java @@ -46,6 +46,7 @@ import com.jpexs.asdec.abc.avm2.treemodel.operations.PreIncrementTreeItem; import com.jpexs.asdec.abc.types.ABCException; import com.jpexs.asdec.abc.types.MethodBody; import com.jpexs.asdec.abc.types.MethodInfo; +import com.jpexs.asdec.abc.types.Multiname; import com.jpexs.asdec.abc.types.traits.TraitSlotConst; import com.jpexs.asdec.helpers.Helper; import com.jpexs.asdec.helpers.Highlighting; @@ -58,6 +59,7 @@ import java.util.regex.Pattern; public class AVM2Code { + private static final boolean DEBUG_MODE=false; public static int toSourceLimit = -1; public ArrayList code = new ArrayList(); public static boolean DEBUG_REWRITE = false; @@ -1599,7 +1601,10 @@ public class AVM2Code { if (ex instanceof UnknownJumpException) { throw (UnknownJumpException) ex; } - ex.printStackTrace(); + if(DEBUG_MODE) + { + ex.printStackTrace(); + } throw new ConvertException(ex.getClass().getSimpleName(), ip); } } @@ -1663,6 +1668,33 @@ public class AVM2Code { return ret; } + private class Slot{ + public TreeItem scope; + public Multiname multiname; + + public Slot(TreeItem scope, Multiname multiname) { + this.scope = scope; + this.multiname = multiname; + } + + @Override + public boolean equals(Object obj) { + if(obj instanceof Slot){ + return (((Slot)obj).scope.getThroughRegister()==scope.getThroughRegister()) + &&(((Slot)obj).multiname==multiname); + } + return false; + } + + @Override + public int hashCode() { + int hash = 7; + hash = 59 * hash + (this.scope != null ? this.scope.hashCode() : 0); + hash = 59 * hash + (this.multiname != null ? this.multiname.hashCode() : 0); + return hash; + } + } + public String toSource(boolean isStatic, int classIndex, ABC abc, ConstantPool constants, MethodInfo method_info[], MethodBody body, boolean hilighted, HashMap localRegNames) { toSourceCount = 0; loopList = new ArrayList(); @@ -1673,30 +1705,8 @@ public class AVM2Code { List list; String s = ""; HashMap localRegs = new HashMap(); - try { - 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; - } - - - String parts[] = s.split("\r\n"); - String sub = ""; - int level = 0; - for (int t = 0; t < body.traits.traits.length; t++) { - //Skip traits with same name as local registers - if ((body.traits.traits[t] instanceof TraitSlotConst) - && (((TraitSlotConst) body.traits.traits[t]).isVar()) - && (localRegNames.containsValue(((TraitSlotConst) body.traits.traits[t]).getName(constants)))) { - continue; - } else { - sub += body.traits.traits[t].convert(constants, method_info, abc) + ";\r\n"; - } - } - int regCount = getRegisterCount(); + + int regCount = getRegisterCount(); int paramCount = 0; if (body.method_info != -1) { MethodInfo mi = method_info[body.method_info]; @@ -1705,16 +1715,56 @@ public class AVM2Code { paramCount++; } } - HashMap localRegTypes = getLocalRegTypes(constants); - for (int i = paramCount + 1; i < regCount; i++) { - 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); - } - sub += ";\r\n"; + + try { + list = toSource(isStatic, classIndex, localRegs, new Stack(), new Stack(), abc, constants, method_info, body, 0, code.size() - 1, localRegNames).output; + + //Declarations + boolean declaredRegisters[]=new boolean[regCount]; + for(int b=0;b declaredSlots=new ArrayList(); + for(int i=0;i loopStack = new Stack(); for (int p = 0; p < parts.length; p++) { diff --git a/trunk/src/com/jpexs/asdec/abc/avm2/instructions/types/CoerceAIns.java b/trunk/src/com/jpexs/asdec/abc/avm2/instructions/types/CoerceAIns.java index 17ddd7102..45b53fe06 100644 --- a/trunk/src/com/jpexs/asdec/abc/avm2/instructions/types/CoerceAIns.java +++ b/trunk/src/com/jpexs/asdec/abc/avm2/instructions/types/CoerceAIns.java @@ -45,7 +45,7 @@ public class CoerceAIns extends InstructionDefinition implements CoerceOrConvert @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) { - stack.push(new CoerceTreeItem(ins, (TreeItem) stack.pop(), "*")); + stack.push(new CoerceTreeItem(ins, (TreeItem) stack.pop(), getTargetType(constants, ins))); } diff --git a/trunk/src/com/jpexs/asdec/abc/avm2/instructions/types/CoerceSIns.java b/trunk/src/com/jpexs/asdec/abc/avm2/instructions/types/CoerceSIns.java index 5ca8eb0e6..ab6efbdad 100644 --- a/trunk/src/com/jpexs/asdec/abc/avm2/instructions/types/CoerceSIns.java +++ b/trunk/src/com/jpexs/asdec/abc/avm2/instructions/types/CoerceSIns.java @@ -42,7 +42,7 @@ public class CoerceSIns extends InstructionDefinition implements CoerceOrConvert @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) { - stack.push(new CoerceTreeItem(ins, (TreeItem) stack.pop(), "string")); + stack.push(new CoerceTreeItem(ins, (TreeItem) stack.pop(), getTargetType(constants, ins))); } @Override diff --git a/trunk/src/com/jpexs/asdec/abc/avm2/instructions/types/ConvertBIns.java b/trunk/src/com/jpexs/asdec/abc/avm2/instructions/types/ConvertBIns.java index 0c3916113..fcdbce42c 100644 --- a/trunk/src/com/jpexs/asdec/abc/avm2/instructions/types/ConvertBIns.java +++ b/trunk/src/com/jpexs/asdec/abc/avm2/instructions/types/ConvertBIns.java @@ -52,7 +52,7 @@ public class ConvertBIns extends InstructionDefinition implements CoerceOrConver @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) { - stack.push(new ConvertTreeItem(ins, (TreeItem) stack.pop(), "boolean")); + stack.push(new ConvertTreeItem(ins, (TreeItem) stack.pop(), getTargetType(constants, ins))); } @Override diff --git a/trunk/src/com/jpexs/asdec/abc/avm2/instructions/types/ConvertDIns.java b/trunk/src/com/jpexs/asdec/abc/avm2/instructions/types/ConvertDIns.java index d2388c427..39d68aaf3 100644 --- a/trunk/src/com/jpexs/asdec/abc/avm2/instructions/types/ConvertDIns.java +++ b/trunk/src/com/jpexs/asdec/abc/avm2/instructions/types/ConvertDIns.java @@ -60,7 +60,7 @@ public class ConvertDIns extends InstructionDefinition implements CoerceOrConver @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) { - stack.push(new ConvertTreeItem(ins, (TreeItem) stack.pop(), "double")); + stack.push(new ConvertTreeItem(ins, (TreeItem) stack.pop(), getTargetType(constants, ins))); } @Override diff --git a/trunk/src/com/jpexs/asdec/abc/avm2/instructions/types/ConvertIIns.java b/trunk/src/com/jpexs/asdec/abc/avm2/instructions/types/ConvertIIns.java index 907490a0a..7807cd334 100644 --- a/trunk/src/com/jpexs/asdec/abc/avm2/instructions/types/ConvertIIns.java +++ b/trunk/src/com/jpexs/asdec/abc/avm2/instructions/types/ConvertIIns.java @@ -58,7 +58,7 @@ public class ConvertIIns extends InstructionDefinition implements CoerceOrConver @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) { - stack.push(new ConvertTreeItem(ins, (TreeItem) stack.pop(), "int")); + stack.push(new ConvertTreeItem(ins, (TreeItem) stack.pop(), getTargetType(constants, ins))); } @Override diff --git a/trunk/src/com/jpexs/asdec/abc/avm2/instructions/types/ConvertOIns.java b/trunk/src/com/jpexs/asdec/abc/avm2/instructions/types/ConvertOIns.java index 23538207e..2500c8ee0 100644 --- a/trunk/src/com/jpexs/asdec/abc/avm2/instructions/types/ConvertOIns.java +++ b/trunk/src/com/jpexs/asdec/abc/avm2/instructions/types/ConvertOIns.java @@ -41,7 +41,7 @@ public class ConvertOIns extends InstructionDefinition implements CoerceOrConver @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) { - stack.push(new ConvertTreeItem(ins, (TreeItem) stack.pop(), "Object")); + stack.push(new ConvertTreeItem(ins, (TreeItem) stack.pop(), getTargetType(constants, ins))); } @Override diff --git a/trunk/src/com/jpexs/asdec/abc/avm2/instructions/types/ConvertSIns.java b/trunk/src/com/jpexs/asdec/abc/avm2/instructions/types/ConvertSIns.java index 3f1e936ff..9e41894bb 100644 --- a/trunk/src/com/jpexs/asdec/abc/avm2/instructions/types/ConvertSIns.java +++ b/trunk/src/com/jpexs/asdec/abc/avm2/instructions/types/ConvertSIns.java @@ -42,7 +42,7 @@ public class ConvertSIns extends InstructionDefinition implements CoerceOrConver @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) { - stack.push(new ConvertTreeItem(ins, (TreeItem) stack.pop(), "string")); + stack.push(new ConvertTreeItem(ins, (TreeItem) stack.pop(), getTargetType(constants, ins))); } @Override diff --git a/trunk/src/com/jpexs/asdec/abc/avm2/instructions/types/ConvertUIns.java b/trunk/src/com/jpexs/asdec/abc/avm2/instructions/types/ConvertUIns.java index 32c35ce2a..492e4129f 100644 --- a/trunk/src/com/jpexs/asdec/abc/avm2/instructions/types/ConvertUIns.java +++ b/trunk/src/com/jpexs/asdec/abc/avm2/instructions/types/ConvertUIns.java @@ -41,7 +41,7 @@ public class ConvertUIns extends InstructionDefinition implements CoerceOrConver @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) { - stack.push(new ConvertTreeItem(ins, (TreeItem) stack.pop(), "uint")); + stack.push(new ConvertTreeItem(ins, (TreeItem) stack.pop(), getTargetType(constants, ins))); } @Override diff --git a/trunk/src/com/jpexs/asdec/abc/avm2/treemodel/clauses/DeclarationTreeItem.java b/trunk/src/com/jpexs/asdec/abc/avm2/treemodel/clauses/DeclarationTreeItem.java new file mode 100644 index 000000000..b9bb1ce8c --- /dev/null +++ b/trunk/src/com/jpexs/asdec/abc/avm2/treemodel/clauses/DeclarationTreeItem.java @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2012 Jindra + * + * 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 2 + * 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +package com.jpexs.asdec.abc.avm2.treemodel.clauses; + +import com.jpexs.asdec.abc.avm2.ConstantPool; +import com.jpexs.asdec.abc.avm2.treemodel.CoerceTreeItem; +import com.jpexs.asdec.abc.avm2.treemodel.ConvertTreeItem; +import com.jpexs.asdec.abc.avm2.treemodel.LocalRegTreeItem; +import com.jpexs.asdec.abc.avm2.treemodel.NewActivationTreeItem; +import com.jpexs.asdec.abc.avm2.treemodel.SetLocalTreeItem; +import com.jpexs.asdec.abc.avm2.treemodel.SetSlotTreeItem; +import com.jpexs.asdec.abc.avm2.treemodel.TreeItem; +import java.util.HashMap; + +/** + * + * @author JPEXS + */ +public class DeclarationTreeItem extends TreeItem { + + public TreeItem assignment; + public String type; + public DeclarationTreeItem(TreeItem assignment,String type){ + super(assignment.instruction,assignment.precedence); + this.type=type; + this.assignment=assignment; + } + + public DeclarationTreeItem(TreeItem assignment){ + this(assignment,null); + } + + @Override + public String toString(ConstantPool constants, HashMap localRegNames) { + if(assignment instanceof SetLocalTreeItem) + { + SetLocalTreeItem lti=(SetLocalTreeItem)assignment; + String type="*"; + if(lti.value instanceof CoerceTreeItem){ + type = ((CoerceTreeItem)lti.value).type; + } + if(lti.value instanceof ConvertTreeItem){ + type = ((ConvertTreeItem)lti.value).type; + } + return "var "+hilight(localRegName(localRegNames, lti.regIndex) + ":"+type+" = ") + lti.value.toString(constants, localRegNames); + } + if(assignment instanceof SetSlotTreeItem) + { + SetSlotTreeItem ssti=(SetSlotTreeItem)assignment; + String ret=""; + if (!(ssti.scope instanceof NewActivationTreeItem)) { + ret = ssti.scope.toString(constants, localRegNames) + "."; + } + if (ssti.scope instanceof LocalRegTreeItem) { + if (((LocalRegTreeItem) ssti.scope).computedValue != null) { + if (((LocalRegTreeItem) ssti.scope).computedValue instanceof NewActivationTreeItem) { + ret = ""; + } + } + } + return "var "+ret + hilight(ssti.slotName.getName(constants)) + ":"+type+hilight(" = ") + ssti.value.toString(constants, localRegNames); + } + return "var "+assignment.toString(constants, localRegNames); + } + +} diff --git a/trunk/src/com/jpexs/asdec/abc/types/traits/TraitSlotConst.java b/trunk/src/com/jpexs/asdec/abc/types/traits/TraitSlotConst.java index 7e5f74176..1b9fefdd3 100644 --- a/trunk/src/com/jpexs/asdec/abc/types/traits/TraitSlotConst.java +++ b/trunk/src/com/jpexs/asdec/abc/types/traits/TraitSlotConst.java @@ -42,11 +42,17 @@ public class TraitSlotConst extends Trait { return "0x" + Helper.formatAddress(fileOffset) + " " + Helper.byteArrToString(bytes) + " SlotConst " + abc.constants.constant_multiname[name_index].toString(abc.constants) + " slot=" + slot_id + " type=" + typeStr + " value=" + (new ValueKind(value_index, value_kind)).toString(abc.constants) + " metadata=" + Helper.intArrToString(metadata); } - public String getNameValueStr(ConstantPool constants) { + public String getType(ConstantPool constants){ String typeStr = "*"; if (type_index > 0) { typeStr = constants.constant_multiname[type_index].getName(constants); } + return typeStr; + } + + public String getNameValueStr(ConstantPool constants) { + + String typeStr = getType(constants); String valueStr = ""; if (value_kind != 0) { valueStr = " = " + (new ValueKind(value_index, value_kind)).toString(constants);