diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/fastactionlist/FastActionList.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/fastactionlist/FastActionList.java index 4f0b3aacd..ab7eaee5a 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/fastactionlist/FastActionList.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/fastactionlist/FastActionList.java @@ -57,6 +57,11 @@ public class FastActionList implements Collection { getJumps(actions, actionItemMap); } + public final ActionItem insertItemBefore(ActionItem item, Action action) { + ActionItem newItem = new ActionItem(action); + return insertItemBefore(item, newItem); + } + public final ActionItem insertItemAfter(ActionItem item, Action action) { ActionItem newItem = new ActionItem(action); return insertItemAfter(item, newItem); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/pcode/ASMParser.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/pcode/ASMParser.java index 1dd150a30..6f681cf0b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/pcode/ASMParser.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/pcode/ASMParser.java @@ -550,6 +550,10 @@ public class ASMParser { } } + if (ret.size() == 0 || !(ret.get(ret.size() - 1) instanceof ActionEnd)) { + ret.add(new ActionEnd()); + } + return ret; } } diff --git a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/ActionScript2ModificationTest.java b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/ActionScript2ModificationTest.java index e8e22ac2f..1f90b8ed6 100644 --- a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/ActionScript2ModificationTest.java +++ b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/ActionScript2ModificationTest.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash; import com.jpexs.decompiler.flash.action.Action; import com.jpexs.decompiler.flash.action.ActionList; +import com.jpexs.decompiler.flash.action.fastactionlist.FastActionList; import com.jpexs.decompiler.flash.action.parser.ActionParseException; import com.jpexs.decompiler.flash.action.parser.pcode.ASMParser; import com.jpexs.decompiler.flash.action.swf4.ActionJump; @@ -67,7 +68,7 @@ public class ActionScript2ModificationTest extends ActionScript2TestBase { return actions; } - public void testRemoveAction(String actionsString, String expectedResult, int[] actionsToRemove) { + public void testRemoveActionNormal(String actionsString, String expectedResult, int[] actionsToRemove) { try { ActionList actions = ASMParser.parse(0, true, actionsString, swf.version, false); @@ -90,7 +91,38 @@ public class ActionScript2ModificationTest extends ActionScript2TestBase { } } - public void testAddAction(String actionsString, String expectedResult, Action action, int index) { + public void testRemoveActionFast(String actionsString, String expectedResult, int[] actionsToRemove) { + try { + ActionList actions = ASMParser.parse(0, true, actionsString, swf.version, false); + FastActionList fastActions = new FastActionList(actions); + + for (int i : actionsToRemove) { + fastActions.removeItem(i, 1); + } + + actions = fastActions.toActionList(); + + DoActionTag doa = getFirstActionTag(); + doa.setActionBytes(Action.actionsToBytes(actions, true, swf.version)); + HighlightedTextWriter writer = new HighlightedTextWriter(new CodeFormatting(), false); + doa.getASMSource(ScriptExportMode.PCODE, writer, doa.getActions()); + String actualResult = normalizeLabels(writer.toString()); + + actualResult = cleanPCode(actualResult); + expectedResult = cleanPCode(expectedResult); + + Assert.assertEquals(actualResult, expectedResult); + } catch (IOException | ActionParseException | InterruptedException ex) { + fail(); + } + } + + public void testRemoveAction(String actionsString, String expectedResult, int[] actionsToRemove) { + testRemoveActionNormal(actionsString, expectedResult, actionsToRemove); + testRemoveActionFast(actionsString, expectedResult, actionsToRemove); + } + + public void testAddActionNormal(String actionsString, String expectedResult, Action action, int index) { try { ActionList actions = ASMParser.parse(0, true, actionsString, swf.version, false); @@ -111,6 +143,29 @@ public class ActionScript2ModificationTest extends ActionScript2TestBase { } } + public void testAddActionFast(String actionsString, String expectedResult, Action action, int index) { + try { + ActionList actions = ASMParser.parse(0, true, actionsString, swf.version, false); + FastActionList fastActions = new FastActionList(actions); + + fastActions.insertItemBefore(fastActions.get(index), action); + actions = fastActions.toActionList(); + + DoActionTag doa = getFirstActionTag(); + doa.setActionBytes(Action.actionsToBytes(actions, true, swf.version)); + HighlightedTextWriter writer = new HighlightedTextWriter(new CodeFormatting(), false); + doa.getASMSource(ScriptExportMode.PCODE, writer, doa.getActions()); + String actualResult = normalizeLabels(writer.toString()); + + actualResult = cleanPCode(actualResult); + expectedResult = cleanPCode(expectedResult); + + Assert.assertEquals(actualResult, expectedResult); + } catch (IOException | ActionParseException | InterruptedException ex) { + fail(); + } + } + @Test public void testRemoveJumpAction() { String actionsString @@ -227,6 +282,33 @@ public class ActionScript2ModificationTest extends ActionScript2TestBase { testRemoveAction(actionsString, expectedResult, new int[]{7}); } + @Test + public void testAddAtionFirst() { + String actionsString + = "ConstantPool\n" + + "DefineFunction \"test\" 1 \"p1\" {\n" + + "Push 1\n" + + "GetVariable\n" + + "}\n" + + "Push 2\n" + + "If label_1\n" + + "Push 3\n" + + "label_1:Push 4"; + String expectedResult + = "GetMember\n" + + "ConstantPool\n" + + "DefineFunction \"test\" 1 \"p1\" {\n" + + "Push 1\n" + + "GetVariable\n" + + "}\n" + + "Push 2\n" + + "If label_1\n" + + "Push 3\n" + + "label_1:Push 4"; + testAddActionNormal(actionsString, expectedResult, new ActionGetMember(), 0); + testAddActionFast(actionsString, expectedResult, new ActionGetMember(), 0); + } + @Test public void testAddAtion1() { String actionsString @@ -250,7 +332,8 @@ public class ActionScript2ModificationTest extends ActionScript2TestBase { + "If label_1\n" + "Push 3\n" + "label_1:Push 4"; - testAddAction(actionsString, expectedResult, new ActionGetMember(), 1); + testAddActionNormal(actionsString, expectedResult, new ActionGetMember(), 1); + testAddActionFast(actionsString, expectedResult, new ActionGetMember(), 1); } @Test @@ -276,7 +359,8 @@ public class ActionScript2ModificationTest extends ActionScript2TestBase { + "If label_1\n" + "Push 3\n" + "label_1:Push 4"; - testAddAction(actionsString, expectedResult, new ActionGetMember(), 2); + testAddActionNormal(actionsString, expectedResult, new ActionGetMember(), 2); + testAddActionFast(actionsString, expectedResult, new ActionGetMember(), 2); } @Test @@ -302,7 +386,8 @@ public class ActionScript2ModificationTest extends ActionScript2TestBase { + "Push 3\n" + "GetMember\n" + "label_1:Push 4"; - testAddAction(actionsString, expectedResult, new ActionGetMember(), 7); + testAddActionNormal(actionsString, expectedResult, new ActionGetMember(), 7); + testAddActionFast(actionsString, expectedResult, new ActionGetMember(), 7); } @Test @@ -328,7 +413,8 @@ public class ActionScript2ModificationTest extends ActionScript2TestBase { + "If label_1\n" + "Push 3\n" + "label_1:Push 4"; - testAddAction(actionsString, expectedResult, new ActionGetMember(), 4); + testAddActionNormal(actionsString, expectedResult, new ActionGetMember(), 4); + testAddActionFast(actionsString, expectedResult, new ActionGetMember(), 4); } @Test @@ -353,6 +439,7 @@ public class ActionScript2ModificationTest extends ActionScript2TestBase { ActionJump jump = new ActionJump(0); jump.setAddress(9); jump.setJumpOffset(24 - 9 - 5); - testAddAction(actionsString, expectedResult, jump, 3); + testAddActionNormal(actionsString, expectedResult, jump, 3); + testAddActionFast(actionsString, expectedResult, jump, 3); } }