From d7071c940f6187237a90037bd9dd62e32dc849f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Sun, 30 Nov 2025 12:35:54 +0100 Subject: [PATCH] Fixed: #2573 AS3 - Incorrect uint/int/Number coercion Fixed: AS3 local registers type propagation --- CHANGELOG.md | 3 + .../decompiler/flash/abc/avm2/AVM2Code.java | 56 ++++++++++--- .../avm2/graph/AVM2GraphTargetDialect.java | 13 +++ .../instructions/InstructionDefinition.java | 81 +++++++++++-------- .../instructions/localregs/DecLocalIIns.java | 5 +- .../instructions/localregs/DecLocalIns.java | 5 +- .../localregs/GetLocalTypeIns.java | 12 +-- .../instructions/localregs/IncLocalIIns.java | 5 +- .../instructions/localregs/IncLocalIns.java | 5 +- .../localregs/SetLocalTypeIns.java | 16 ++-- .../avm2/instructions/other/SetSlotIns.java | 16 ++-- .../other/decimalsupport/DecLocalPIns.java | 5 +- .../other/decimalsupport/IncLocalPIns.java | 5 +- .../abc/avm2/model/DecLocalAVM2Item.java | 9 ++- .../abc/avm2/model/DecrementAVM2Item.java | 13 +-- .../abc/avm2/model/IncLocalAVM2Item.java | 9 ++- .../abc/avm2/model/IncrementAVM2Item.java | 11 --- .../abc/avm2/model/PostDecrementAVM2Item.java | 15 +++- .../abc/avm2/model/PostIncrementAVM2Item.java | 15 +++- .../model/clauses/AssignmentAVM2Item.java | 5 ++ .../avm2/model/operations/AddAVM2Item.java | 18 +---- .../model/operations/MultiplyAVM2Item.java | 12 --- .../operations/PreDecrementAVM2Item.java | 16 +++- .../operations/PreIncrementAVM2Item.java | 19 ++++- .../model/operations/SubtractAVM2Item.java | 20 ----- .../parser/script/ActionScript3Parser.java | 8 +- .../decompiler/graph/GraphTargetDialect.java | 12 ++- .../decompiler/graph/GraphTargetItem.java | 3 +- .../ActionScript3ClassicAirDecompileTest.java | 14 ++-- .../ActionScript3ClassicDecompileTest.java | 4 +- 30 files changed, 254 insertions(+), 176 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bb4c97341..7e4ec28b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ All notable changes to this project will be documented in this file. - [#2570] ClassCastException on exporting sound head (export all command) - [#2571] SVG export - StackOverflow for DefineVideoStream - [#2575] dumpSWF CLI command displayed import assets GUI dialog +- [#2573] AS3 - Incorrect uint/int/Number coercion +- AS3 local registers type propagation ### Changed - [#2575] dumpSWF CLI command only allows single SWF dump (no imports, etc.) @@ -4055,6 +4057,7 @@ Major version of SWF to XML export changed to 2. [#2570]: https://www.free-decompiler.com/flash/issues/2570 [#2571]: https://www.free-decompiler.com/flash/issues/2571 [#2575]: https://www.free-decompiler.com/flash/issues/2575 +[#2573]: https://www.free-decompiler.com/flash/issues/2573 [#2556]: https://www.free-decompiler.com/flash/issues/2556 [#2536]: https://www.free-decompiler.com/flash/issues/2536 [#2537]: https://www.free-decompiler.com/flash/issues/2537 diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java index 959614f63..8edc63995 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java @@ -261,6 +261,8 @@ import com.jpexs.decompiler.flash.abc.avm2.model.NewActivationAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.NewFunctionAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.NullAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.PackageAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.PostDecrementAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.PostIncrementAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.ReturnValueAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.ReturnVoidAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.SetLocalAVM2Item; @@ -270,10 +272,13 @@ import com.jpexs.decompiler.flash.abc.avm2.model.SetTypeAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.StoreNewActivationAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.TraitSlotConstAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.UndefinedAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.clauses.AssignmentAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.clauses.DeclarationAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.clauses.ForEachInAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.clauses.ForInAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.PreIncrementAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.parser.script.AbcIndexing; +import com.jpexs.decompiler.flash.abc.avm2.parser.script.AssignableAVM2Item; import com.jpexs.decompiler.flash.abc.types.ABCException; import com.jpexs.decompiler.flash.abc.types.AssignedValue; import com.jpexs.decompiler.flash.abc.types.ConvertData; @@ -2174,18 +2179,30 @@ public class AVM2Code implements Cloneable { return assignment; } GraphTargetItem vtype = TypeItem.UNBOUNDED; - if (assignment.value instanceof ConvertAVM2Item) { - vtype = ((ConvertAVM2Item) assignment.value).type; - } else if (assignment.value instanceof CoerceAVM2Item) { - vtype = ((CoerceAVM2Item) assignment.value).typeObj; - } else if (assignment instanceof LocalRegAVM2Item) { //for..in - vtype = ((LocalRegAVM2Item) assignment).type; - } else if (assignment instanceof GetSlotAVM2Item) { //for..in - vtype = ((GetSlotAVM2Item) assignment).slotType; - } else if ((assignment.value instanceof SimpleValue) && ((SimpleValue) assignment.value).isSimpleValue()) { - vtype = assignment.value.returnType(); - } else if (assignment.value instanceof GetLexAVM2Item) { - vtype = assignment.value.returnType(); + + if ( + (assignment instanceof PostIncrementAVM2Item) + || (assignment instanceof PostDecrementAVM2Item) + || (assignment instanceof PreIncrementAVM2Item) + || (assignment instanceof PreIncrementAVM2Item) + ) { + vtype = assignment.returnType(); + } else { + if (assignment.value instanceof ConvertAVM2Item) { + vtype = ((ConvertAVM2Item) assignment.value).type; + } else if (assignment.value instanceof CoerceAVM2Item) { + vtype = ((CoerceAVM2Item) assignment.value).typeObj; + } else if (assignment instanceof LocalRegAVM2Item) { //for..in + vtype = ((LocalRegAVM2Item) assignment).type; + } else if (assignment instanceof GetSlotAVM2Item) { //for..in + vtype = ((GetSlotAVM2Item) assignment).slotType; + } else if ((assignment.value instanceof SimpleValue) && ((SimpleValue) assignment.value).isSimpleValue()) { + vtype = assignment.value.returnType(); + } else if (assignment.value instanceof GetLexAVM2Item) { + vtype = assignment.value.returnType(); + } else if (assignment.value instanceof LocalRegAVM2Item) { + vtype = assignment.value.returnType(); + } } boolean isNull = false; @@ -2410,6 +2427,21 @@ public class AVM2Code implements Cloneable { } } } + if ((subItem instanceof PostIncrementAVM2Item) + || (subItem instanceof PostDecrementAVM2Item) + || (subItem instanceof PreIncrementAVM2Item) + || (subItem instanceof PreIncrementAVM2Item)) { + if (((AssignmentAVM2Item) subItem).getObject() instanceof LocalRegAVM2Item) { + int reg = ((LocalRegAVM2Item) ((AssignmentAVM2Item) subItem).getObject()).regIndex; + handleDeclareReg(minreg, subItem, declaredRegisters, declaredSlots, reg); + } + } + if (subItem instanceof LocalRegAVM2Item) { + LocalRegAVM2Item getLocal = (LocalRegAVM2Item) subItem; + if (declaredRegisters[getLocal.regIndex] != null) { + getLocal.type = declaredRegisters[getLocal.regIndex].type; + } + } if (subItem instanceof SetPropertyAVM2Item) { SetPropertyAVM2Item sp = (SetPropertyAVM2Item) subItem; if (sp.object instanceof FindPropertyAVM2Item) { 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 ad8a9645d..44923a9b6 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 @@ -16,6 +16,8 @@ */ package com.jpexs.decompiler.flash.abc.avm2.graph; +import com.jpexs.decompiler.flash.abc.avm2.model.CoerceAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.ConvertAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.DoubleValueAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.IntegerValueAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.NameValuePair; @@ -122,4 +124,15 @@ public class AVM2GraphTargetDialect extends GraphTargetDialect { } return writer; } + + @Override + public GraphTargetItem copyCoerce(GraphTargetItem coercedOriginal, GraphTargetItem newValue) { + if (coercedOriginal instanceof ConvertAVM2Item) { + return new ConvertAVM2Item(coercedOriginal.getSrc(), coercedOriginal.getLineStartItem(), newValue, ((ConvertAVM2Item) coercedOriginal).type); + } + if (coercedOriginal instanceof CoerceAVM2Item) { + return new CoerceAVM2Item(coercedOriginal.getSrc(), coercedOriginal.getLineStartItem(), newValue, ((CoerceAVM2Item) coercedOriginal).typeObj); + } + return super.copyCoerce(coercedOriginal, newValue); + } } 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 712b4068a..e6ce5e3b3 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 @@ -27,6 +27,7 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetPropertyIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.other.SetPropertyIns; import com.jpexs.decompiler.flash.abc.avm2.model.ApplyTypeAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.ClassAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.CoerceAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.ConstructAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.ConvertAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.DecrementAVM2Item; @@ -61,6 +62,7 @@ import com.jpexs.decompiler.graph.GraphSourceItem; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.ScopeStack; import com.jpexs.decompiler.graph.TranslateStack; +import com.jpexs.decompiler.graph.TypeItem; import com.jpexs.decompiler.graph.model.CommaExpressionItem; import com.jpexs.decompiler.graph.model.DuplicateItem; import com.jpexs.decompiler.graph.model.DuplicateSourceItem; @@ -697,9 +699,9 @@ public abstract class InstructionDefinition implements Serializable { output.remove(output.size() - 1); getProp.object = st.value; if (isIncrement) { - stack.addToOutput(new PreIncrementAVM2Item(value.getSrc(), value.lineStartItem, getProp)); + stack.addToOutput(new PreIncrementAVM2Item(value.getSrc(), value.lineStartItem, getProp, value.value.returnType())); } else { - stack.addToOutput(new PreDecrementAVM2Item(value.getSrc(), value.lineStartItem, getProp)); + stack.addToOutput(new PreDecrementAVM2Item(value.getSrc(), value.lineStartItem, getProp, value.value.returnType())); } return; } @@ -731,9 +733,9 @@ public abstract class InstructionDefinition implements Serializable { output.remove(output.size() - 1); getProp.object = st.value; if (isIncrement) { - stack.addToOutput(new PostIncrementAVM2Item(value.getSrc(), value.lineStartItem, getProp)); + stack.addToOutput(new PostIncrementAVM2Item(value.getSrc(), value.lineStartItem, getProp, TypeItem.NUMBER)); } else { - stack.addToOutput(new PostDecrementAVM2Item(value.getSrc(), value.lineStartItem, getProp)); + stack.addToOutput(new PostDecrementAVM2Item(value.getSrc(), value.lineStartItem, getProp, TypeItem.NUMBER)); } return; } @@ -784,9 +786,9 @@ public abstract class InstructionDefinition implements Serializable { fm.name = setLocName.value; stack.pop(); if (isIncrement) { - stack.push(new PreIncrementAVM2Item(setLocValue.value.getSrc(), setLocValue.value.getLineStartItem(), getProp)); + stack.push(new PreIncrementAVM2Item(setLocValue.value.getSrc(), setLocValue.value.getLineStartItem(), getProp, TypeItem.NUMBER)); } else { - stack.push(new PreDecrementAVM2Item(setLocValue.value.getSrc(), setLocValue.value.getLineStartItem(), getProp)); + stack.push(new PreDecrementAVM2Item(setLocValue.value.getSrc(), setLocValue.value.getLineStartItem(), getProp, TypeItem.NUMBER)); } return; } @@ -824,9 +826,9 @@ public abstract class InstructionDefinition implements Serializable { fm.name = setLocName.value; output.remove(output.size() - 1); if (isIncrement) { - stack.addToOutput(new PreIncrementAVM2Item(setLocValue.value.getSrc(), setLocValue.value.getLineStartItem(), getProp)); + stack.addToOutput(new PreIncrementAVM2Item(setLocValue.value.getSrc(), setLocValue.value.getLineStartItem(), getProp, TypeItem.NUMBER)); } else { - stack.addToOutput(new PreDecrementAVM2Item(setLocValue.value.getSrc(), setLocValue.value.getLineStartItem(), getProp)); + stack.addToOutput(new PreDecrementAVM2Item(setLocValue.value.getSrc(), setLocValue.value.getLineStartItem(), getProp, TypeItem.NUMBER)); } return; } @@ -881,9 +883,9 @@ public abstract class InstructionDefinition implements Serializable { output.remove(output.size() - 1); stack.moveToStack(output); if (isIncrement) { - stack.push(new PostIncrementAVM2Item(setLocValue.value.getSrc(), setLocValue.value.getLineStartItem(), getProp)); + stack.push(new PostIncrementAVM2Item(setLocValue.value.getSrc(), setLocValue.value.getLineStartItem(), getProp, TypeItem.NUMBER)); } else { - stack.push(new PostDecrementAVM2Item(setLocValue.value.getSrc(), setLocValue.value.getLineStartItem(), getProp)); + stack.push(new PostDecrementAVM2Item(setLocValue.value.getSrc(), setLocValue.value.getLineStartItem(), getProp, TypeItem.NUMBER)); } return; } @@ -929,9 +931,9 @@ public abstract class InstructionDefinition implements Serializable { output.remove(output.size() - 1); stack.moveToStack(output); if (isIncrement) { - stack.addToOutput(new PostIncrementAVM2Item(setLocValue.value.getSrc(), setLocValue.value.getLineStartItem(), getProp)); + stack.addToOutput(new PostIncrementAVM2Item(setLocValue.value.getSrc(), setLocValue.value.getLineStartItem(), getProp, TypeItem.NUMBER)); } else { - stack.addToOutput(new PostDecrementAVM2Item(setLocValue.value.getSrc(), setLocValue.value.getLineStartItem(), getProp)); + stack.addToOutput(new PostDecrementAVM2Item(setLocValue.value.getSrc(), setLocValue.value.getLineStartItem(), getProp, TypeItem.NUMBER)); } return; } @@ -969,9 +971,9 @@ public abstract class InstructionDefinition implements Serializable { getProp.object = setLocObj.value; stack.pop(); if (isIncrement) { - stack.push(new PreIncrementAVM2Item(setLocValue.value.getSrc(), setLocValue.value.getLineStartItem(), getProp)); + stack.push(new PreIncrementAVM2Item(setLocValue.value.getSrc(), setLocValue.value.getLineStartItem(), getProp, TypeItem.NUMBER)); } else { - stack.push(new PreDecrementAVM2Item(setLocValue.value.getSrc(), setLocValue.value.getLineStartItem(), getProp)); + stack.push(new PreDecrementAVM2Item(setLocValue.value.getSrc(), setLocValue.value.getLineStartItem(), getProp, TypeItem.NUMBER)); } return; } @@ -1006,9 +1008,9 @@ public abstract class InstructionDefinition implements Serializable { output.remove(output.size() - 1); stack.moveToStack(output); if (isIncrement) { - stack.addToOutput(new PreIncrementAVM2Item(setLocValue.value.getSrc(), setLocValue.value.getLineStartItem(), getProp)); + stack.addToOutput(new PreIncrementAVM2Item(setLocValue.value.getSrc(), setLocValue.value.getLineStartItem(), getProp, TypeItem.NUMBER)); } else { - stack.addToOutput(new PreDecrementAVM2Item(setLocValue.value.getSrc(), setLocValue.value.getLineStartItem(), getProp)); + stack.addToOutput(new PreDecrementAVM2Item(setLocValue.value.getSrc(), setLocValue.value.getLineStartItem(), getProp, TypeItem.NUMBER)); } return; } @@ -1059,9 +1061,9 @@ public abstract class InstructionDefinition implements Serializable { output.remove(output.size() - 1); stack.moveToStack(output); if (isIncrement) { - stack.push(new PostIncrementAVM2Item(setLocValue.value.getSrc(), setLocValue.value.getLineStartItem(), getProp)); + stack.push(new PostIncrementAVM2Item(setLocValue.value.getSrc(), setLocValue.value.getLineStartItem(), getProp, TypeItem.NUMBER)); } else { - stack.push(new PostDecrementAVM2Item(setLocValue.value.getSrc(), setLocValue.value.getLineStartItem(), getProp)); + stack.push(new PostDecrementAVM2Item(setLocValue.value.getSrc(), setLocValue.value.getLineStartItem(), getProp, TypeItem.NUMBER)); } return; } @@ -1117,9 +1119,9 @@ public abstract class InstructionDefinition implements Serializable { output.remove(output.size() - 1); stack.moveToStack(output); if (isIncrement) { - stack.push(new PostIncrementAVM2Item(setLocValue.value.getSrc(), setLocValue.value.getLineStartItem(), getProp)); + stack.push(new PostIncrementAVM2Item(setLocValue.value.getSrc(), setLocValue.value.getLineStartItem(), getProp, TypeItem.NUMBER)); } else { - stack.push(new PostDecrementAVM2Item(setLocValue.value.getSrc(), setLocValue.value.getLineStartItem(), getProp)); + stack.push(new PostDecrementAVM2Item(setLocValue.value.getSrc(), setLocValue.value.getLineStartItem(), getProp, TypeItem.NUMBER)); } return; } @@ -1196,9 +1198,9 @@ public abstract class InstructionDefinition implements Serializable { stack.pop(); stack.moveToStack(output); if (isIncrement) { - stack.push(new PreIncrementAVM2Item(st.value.getSrc(), st.value.getLineStartItem(), st.value.value)); + stack.push(new PreIncrementAVM2Item(st.value.getSrc(), st.value.getLineStartItem(), st.value.value, TypeItem.NUMBER)); } else { - stack.push(new PreDecrementAVM2Item(st.value.getSrc(), st.value.getLineStartItem(), st.value.value)); + stack.push(new PreDecrementAVM2Item(st.value.getSrc(), st.value.getLineStartItem(), st.value.value, TypeItem.NUMBER)); } return; } @@ -1220,9 +1222,9 @@ public abstract class InstructionDefinition implements Serializable { FullMultinameAVM2Item fm = (FullMultinameAVM2Item) getProp.propertyName; if (fm.compareSame(multiname)) { if (isIncrement) { - stack.addToOutput(new PreIncrementAVM2Item(value.getSrc(), value.getLineStartItem(), getProp)); + stack.addToOutput(new PreIncrementAVM2Item(value.getSrc(), value.getLineStartItem(), getProp, TypeItem.NUMBER)); } else { - stack.addToOutput(new PreDecrementAVM2Item(value.getSrc(), value.getLineStartItem(), getProp)); + stack.addToOutput(new PreDecrementAVM2Item(value.getSrc(), value.getLineStartItem(), getProp, TypeItem.NUMBER)); } return; } @@ -1273,9 +1275,9 @@ public abstract class InstructionDefinition implements Serializable { output.remove(output.size() - 1); stack.moveToStack(output); if (isIncrement) { - stack.push(new PostIncrementAVM2Item(value.getSrc(), value.getLineStartItem(), st.value.value)); + stack.push(new PostIncrementAVM2Item(value.getSrc(), value.getLineStartItem(), st.value.value, TypeItem.NUMBER)); } else { - stack.push(new PostDecrementAVM2Item(value.getSrc(), value.getLineStartItem(), st.value.value)); + stack.push(new PostDecrementAVM2Item(value.getSrc(), value.getLineStartItem(), st.value.value, TypeItem.NUMBER)); } return; } @@ -1299,9 +1301,9 @@ public abstract class InstructionDefinition implements Serializable { FullMultinameAVM2Item fm = (FullMultinameAVM2Item) getProp.propertyName; if (fm.compareSame(multiname)) { if (isIncrement) { - stack.addToOutput(new PostIncrementAVM2Item(value.getSrc(), value.getLineStartItem(), getProp)); + stack.addToOutput(new PostIncrementAVM2Item(value.getSrc(), value.getLineStartItem(), getProp, TypeItem.NUMBER)); } else { - stack.addToOutput(new PostDecrementAVM2Item(value.getSrc(), value.getLineStartItem(), getProp)); + stack.addToOutput(new PostDecrementAVM2Item(value.getSrc(), value.getLineStartItem(), getProp, TypeItem.NUMBER)); } return; } @@ -1448,16 +1450,16 @@ public abstract class InstructionDefinition implements Serializable { if (isIncrement) { if (hasConvert && standalone) { - return new PostIncrementAVM2Item(ins, localData.lineStartInstruction, getProperty); + return new PostIncrementAVM2Item(ins, localData.lineStartInstruction, getProperty, TypeItem.NUMBER); } //TestIncDec3 with result - return new PreIncrementAVM2Item(ins, localData.lineStartInstruction, getProperty); + return new PreIncrementAVM2Item(ins, localData.lineStartInstruction, getProperty, TypeItem.NUMBER); } else { if (hasConvert && standalone) { - return new PostDecrementAVM2Item(ins, localData.lineStartInstruction, getProperty); + return new PostDecrementAVM2Item(ins, localData.lineStartInstruction, getProperty, TypeItem.NUMBER); } //TestIncDec3 with result - return new PreDecrementAVM2Item(ins, localData.lineStartInstruction, getProperty); + return new PreDecrementAVM2Item(ins, localData.lineStartInstruction, getProperty, TypeItem.NUMBER); } } } @@ -1466,4 +1468,19 @@ public abstract class InstructionDefinition implements Serializable { } return null; } + + /** + * Gets number type from item. (can be coerce or convert, if not, number is returned) + * @param item Input item + * @return Type + */ + public static GraphTargetItem getNumberType(GraphTargetItem item) { + if (item instanceof ConvertAVM2Item) { + return ((ConvertAVM2Item) item).type; + } + if (item instanceof CoerceAVM2Item) { + return ((CoerceAVM2Item) item).typeObj; + } + return TypeItem.NUMBER; + } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/DecLocalIIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/DecLocalIIns.java index bcde1fa77..505b92bba 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/DecLocalIIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/DecLocalIIns.java @@ -31,6 +31,7 @@ import com.jpexs.decompiler.flash.ecma.EcmaScript; import com.jpexs.decompiler.flash.ecma.NotCompileTime; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; +import com.jpexs.decompiler.graph.TypeItem; import java.util.List; /** @@ -67,13 +68,13 @@ public class DecLocalIIns extends InstructionDefinition { if (stackTop instanceof LocalRegAVM2Item) { if (regId == ((LocalRegAVM2Item) stackTop).regIndex) { stack.pop(); - stack.push(new PostDecrementAVM2Item(ins, localData.lineStartInstruction, stackTop)); + stack.push(new PostDecrementAVM2Item(ins, localData.lineStartInstruction, stackTop, TypeItem.INT)); isPostDec = true; } } } if (!isPostDec) { - stack.addToOutput(new DecLocalAVM2Item(ins, localData.lineStartInstruction, regId)); + stack.addToOutput(new DecLocalAVM2Item(ins, localData.lineStartInstruction, regId, TypeItem.INT)); } if (localData.localRegs.containsKey(regId)) { localData.localRegs.put(regId, new SubtractAVM2Item(ins, localData.lineStartInstruction, localData.localRegs.get(regId), new IntegerValueAVM2Item(ins, localData.lineStartInstruction, 1))); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/DecLocalIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/DecLocalIns.java index ac74cc594..b71351a36 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/DecLocalIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/DecLocalIns.java @@ -31,6 +31,7 @@ import com.jpexs.decompiler.flash.ecma.EcmaScript; import com.jpexs.decompiler.flash.ecma.NotCompileTime; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; +import com.jpexs.decompiler.graph.TypeItem; import java.util.List; /** @@ -68,13 +69,13 @@ public class DecLocalIns extends InstructionDefinition { if (stackTop instanceof LocalRegAVM2Item) { if (regId == ((LocalRegAVM2Item) stackTop).regIndex) { stack.pop(); - stack.push(new PostDecrementAVM2Item(ins, localData.lineStartInstruction, stackTop)); + stack.push(new PostDecrementAVM2Item(ins, localData.lineStartInstruction, stackTop, TypeItem.NUMBER)); isPostDec = true; } } } if (!isPostDec) { - stack.addToOutput(new DecLocalAVM2Item(ins, localData.lineStartInstruction, regId)); + stack.addToOutput(new DecLocalAVM2Item(ins, localData.lineStartInstruction, regId, TypeItem.NUMBER)); } if (localData.localRegs.containsKey(regId)) { localData.localRegs.put(regId, new SubtractAVM2Item(ins, localData.lineStartInstruction, localData.localRegs.get(regId), new IntegerValueAVM2Item(ins, localData.lineStartInstruction, 1))); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocalTypeIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocalTypeIns.java index a64f124c1..7dd5290be 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocalTypeIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocalTypeIns.java @@ -150,7 +150,7 @@ public abstract class GetLocalTypeIns extends InstructionDefinition { if (inc.regIndex == regId) { output.remove(output.size() - 1); stack.moveToStack(output); - stack.push(new PreIncrementAVM2Item(lastOutput.getSrc(), lastOutput.getLineStartItem(), result)); + stack.push(new PreIncrementAVM2Item(lastOutput.getSrc(), lastOutput.getLineStartItem(), result, inc.type)); return; } } @@ -159,7 +159,7 @@ public abstract class GetLocalTypeIns extends InstructionDefinition { if (dec.regIndex == regId) { output.remove(output.size() - 1); stack.moveToStack(output); - stack.push(new PreDecrementAVM2Item(lastOutput.getSrc(), lastOutput.getLineStartItem(), result)); + stack.push(new PreDecrementAVM2Item(lastOutput.getSrc(), lastOutput.getLineStartItem(), result, dec.type)); return; } } @@ -193,9 +193,9 @@ public abstract class GetLocalTypeIns extends InstructionDefinition { output.remove(output.size() - 1); stack.moveToStack(output); if (isIncrement) { - stack.push(new PostIncrementAVM2Item(setProp.value.getSrc(), setProp.value.getLineStartItem(), getProp)); + stack.push(new PostIncrementAVM2Item(setProp.value.getSrc(), setProp.value.getLineStartItem(), getProp, setLoc.value)); } else { - stack.push(new PostDecrementAVM2Item(setProp.value.getSrc(), setProp.value.getLineStartItem(), getProp)); + stack.push(new PostDecrementAVM2Item(setProp.value.getSrc(), setProp.value.getLineStartItem(), getProp, setLoc.value)); } return; } @@ -266,9 +266,9 @@ public abstract class GetLocalTypeIns extends InstructionDefinition { output.remove(output.size() - 1); stack.moveToStack(output); if (isIncrement) { - stack.push(new PreIncrementAVM2Item(setLocal.value.getSrc(), setLocal.value.getLineStartItem(), getProp)); + stack.push(new PreIncrementAVM2Item(setLocal.value.getSrc(), setLocal.value.getLineStartItem(), getProp, TypeItem.NUMBER)); } else { - stack.push(new PreDecrementAVM2Item(setLocal.value.getSrc(), setLocal.value.getLineStartItem(), getProp)); + stack.push(new PreDecrementAVM2Item(setLocal.value.getSrc(), setLocal.value.getLineStartItem(), getProp, TypeItem.NUMBER)); } return; } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/IncLocalIIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/IncLocalIIns.java index 8bcccb480..ab4955a9f 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/IncLocalIIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/IncLocalIIns.java @@ -31,6 +31,7 @@ import com.jpexs.decompiler.flash.ecma.EcmaScript; import com.jpexs.decompiler.flash.ecma.NotCompileTime; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; +import com.jpexs.decompiler.graph.TypeItem; import java.util.List; /** @@ -67,13 +68,13 @@ public class IncLocalIIns extends InstructionDefinition { if (stackTop instanceof LocalRegAVM2Item) { if (regId == ((LocalRegAVM2Item) stackTop).regIndex) { stack.pop(); - stack.push(new PostIncrementAVM2Item(ins, localData.lineStartInstruction, stackTop)); + stack.push(new PostIncrementAVM2Item(ins, localData.lineStartInstruction, stackTop, TypeItem.INT)); isPostInc = true; } } } if (!isPostInc) { - stack.addToOutput(new IncLocalAVM2Item(ins, localData.lineStartInstruction, regId)); + stack.addToOutput(new IncLocalAVM2Item(ins, localData.lineStartInstruction, regId, TypeItem.INT)); } if (localData.localRegs.containsKey(regId)) { localData.localRegs.put(regId, new AddAVM2Item(ins, localData.lineStartInstruction, localData.localRegs.get(regId), new IntegerValueAVM2Item(ins, localData.lineStartInstruction, 1))); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/IncLocalIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/IncLocalIns.java index 86c4e5b86..55e4eaf21 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/IncLocalIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/IncLocalIns.java @@ -31,6 +31,7 @@ import com.jpexs.decompiler.flash.ecma.EcmaScript; import com.jpexs.decompiler.flash.ecma.NotCompileTime; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; +import com.jpexs.decompiler.graph.TypeItem; import java.util.List; /** @@ -68,13 +69,13 @@ public class IncLocalIns extends InstructionDefinition { if (stackTop instanceof LocalRegAVM2Item) { if (regId == ((LocalRegAVM2Item) stackTop).regIndex) { stack.pop(); - stack.push(new PostIncrementAVM2Item(ins, localData.lineStartInstruction, stackTop)); + stack.push(new PostIncrementAVM2Item(ins, localData.lineStartInstruction, stackTop, TypeItem.NUMBER)); isPostInc = true; } } } if (!isPostInc) { - stack.addToOutput(new IncLocalAVM2Item(ins, localData.lineStartInstruction, regId)); + stack.addToOutput(new IncLocalAVM2Item(ins, localData.lineStartInstruction, regId, TypeItem.NUMBER)); } if (localData.localRegs.containsKey(regId)) { localData.localRegs.put(regId, new AddAVM2Item(ins, localData.lineStartInstruction, localData.localRegs.get(regId), new IntegerValueAVM2Item(ins, localData.lineStartInstruction, 1))); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocalTypeIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocalTypeIns.java index f3ae846f5..d45377e2b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocalTypeIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocalTypeIns.java @@ -107,19 +107,19 @@ public abstract class SetLocalTypeIns extends InstructionDefinition implements S GraphTargetItem.checkDup(stack, output, stack.pop(), value.getNotCoerced().value); //stack.pop(); //TestIncDec2 with result - stack.push(new PostIncrementAVM2Item(ins, localData.lineStartInstruction, inside)); + stack.push(new PostIncrementAVM2Item(ins, localData.lineStartInstruction, inside, getNumberType(value))); } else if ((top instanceof IncrementAVM2Item) && (((IncrementAVM2Item) top).value == inside)) { GraphTargetItem.checkDup(stack, output, stack.pop(), value); //stack.pop(); //TestIncDec1 with result - stack.push(new PreIncrementAVM2Item(ins, localData.lineStartInstruction, inside)); + stack.push(new PreIncrementAVM2Item(ins, localData.lineStartInstruction, inside, getNumberType(value))); } else { - stack.addToOutput(new PostIncrementAVM2Item(ins, localData.lineStartInstruction, inside)); + stack.addToOutput(new PostIncrementAVM2Item(ins, localData.lineStartInstruction, inside, getNumberType(value))); } } else { //TestIncDec1 no result - stack.addToOutput(new PostIncrementAVM2Item(ins, localData.lineStartInstruction, inside)); + stack.addToOutput(new PostIncrementAVM2Item(ins, localData.lineStartInstruction, inside, getNumberType(value))); } return; } @@ -136,18 +136,18 @@ public abstract class SetLocalTypeIns extends InstructionDefinition implements S GraphTargetItem.checkDup(stack, output, stack.pop(), value.getNotCoerced().value); //stack.pop(); //TestIncDec2 with result - stack.push(new PostDecrementAVM2Item(ins, localData.lineStartInstruction, inside)); + stack.push(new PostDecrementAVM2Item(ins, localData.lineStartInstruction, inside, getNumberType(value))); } else if ((top instanceof DecrementAVM2Item) && (((DecrementAVM2Item) top).value == inside)) { GraphTargetItem.checkDup(stack, output, stack.pop(), value); //stack.pop(); //TestIncDec1 with result - stack.push(new PreDecrementAVM2Item(ins, localData.lineStartInstruction, inside)); + stack.push(new PreDecrementAVM2Item(ins, localData.lineStartInstruction, inside, getNumberType(value))); } else { - stack.addToOutput(new PostDecrementAVM2Item(ins, localData.lineStartInstruction, inside)); + stack.addToOutput(new PostDecrementAVM2Item(ins, localData.lineStartInstruction, inside, getNumberType(value))); } } else { //TestIncDec1 no result - stack.addToOutput(new PostDecrementAVM2Item(ins, localData.lineStartInstruction, inside)); + stack.addToOutput(new PostDecrementAVM2Item(ins, localData.lineStartInstruction, inside, getNumberType(value))); } return; } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/SetSlotIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/SetSlotIns.java index 40952fdf1..0f556a609 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/SetSlotIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/SetSlotIns.java @@ -109,17 +109,17 @@ public class SetSlotIns extends InstructionDefinition implements SetTypeIns { GraphTargetItem.checkDup(stack, output, stack.pop(), value.getNotCoercedNoDup().value); //stack.pop(); //TestIncDec12 with result - stack.push(new PostIncrementAVM2Item(ins, localData.lineStartInstruction, inside)); + stack.push(new PostIncrementAVM2Item(ins, localData.lineStartInstruction, inside, getNumberType(value))); } else if ((top instanceof IncrementAVM2Item) && (((IncrementAVM2Item) top).value == inside)) { GraphTargetItem.checkDup(stack, output, stack.pop(), value.getNotCoercedNoDup()); //stack.pop(); //TestIncDec11 with result - stack.push(new PreIncrementAVM2Item(ins, localData.lineStartInstruction, inside)); + stack.push(new PreIncrementAVM2Item(ins, localData.lineStartInstruction, inside, getNumberType(value))); } else { - stack.addToOutput(new PostIncrementAVM2Item(ins, localData.lineStartInstruction, inside)); + stack.addToOutput(new PostIncrementAVM2Item(ins, localData.lineStartInstruction, inside, getNumberType(value))); } } else { - stack.addToOutput(new PostIncrementAVM2Item(ins, localData.lineStartInstruction, inside)); + stack.addToOutput(new PostIncrementAVM2Item(ins, localData.lineStartInstruction, inside, getNumberType(value))); } return; } @@ -139,17 +139,17 @@ public class SetSlotIns extends InstructionDefinition implements SetTypeIns { GraphTargetItem.checkDup(stack, output, stack.pop(), value.getNotCoercedNoDup().value); //stack.pop(); //TestIncDec12 with result - stack.push(new PostDecrementAVM2Item(ins, localData.lineStartInstruction, inside)); + stack.push(new PostDecrementAVM2Item(ins, localData.lineStartInstruction, inside, getNumberType(value))); } else if ((top instanceof DecrementAVM2Item) && (((DecrementAVM2Item) top).value == inside)) { GraphTargetItem.checkDup(stack, output, stack.pop(), value.getNotCoercedNoDup()); //stack.pop(); //TestIncDec11 with result - stack.push(new PreDecrementAVM2Item(ins, localData.lineStartInstruction, inside)); + stack.push(new PreDecrementAVM2Item(ins, localData.lineStartInstruction, inside, getNumberType(value))); } else { - stack.addToOutput(new PostDecrementAVM2Item(ins, localData.lineStartInstruction, inside)); + stack.addToOutput(new PostDecrementAVM2Item(ins, localData.lineStartInstruction, inside, getNumberType(value))); } } else { - stack.addToOutput(new PostDecrementAVM2Item(ins, localData.lineStartInstruction, inside)); + stack.addToOutput(new PostDecrementAVM2Item(ins, localData.lineStartInstruction, inside, getNumberType(value))); } return; } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/decimalsupport/DecLocalPIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/decimalsupport/DecLocalPIns.java index c8c00fc4c..15063bbf8 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/decimalsupport/DecLocalPIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/decimalsupport/DecLocalPIns.java @@ -33,6 +33,7 @@ import com.jpexs.decompiler.flash.abc.avm2.model.PostDecrementAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.operations.SubtractAVM2Item; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; +import com.jpexs.decompiler.graph.TypeItem; import java.util.List; /** @@ -78,13 +79,13 @@ public class DecLocalPIns extends InstructionDefinition { if (stackTop instanceof LocalRegAVM2Item) { if (regId == ((LocalRegAVM2Item) stackTop).regIndex) { stack.pop(); - stack.push(new PostDecrementAVM2Item(ins, localData.lineStartInstruction, stackTop)); + stack.push(new PostDecrementAVM2Item(ins, localData.lineStartInstruction, stackTop, new TypeItem("decimal"))); isPostDec = true; } } } if (!isPostDec) { - stack.addToOutput(new DecLocalAVM2Item(ins, localData.lineStartInstruction, regId)); + stack.addToOutput(new DecLocalAVM2Item(ins, localData.lineStartInstruction, regId, new TypeItem("decimal"))); } if (localData.localRegs.containsKey(regId)) { localData.localRegs.put(regId, new SubtractAVM2Item(ins, localData.lineStartInstruction, localData.localRegs.get(regId), new IntegerValueAVM2Item(ins, localData.lineStartInstruction, 1))); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/decimalsupport/IncLocalPIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/decimalsupport/IncLocalPIns.java index 135833291..1f1885f17 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/decimalsupport/IncLocalPIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/decimalsupport/IncLocalPIns.java @@ -33,6 +33,7 @@ import com.jpexs.decompiler.flash.abc.avm2.model.PostIncrementAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.operations.AddAVM2Item; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; +import com.jpexs.decompiler.graph.TypeItem; import java.util.List; /** @@ -78,13 +79,13 @@ public class IncLocalPIns extends InstructionDefinition { if (stackTop instanceof LocalRegAVM2Item) { if (regId == ((LocalRegAVM2Item) stackTop).regIndex) { stack.pop(); - stack.push(new PostIncrementAVM2Item(ins, localData.lineStartInstruction, stackTop)); + stack.push(new PostIncrementAVM2Item(ins, localData.lineStartInstruction, stackTop, new TypeItem("decimal"))); isPostInc = true; } } } if (!isPostInc) { - stack.addToOutput(new IncLocalAVM2Item(ins, localData.lineStartInstruction, regId)); + stack.addToOutput(new IncLocalAVM2Item(ins, localData.lineStartInstruction, regId, new TypeItem("decimal"))); } if (localData.localRegs.containsKey(regId)) { localData.localRegs.put(regId, new AddAVM2Item(ins, localData.lineStartInstruction, localData.localRegs.get(regId), new IntegerValueAVM2Item(ins, localData.lineStartInstruction, 1))); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/DecLocalAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/DecLocalAVM2Item.java index bb6c80f95..abf3e72f2 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/DecLocalAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/DecLocalAVM2Item.java @@ -34,15 +34,22 @@ public class DecLocalAVM2Item extends AVM2Item { */ public int regIndex; + /** + * Type + */ + public GraphTargetItem type; + /** * Constructor. * @param instruction Instruction * @param lineStartIns Line start instruction * @param regIndex Register index + * @param type Type */ - public DecLocalAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, int regIndex) { + public DecLocalAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, int regIndex, GraphTargetItem type) { super(instruction, lineStartIns, PRECEDENCE_POSTFIX); this.regIndex = regIndex; + this.type = type; } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/DecrementAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/DecrementAVM2Item.java index 21b8f9d92..f285dea55 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/DecrementAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/DecrementAVM2Item.java @@ -68,18 +68,7 @@ public class DecrementAVM2Item extends AVM2Item { } @Override - public GraphTargetItem returnType() { - if (value.returnType().equals(TypeItem.INT)) { - return TypeItem.INT; - } - if (value.returnType().equals(TypeItem.UINT)) { - return TypeItem.UINT; - } - - if (value.returnType().equals(TypeItem.NUMBER)) { - return TypeItem.NUMBER; - } - + public GraphTargetItem returnType() { return TypeItem.NUMBER; } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/IncLocalAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/IncLocalAVM2Item.java index 280a7466e..f1e7b4a05 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/IncLocalAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/IncLocalAVM2Item.java @@ -33,16 +33,23 @@ public class IncLocalAVM2Item extends AVM2Item { * Local register index */ public int regIndex; + + /** + * Type + */ + public GraphTargetItem type; /** * Constructor. * @param instruction Instruction * @param lineStartIns Line start instruction * @param regIndex Local register index + * @param type Type */ - public IncLocalAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, int regIndex) { + public IncLocalAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, int regIndex, GraphTargetItem type) { super(instruction, lineStartIns, PRECEDENCE_POSTFIX); this.regIndex = regIndex; + this.type = type; } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/IncrementAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/IncrementAVM2Item.java index 23af93a3e..e0104df76 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/IncrementAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/IncrementAVM2Item.java @@ -69,17 +69,6 @@ public class IncrementAVM2Item extends AVM2Item { @Override public GraphTargetItem returnType() { - if (value.returnType().equals(TypeItem.INT)) { - return TypeItem.INT; - } - if (value.returnType().equals(TypeItem.UINT)) { - return TypeItem.UINT; - } - - if (value.returnType().equals(TypeItem.NUMBER)) { - return TypeItem.NUMBER; - } - return TypeItem.NUMBER; } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/PostDecrementAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/PostDecrementAVM2Item.java index 736e57bdd..53c9416d4 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/PostDecrementAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/PostDecrementAVM2Item.java @@ -41,16 +41,23 @@ public class PostDecrementAVM2Item extends AVM2Item implements AssignmentAVM2Ite * Object */ public GraphTargetItem object; + + /** + * Type + */ + public GraphTargetItem type; /** * Constructor. * @param instruction Instruction * @param lineStartIns Line start instruction * @param object Object + * @param type Type */ - public PostDecrementAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem object) { + public PostDecrementAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem object, GraphTargetItem type) { super(instruction, lineStartIns, PRECEDENCE_POSTFIX); this.object = object; + this.type = type; } @Override @@ -71,7 +78,7 @@ public class PostDecrementAVM2Item extends AVM2Item implements AssignmentAVM2Ite @Override public GraphTargetItem returnType() { - return object.returnType(); + return type; } @Override @@ -120,4 +127,8 @@ public class PostDecrementAVM2Item extends AVM2Item implements AssignmentAVM2Ite return true; } + @Override + public GraphTargetItem getObject() { + return object; + } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/PostIncrementAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/PostIncrementAVM2Item.java index 56036e4a2..1ddd43b9f 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/PostIncrementAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/PostIncrementAVM2Item.java @@ -42,15 +42,22 @@ public class PostIncrementAVM2Item extends AVM2Item implements AssignmentAVM2Ite */ public GraphTargetItem object; + /** + * Type + */ + public GraphTargetItem type; + /** * Constructor. * @param instruction Instruction * @param lineStartIns Line start instruction * @param object Object + * @param type Type */ - public PostIncrementAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem object) { + public PostIncrementAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem object, GraphTargetItem type) { super(instruction, lineStartIns, PRECEDENCE_POSTFIX); this.object = object; + this.type = type; } @Override @@ -71,7 +78,7 @@ public class PostIncrementAVM2Item extends AVM2Item implements AssignmentAVM2Ite @Override public GraphTargetItem returnType() { - return object.returnType(); + return type; } @Override @@ -120,4 +127,8 @@ public class PostIncrementAVM2Item extends AVM2Item implements AssignmentAVM2Ite return true; } + @Override + public GraphTargetItem getObject() { + return object; + } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/clauses/AssignmentAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/clauses/AssignmentAVM2Item.java index d35902712..719269a28 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/clauses/AssignmentAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/clauses/AssignmentAVM2Item.java @@ -16,10 +16,15 @@ */ package com.jpexs.decompiler.flash.abc.avm2.model.clauses; +import com.jpexs.decompiler.graph.GraphTargetItem; + /** * Assignment. * * @author JPEXS */ public interface AssignmentAVM2Item { + public GraphTargetItem returnType(); + + public GraphTargetItem getObject(); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/AddAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/AddAVM2Item.java index dcee34607..99bc1eda9 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/AddAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/AddAVM2Item.java @@ -112,23 +112,7 @@ public class AddAVM2Item extends BinaryOpItem implements CompoundableBinaryOp { GraphTargetItem rightType = rightSide.returnType(); if (leftType.equals(TypeItem.STRING) || rightType.equals(TypeItem.STRING)) { return TypeItem.STRING; - } - if (leftType.equals(TypeItem.INT) && rightType.equals(TypeItem.INT)) { - return TypeItem.INT; - } - - if ((leftType.equals(TypeItem.INT) && rightType.equals(TypeItem.UINT)) - || (leftType.equals(TypeItem.UINT) && rightType.equals(TypeItem.INT))) { - return TypeItem.INT; - } - - if (leftType.equals(TypeItem.UINT) && rightType.equals(TypeItem.UINT)) { - return TypeItem.UINT; - } - - if (leftType.equals(TypeItem.NUMBER) || rightType.equals(TypeItem.NUMBER)) { - return TypeItem.NUMBER; - } + } return TypeItem.NUMBER; } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/MultiplyAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/MultiplyAVM2Item.java index 1d8a9534f..14dd52e11 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/MultiplyAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/MultiplyAVM2Item.java @@ -92,18 +92,6 @@ public class MultiplyAVM2Item extends BinaryOpItem implements CompoundableBinary @Override public GraphTargetItem returnType() { - GraphTargetItem leftType = leftSide.returnType(); - GraphTargetItem rightType = rightSide.returnType(); - if (leftType.equals(TypeItem.INT) && rightType.equals(TypeItem.INT)) { - return TypeItem.INT; - } - if (leftType.equals(TypeItem.UINT) && rightType.equals(TypeItem.UINT)) { - return TypeItem.UINT; - } - if (leftType.equals(TypeItem.NUMBER) || rightType.equals(TypeItem.NUMBER)) { - return TypeItem.NUMBER; - } - return TypeItem.NUMBER; } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/PreDecrementAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/PreDecrementAVM2Item.java index 7bd2b88c9..7ec8cc404 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/PreDecrementAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/PreDecrementAVM2Item.java @@ -35,14 +35,21 @@ import java.util.List; */ public class PreDecrementAVM2Item extends UnaryOpItem implements AssignmentAVM2Item { + /** + * Type + */ + public GraphTargetItem type; + /** * Constructor. * @param instruction Instruction * @param lineStartIns Line start instruction * @param object Object + * @param type Type */ - public PreDecrementAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem object) { + public PreDecrementAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem object, GraphTargetItem type) { super(AVM2GraphTargetDialect.INSTANCE, instruction, lineStartIns, PRECEDENCE_UNARY, object, "--", "" /*"Number" Causes unnecessary ++Number(xx) when xx not number*/); + this.type = type; } @Override @@ -68,6 +75,11 @@ public class PreDecrementAVM2Item extends UnaryOpItem implements AssignmentAVM2I @Override public GraphTargetItem returnType() { - return value.returnType(); + return type; } + + @Override + public GraphTargetItem getObject() { + return value; + } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/PreIncrementAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/PreIncrementAVM2Item.java index de08f2c63..d55d040a6 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/PreIncrementAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/PreIncrementAVM2Item.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.abc.avm2.model.operations; import com.jpexs.decompiler.flash.SourceGeneratorLocalData; import com.jpexs.decompiler.flash.abc.avm2.graph.AVM2GraphTargetDialect; +import com.jpexs.decompiler.flash.abc.avm2.model.clauses.AssignmentAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.parser.script.AssignableAVM2Item; import com.jpexs.decompiler.graph.CompilationException; import com.jpexs.decompiler.graph.GraphSourceItem; @@ -32,16 +33,23 @@ import java.util.List; * * @author JPEXS */ -public class PreIncrementAVM2Item extends UnaryOpItem { +public class PreIncrementAVM2Item extends UnaryOpItem implements AssignmentAVM2Item { + /** + * Type + */ + public GraphTargetItem type; + /** * Constructor. * @param instruction Instruction * @param lineStartIns Line start instruction * @param object Object + * @param type Type */ - public PreIncrementAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem object) { + public PreIncrementAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem object, GraphTargetItem type) { super(AVM2GraphTargetDialect.INSTANCE, instruction, lineStartIns, PRECEDENCE_UNARY, object, "++", "" /*"Number" Causes unnecessary ++Number(xx) when xx not number*/); + this.type = type; } @Override @@ -67,6 +75,11 @@ public class PreIncrementAVM2Item extends UnaryOpItem { @Override public GraphTargetItem returnType() { - return value.returnType(); + return type; + } + + @Override + public GraphTargetItem getObject() { + return value; } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/SubtractAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/SubtractAVM2Item.java index 8a6d25e22..39283e080 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/SubtractAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/SubtractAVM2Item.java @@ -101,26 +101,6 @@ public class SubtractAVM2Item extends BinaryOpItem implements CompoundableBinary @Override public GraphTargetItem returnType() { - GraphTargetItem leftType = leftSide.returnType(); - GraphTargetItem rightType = rightSide.returnType(); - - if (leftType.equals(TypeItem.INT) && rightType.equals(TypeItem.INT)) { - return TypeItem.INT; - } - - if ((leftType.equals(TypeItem.INT) && rightType.equals(TypeItem.UINT)) - || (leftType.equals(TypeItem.UINT) && rightType.equals(TypeItem.INT))) { - return TypeItem.INT; - } - - if (leftType.equals(TypeItem.UINT) && rightType.equals(TypeItem.UINT)) { - return TypeItem.INT; - } - - if (leftType.equals(TypeItem.NUMBER) || rightType.equals(TypeItem.NUMBER)) { - return TypeItem.NUMBER; - } - return TypeItem.NUMBER; } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3Parser.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3Parser.java index 66f26b6b4..fba189428 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3Parser.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3Parser.java @@ -233,14 +233,14 @@ public class ActionScript3Parser { if (!isNameOrProp(ret)) { throw new AVM2ParseException("Invalid assignment", lexer.yyline()); } - ret = new PostIncrementAVM2Item(null, null, ret); + ret = new PostIncrementAVM2Item(null, null, ret, TypeItem.NUMBER); //TODO: how about TypeItem.INT? s = lex(); } else if (s.type == SymbolType.DECREMENT) { if (!isNameOrProp(ret)) { throw new AVM2ParseException("Invalid assignment", lexer.yyline()); } - ret = new PostDecrementAVM2Item(null, null, ret); + ret = new PostDecrementAVM2Item(null, null, ret, TypeItem.NUMBER); //TODO: how about TypeItem.INT? s = lex(); } @@ -2660,10 +2660,10 @@ public class ActionScript3Parser { throw new AVM2ParseException("Not a property or name", lexer.yyline()); } if (s.type == SymbolType.INCREMENT) { - ret = new PreIncrementAVM2Item(null, null, varincdec); + ret = new PreIncrementAVM2Item(null, null, varincdec, TypeItem.NUMBER); //TODO: how about TypeItem.INT? } if (s.type == SymbolType.DECREMENT) { - ret = new PreDecrementAVM2Item(null, null, varincdec); + ret = new PreDecrementAVM2Item(null, null, varincdec, TypeItem.NUMBER); //TODO: how about TypeItem.INT? } break; 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 f99439b9d..4e3148fc4 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/GraphTargetDialect.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/GraphTargetDialect.java @@ -41,7 +41,7 @@ public abstract class GraphTargetDialect { * @return GraphTarget item */ public abstract GraphTargetItem valToItem(Object value); - + /** * Checks whether this dialect allows multi level breaks * @@ -59,4 +59,14 @@ public abstract class GraphTargetDialect { * @return Writer */ public abstract GraphTextWriter writeTemporaryDeclaration(GraphTextWriter writer, LocalData localData, String suffix, int tempIndex, GraphTargetItem value) throws InterruptedException; + + /** + * Copy coerce value + * @param coercedOriginal + * @param newValue + * @return NewValue with copied coerce from coercedOriginal + */ + public GraphTargetItem copyCoerce(GraphTargetItem coercedOriginal, GraphTargetItem newValue) { + return newValue; + } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/GraphTargetItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/GraphTargetItem.java index 5665b181d..2fd9e76ab 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/GraphTargetItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/GraphTargetItem.java @@ -188,7 +188,8 @@ public abstract class GraphTargetItem implements Serializable, Cloneable { if (it2 == null) { return it; } - return it2; + + return it.dialect.copyCoerce(it, it2); } /** diff --git a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3ClassicAirDecompileTest.java b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3ClassicAirDecompileTest.java index 863a64d16..802b61597 100644 --- a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3ClassicAirDecompileTest.java +++ b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3ClassicAirDecompileTest.java @@ -491,7 +491,7 @@ public class ActionScript3ClassicAirDecompileTest extends ActionScript3Decompile @Test public void testDoWhile() { - decompileMethod("classic_air", "testDoWhile", "var a:int = 8;\r\n" + decompileMethod("classic_air", "testDoWhile", "var a:* = 8;\r\n" + "do\r\n" + "{\r\n" + "trace(\"a=\" + a);\r\n" @@ -595,7 +595,7 @@ public class ActionScript3ClassicAirDecompileTest extends ActionScript3Decompile @Test public void testFinallyZeroJump() { - decompileMethod("classic_air", "testFinallyZeroJump", "var str:* = param1;\r\n" + decompileMethod("classic_air", "testFinallyZeroJump", "var str:String = param1;\r\n" + "try\r\n" + "{\r\n" + "}\r\n" @@ -751,7 +751,7 @@ public class ActionScript3ClassicAirDecompileTest extends ActionScript3Decompile + "list[1] = \"second\";\r\n" + "list[2] = \"third\";\r\n" + "var _loc4_:int = 0;\r\n" - + "var _loc3_:* = list;\r\n" + + "var _loc3_:Array = list;\r\n" + "for each(item in _loc3_)\r\n" + "{\r\n" + "return item;\r\n" @@ -913,7 +913,7 @@ public class ActionScript3ClassicAirDecompileTest extends ActionScript3Decompile decompileMethod("classic_air", "testForInReturn", "var dic:Dictionary = null;\r\n" + "var item:* = null;\r\n" + "var _loc4_:int = 0;\r\n" - + "var _loc3_:* = dic;\r\n" + + "var _loc3_:Dictionary = dic;\r\n" + "for(item in _loc3_)\r\n" + "{\r\n" + "return item;\r\n" @@ -1343,7 +1343,7 @@ public class ActionScript3ClassicAirDecompileTest extends ActionScript3Decompile @Test public void testIncDec1() { - decompileMethod("classic_air", "testIncDec1", "var a:int = 5;\r\n" + decompileMethod("classic_air", "testIncDec1", "var a:* = 5;\r\n" + "trace(\"++a with result\");\r\n" + "trace(++a);\r\n" + "trace(\"--a with result\");\r\n" @@ -1357,7 +1357,7 @@ public class ActionScript3ClassicAirDecompileTest extends ActionScript3Decompile @Test public void testIncDec2() { - decompileMethod("classic_air", "testIncDec2", "var a:int = 5;\r\n" + decompileMethod("classic_air", "testIncDec2", "var a:* = 5;\r\n" + "trace(\"a++ with result\");\r\n" + "trace(a++);\r\n" + "trace(\"a-- with result\");\r\n" @@ -1903,7 +1903,7 @@ public class ActionScript3ClassicAirDecompileTest extends ActionScript3Decompile @Test public void testOptimization() { decompileMethod("classic_air", "testOptimization", "var f:int = 0;\r\n" - + "var g:* = 0;\r\n" + + "var g:int = 0;\r\n" + "var h:int = 0;\r\n" + "var a:int = 1;\r\n" + "var b:int = 2;\r\n" diff --git a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3ClassicDecompileTest.java b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3ClassicDecompileTest.java index 59ed22a8b..24d5fea38 100644 --- a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3ClassicDecompileTest.java +++ b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3ClassicDecompileTest.java @@ -2243,8 +2243,8 @@ public class ActionScript3ClassicDecompileTest extends ActionScript3DecompileTes public void testTernarOperator2() { decompileMethod("classic", "testTernarOperator2", "var b:Boolean = true;\r\n" + "var i:int = 1;\r\n" - + "var j:int = b ? i : i + 1;\r\n" - + "var k:int = Boolean(i) ? j : j + 1;\r\n", + + "var j:int = b ? i : int(i + 1);\r\n" + + "var k:int = Boolean(i) ? j : int(j + 1);\r\n", false); }