diff --git a/CHANGELOG.md b/CHANGELOG.md index b119bc35d..4c4e49c89 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ All notable changes to this project will be documented in this file. - Correct body index for script initializer in P-code debugging - #1550 TTF export - correctly handle duplicate unicode codes - #1548 correctly handle empty generated file names +- #1379 AS3 - better handling local registers postincrement/decrement ## [11.3.0] - 2020-04-25 ### Added 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 4f0a3d597..cab47621c 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 @@ -12,7 +12,8 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library. */ + * License along with this library. + */ package com.jpexs.decompiler.flash.abc.avm2.instructions.localregs; import com.jpexs.decompiler.flash.abc.AVM2LocalData; @@ -23,6 +24,8 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; import com.jpexs.decompiler.flash.abc.avm2.model.DecLocalAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.IntegerValueAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.LocalRegAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.PostDecrementAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.operations.SubtractAVM2Item; import com.jpexs.decompiler.flash.ecma.EcmaScript; import com.jpexs.decompiler.flash.ecma.NotCompileTime; @@ -54,7 +57,20 @@ public class DecLocalIIns extends InstructionDefinition { @Override public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List output, String path) { int regId = ins.operands[0]; - output.add(new DecLocalAVM2Item(ins, localData.lineStartInstruction, regId)); + boolean isPostDec = false; + if (!stack.isEmpty()) { + GraphTargetItem stackTop = stack.peek(); + if (stackTop instanceof LocalRegAVM2Item) { + if (regId == ((LocalRegAVM2Item) stackTop).regIndex) { + stack.pop(); + stack.push(new PostDecrementAVM2Item(ins, localData.lineStartInstruction, stackTop)); + isPostDec = true; + } + } + } + if (!isPostDec) { + output.add(new DecLocalAVM2Item(ins, localData.lineStartInstruction, regId)); + } if (localData.localRegs.containsKey(regId)) { localData.localRegs.put(regId, new SubtractAVM2Item(ins, localData.lineStartInstruction, localData.localRegs.get(regId), new IntegerValueAVM2Item(ins, localData.lineStartInstruction, 1L))); } else { 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 fce7ff632..57abe0704 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 @@ -12,7 +12,8 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library. */ + * License along with this library. + */ package com.jpexs.decompiler.flash.abc.avm2.instructions.localregs; import com.jpexs.decompiler.flash.abc.AVM2LocalData; @@ -23,6 +24,8 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; import com.jpexs.decompiler.flash.abc.avm2.model.DecLocalAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.IntegerValueAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.LocalRegAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.PostDecrementAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.operations.SubtractAVM2Item; import com.jpexs.decompiler.flash.ecma.EcmaScript; import com.jpexs.decompiler.flash.ecma.NotCompileTime; @@ -54,7 +57,20 @@ public class DecLocalIns extends InstructionDefinition { @Override public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List output, String path) { int regId = ins.operands[0]; - output.add(new DecLocalAVM2Item(ins, localData.lineStartInstruction, regId)); + boolean isPostDec = false; + if (!stack.isEmpty()) { + GraphTargetItem stackTop = stack.peek(); + if (stackTop instanceof LocalRegAVM2Item) { + if (regId == ((LocalRegAVM2Item) stackTop).regIndex) { + stack.pop(); + stack.push(new PostDecrementAVM2Item(ins, localData.lineStartInstruction, stackTop)); + isPostDec = true; + } + } + } + if (!isPostDec) { + output.add(new DecLocalAVM2Item(ins, localData.lineStartInstruction, regId)); + } if (localData.localRegs.containsKey(regId)) { localData.localRegs.put(regId, new SubtractAVM2Item(ins, localData.lineStartInstruction, localData.localRegs.get(regId), new IntegerValueAVM2Item(ins, localData.lineStartInstruction, 1L))); } else { 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 4256dc51f..ef697dcbe 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 @@ -12,7 +12,8 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library. */ + * License along with this library. + */ package com.jpexs.decompiler.flash.abc.avm2.instructions.localregs; import com.jpexs.decompiler.flash.abc.AVM2LocalData; @@ -23,6 +24,8 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; import com.jpexs.decompiler.flash.abc.avm2.model.IncLocalAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.IntegerValueAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.LocalRegAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.PostIncrementAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.operations.AddAVM2Item; import com.jpexs.decompiler.flash.ecma.EcmaScript; import com.jpexs.decompiler.flash.ecma.NotCompileTime; @@ -54,11 +57,22 @@ public class IncLocalIIns extends InstructionDefinition { @Override public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List output, String path) { int regId = ins.operands[0]; - output.add(new IncLocalAVM2Item(ins, localData.lineStartInstruction, regId)); + boolean isPostInc = false; + if (!stack.isEmpty()) { + GraphTargetItem stackTop = stack.peek(); + if (stackTop instanceof LocalRegAVM2Item) { + if (regId == ((LocalRegAVM2Item) stackTop).regIndex) { + stack.pop(); + stack.push(new PostIncrementAVM2Item(ins, localData.lineStartInstruction, stackTop)); + isPostInc = true; + } + } + } + if (!isPostInc) { + output.add(new IncLocalAVM2Item(ins, localData.lineStartInstruction, regId)); + } if (localData.localRegs.containsKey(regId)) { localData.localRegs.put(regId, new AddAVM2Item(ins, localData.lineStartInstruction, localData.localRegs.get(regId), new IntegerValueAVM2Item(ins, localData.lineStartInstruction, 1L))); - } else { - //localRegs.put(regIndex, new AddAVM2Item(ins, localData.lineStartInstruction, null, new IntegerValueAVM2Item(ins, localData.lineStartInstruction, new Long(1)))); } if (!localData.localRegAssignmentIps.containsKey(regId)) { localData.localRegAssignmentIps.put(regId, 0); 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 70b4121aa..0ff39a48e 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 @@ -12,7 +12,8 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library. */ + * License along with this library. + */ package com.jpexs.decompiler.flash.abc.avm2.instructions.localregs; import com.jpexs.decompiler.flash.abc.AVM2LocalData; @@ -23,6 +24,8 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; import com.jpexs.decompiler.flash.abc.avm2.model.IncLocalAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.IntegerValueAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.LocalRegAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.PostIncrementAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.operations.AddAVM2Item; import com.jpexs.decompiler.flash.ecma.EcmaScript; import com.jpexs.decompiler.flash.ecma.NotCompileTime; @@ -54,7 +57,20 @@ public class IncLocalIns extends InstructionDefinition { @Override public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List output, String path) { int regId = ins.operands[0]; - output.add(new IncLocalAVM2Item(ins, localData.lineStartInstruction, regId)); + boolean isPostInc = false; + if (!stack.isEmpty()) { + GraphTargetItem stackTop = stack.peek(); + if (stackTop instanceof LocalRegAVM2Item) { + if (regId == ((LocalRegAVM2Item) stackTop).regIndex) { + stack.pop(); + stack.push(new PostIncrementAVM2Item(ins, localData.lineStartInstruction, stackTop)); + isPostInc = true; + } + } + } + if (!isPostInc) { + output.add(new IncLocalAVM2Item(ins, localData.lineStartInstruction, regId)); + } if (localData.localRegs.containsKey(regId)) { localData.localRegs.put(regId, new AddAVM2Item(ins, localData.lineStartInstruction, localData.localRegs.get(regId), new IntegerValueAVM2Item(ins, localData.lineStartInstruction, 1L))); } else {