diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2GraphTargetDialect.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2GraphTargetDialect.java index ecbbc1dca..a04e0bb95 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2GraphTargetDialect.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2GraphTargetDialect.java @@ -28,9 +28,11 @@ import com.jpexs.decompiler.flash.ecma.ArrayType; import com.jpexs.decompiler.flash.ecma.Null; import com.jpexs.decompiler.flash.ecma.ObjectType; import com.jpexs.decompiler.flash.ecma.Undefined; +import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.graph.GraphTargetDialect; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.model.FalseItem; +import com.jpexs.decompiler.graph.model.LocalData; import com.jpexs.decompiler.graph.model.TrueItem; import java.util.ArrayList; import java.util.List; @@ -107,4 +109,16 @@ public class AVM2GraphTargetDialect extends GraphTargetDialect { public boolean doesAllowMultilevelBreaks() { return true; } + + @Override + public GraphTextWriter writeTemporaryDeclaration(GraphTextWriter writer, LocalData localData, String suffix, int tempIndex, GraphTargetItem value) throws InterruptedException { + writer.append("var "); + writer.append("_temp"); + writer.append("_").append(tempIndex).append(":*"); + if (value != null) { + writer.append(" = "); + value.appendTry(writer, localData); + } + return writer; + } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/InstructionDefinition.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/InstructionDefinition.java index c99a5786c..418f0573f 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/InstructionDefinition.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/InstructionDefinition.java @@ -835,6 +835,8 @@ public abstract class InstructionDefinition implements Serializable { Reference callType = new Reference<>(null); GetPropertyIns.resolvePropertyType(localData, obj, multiname, isStatic, type, callType); + obj = obj.getThroughDuplicate(); + SetTypeAVM2Item result; if (init) { result = new InitPropertyAVM2Item(ins, localData.lineStartInstruction, obj, multiname, value, type.getVal(), callType.getVal(), isStatic.getVal()); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/executing/CallIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/executing/CallIns.java index 0a27db39e..479b7a73b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/executing/CallIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/executing/CallIns.java @@ -31,6 +31,7 @@ import com.jpexs.decompiler.flash.ecma.NotCompileTime; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; import com.jpexs.decompiler.graph.model.DuplicateItem; +import com.jpexs.decompiler.graph.model.DuplicateSourceItem; import java.util.ArrayList; import java.util.List; @@ -90,6 +91,9 @@ public class CallIns extends InstructionDefinition { if (getProperty.object.value == receiver.getThroughDuplicate()) { getProperty.object = receiver.getThroughDuplicate(); } + if (receiver instanceof DuplicateSourceItem) { + receiver = receiver.getThroughDuplicate(); + } } else if (getProperty.object instanceof SetLocalAVM2Item) { SetLocalAVM2Item setLocal = (SetLocalAVM2Item) getProperty.object; if (receiver instanceof LocalRegAVM2Item) { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetPropertyIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetPropertyIns.java index 50cd07c30..449b40cdc 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetPropertyIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetPropertyIns.java @@ -46,6 +46,7 @@ import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; import com.jpexs.decompiler.graph.TypeItem; import com.jpexs.decompiler.graph.model.DuplicateItem; +import com.jpexs.decompiler.graph.model.DuplicateSourceItem; import com.jpexs.helpers.Reference; import java.util.ArrayList; import java.util.List; @@ -113,9 +114,10 @@ public class GetPropertyIns extends InstructionDefinition { } } } - if (findPropName.name instanceof DuplicateItem) { + if (findPropName.name instanceof DuplicateItem || findPropName.name instanceof DuplicateSourceItem) { if (findPropName.name.getThroughDuplicate() == multiname.name.getThroughDuplicate()) { findPropName.name = findPropName.name.value; + multiname.name = multiname.name.getThroughDuplicate(); } } if (findPropName.namespace instanceof SetLocalAVM2Item) { @@ -130,9 +132,10 @@ public class GetPropertyIns extends InstructionDefinition { } } } - if (findPropName.namespace instanceof DuplicateItem) { + if (findPropName.namespace instanceof DuplicateItem || findPropName.namespace instanceof DuplicateSourceItem) { if (findPropName.namespace.getThroughDuplicate() == multiname.namespace.getThroughDuplicate()) { - findPropName.namespace = findPropName.namespace.value; + findPropName.namespace = findPropName.namespace.getThroughDuplicate(); + multiname.namespace = multiname.namespace.getThroughDuplicate(); } } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ActionGraphTargetDialect.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ActionGraphTargetDialect.java index f7a455ac1..20cff2051 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ActionGraphTargetDialect.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ActionGraphTargetDialect.java @@ -23,9 +23,11 @@ import com.jpexs.decompiler.flash.ecma.ArrayType; import com.jpexs.decompiler.flash.ecma.Null; import com.jpexs.decompiler.flash.ecma.ObjectType; import com.jpexs.decompiler.flash.ecma.Undefined; +import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.graph.GraphTargetDialect; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.model.FalseItem; +import com.jpexs.decompiler.graph.model.LocalData; import com.jpexs.decompiler.graph.model.TrueItem; import java.util.ArrayList; import java.util.List; @@ -112,4 +114,16 @@ public class ActionGraphTargetDialect extends GraphTargetDialect { public boolean doesAllowMultilevelBreaks() { return false; } + + @Override + public GraphTextWriter writeTemporaryDeclaration(GraphTextWriter writer, LocalData localData, String suffix, int tempIndex, GraphTargetItem value) throws InterruptedException { + writer.append("var "); + writer.append("_temp"); + writer.append("_").append(tempIndex); + if (value != null) { + writer.append(" = "); + value.appendTry(writer, localData); + } + return writer; + } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/Graph.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/Graph.java index 76c9ab4ca..78136e029 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/Graph.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/Graph.java @@ -31,6 +31,7 @@ import com.jpexs.decompiler.graph.model.ContinueItem; import com.jpexs.decompiler.graph.model.DefaultItem; import com.jpexs.decompiler.graph.model.DoWhileItem; import com.jpexs.decompiler.graph.model.DuplicateItem; +import com.jpexs.decompiler.graph.model.DuplicateSourceItem; import com.jpexs.decompiler.graph.model.ExitItem; import com.jpexs.decompiler.graph.model.FalseItem; import com.jpexs.decompiler.graph.model.ForItem; @@ -47,6 +48,7 @@ import com.jpexs.decompiler.graph.model.OrItem; import com.jpexs.decompiler.graph.model.PopItem; import com.jpexs.decompiler.graph.model.PushItem; import com.jpexs.decompiler.graph.model.ScriptEndItem; +import com.jpexs.decompiler.graph.model.SetTemporaryItem; import com.jpexs.decompiler.graph.model.SwitchItem; import com.jpexs.decompiler.graph.model.TernarOpItem; import com.jpexs.decompiler.graph.model.TrueItem; @@ -1034,7 +1036,49 @@ public class Graph { makeAllCommands(ret, stack); finalProcessAll(null, ret, 0, getFinalData(localData, loops, throwStates), path); //fixSwitchEnds(ret); + handleSetTemporaryDeclarations(ret); return ret; + } + private void handleSetTemporaryDeclarations(List items) { + for (int i = 0; i < items.size(); i++) { + GraphTargetItem item = items.get(i); + if (item instanceof SetTemporaryItem) { + SetTemporaryItem s = (SetTemporaryItem) item; + s.declaration = true; + } + if (item instanceof DuplicateSourceItem) { + DuplicateSourceItem s = (DuplicateSourceItem) item; + s.declaration = true; + } + + Reference iRef = new Reference<>(i); + item.visitRecursivelyNoBlock(new AbstractGraphTargetRecursiveVisitor() { + @Override + public void visit(GraphTargetItem item, Stack parentStack) { + if (item instanceof SetTemporaryItem) { + SetTemporaryItem st = (SetTemporaryItem) item; + SetTemporaryItem dec = new SetTemporaryItem(dialect, null, null, null, st.tempIndex, st.getSuffix()); + dec.declaration = true; + items.add(iRef.getVal(), dec); + iRef.setVal(iRef.getVal() + 1); + } + if (item instanceof DuplicateSourceItem) { + DuplicateSourceItem st = (DuplicateSourceItem) item; + SetTemporaryItem dec = new SetTemporaryItem(dialect, null, null, null, st.tempIndex, ""); + dec.declaration = true; + items.add(iRef.getVal(), dec); + iRef.setVal(iRef.getVal() + 1); + } + } + }); + i = iRef.getVal(); + if (item instanceof Block) { + Block blk = (Block) item; + for (List sub : blk.getSubs()) { + handleSetTemporaryDeclarations(sub); + } + } + } } /* diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/GraphTargetDialect.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/GraphTargetDialect.java index 3d0db2942..f99439b9d 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/GraphTargetDialect.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/GraphTargetDialect.java @@ -16,6 +16,9 @@ */ package com.jpexs.decompiler.graph; +import com.jpexs.decompiler.flash.helpers.GraphTextWriter; +import com.jpexs.decompiler.graph.model.LocalData; + /** * Dialect - high level language type. * @@ -45,4 +48,15 @@ public abstract class GraphTargetDialect { * @return True when allows */ public abstract boolean doesAllowMultilevelBreaks(); + + /** + * Prints temporary declaration + * @param writer Writer + * @param localData Local data + * @param suffix Suffix + * @param tempIndex Temporary index + * @param value Value + * @return Writer + */ + public abstract GraphTextWriter writeTemporaryDeclaration(GraphTextWriter writer, LocalData localData, String suffix, int tempIndex, GraphTargetItem value) throws InterruptedException; } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/model/DuplicateItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/model/DuplicateItem.java index 92441dde2..15bb51327 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/model/DuplicateItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/model/DuplicateItem.java @@ -17,7 +17,6 @@ package com.jpexs.decompiler.graph.model; import com.jpexs.decompiler.flash.SourceGeneratorLocalData; -import com.jpexs.decompiler.flash.configuration.Configuration; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.graph.CompilationException; import com.jpexs.decompiler.graph.GraphSourceItem; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/model/DuplicateSourceItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/model/DuplicateSourceItem.java index b511f12a1..6e8f52ae4 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/model/DuplicateSourceItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/model/DuplicateSourceItem.java @@ -17,7 +17,6 @@ package com.jpexs.decompiler.graph.model; import com.jpexs.decompiler.flash.SourceGeneratorLocalData; -import com.jpexs.decompiler.flash.configuration.Configuration; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.graph.CompilationException; import com.jpexs.decompiler.graph.GraphSourceItem; @@ -37,7 +36,9 @@ import java.util.Set; public class DuplicateSourceItem extends GraphTargetItem implements SimpleValue, HasTempIndex { public int tempIndex; - + public boolean declaration = false; + + /** * Constructor. * @@ -75,7 +76,10 @@ public class DuplicateSourceItem extends GraphTargetItem implements SimpleValue, while ((val instanceof HasTempIndex) && ((HasTempIndex) val).getTempIndex() == tempIndex) { val = val.value; } - writer.append("_tempdup_").append(tempIndex).append(" = "); + if (declaration) { + return dialect.writeTemporaryDeclaration(writer, localData, "", tempIndex, val); + } + writer.append("_temp_").append(tempIndex).append(" = "); val.appendTry(writer, localData); return writer; } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/model/SetTemporaryItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/model/SetTemporaryItem.java index 2c12a88c4..5537fa79b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/model/SetTemporaryItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/model/SetTemporaryItem.java @@ -38,6 +38,8 @@ public class SetTemporaryItem extends GraphTargetItem implements SimpleValue, Ha private static final boolean SHOW_SUFFIX = false; public int tempIndex; + public boolean declaration = false; + private final String suffix; public String getSuffix() { @@ -53,7 +55,7 @@ public class SetTemporaryItem extends GraphTargetItem implements SimpleValue, Ha * @param value Value */ public SetTemporaryItem(GraphTargetDialect dialect, GraphSourceItem src, GraphSourceItem lineStartIns, GraphTargetItem value, int tempIndex, String suffix) { - super(dialect, src, lineStartIns, value.getPrecedence(), value); + super(dialect, src, lineStartIns, PRECEDENCE_ASSIGNMENT, value); this.tempIndex = tempIndex; this.suffix = suffix; } @@ -74,13 +76,15 @@ public class SetTemporaryItem extends GraphTargetItem implements SimpleValue, Ha while ((val instanceof HasTempIndex) && ((HasTempIndex) val).getTempIndex() == tempIndex) { val = val.value; } - writer.append("_temp"); + if (declaration) { + return dialect.writeTemporaryDeclaration(writer, localData, SHOW_SUFFIX ? suffix : "", tempIndex, val); + } + writer.append("_temp"); if (SHOW_SUFFIX) { writer.append(suffix); } writer.append("_").append(tempIndex).append(" = "); - val.appendTry(writer, localData); - return writer; + return value.appendTry(writer, localData); } @Override