diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/ActionScript2Parser.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/ActionScript2Parser.java index 961d2a403..f41ac1076 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/ActionScript2Parser.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/ActionScript2Parser.java @@ -120,6 +120,7 @@ import com.jpexs.decompiler.flash.action.model.operations.SubtractActionItem; import com.jpexs.decompiler.flash.action.model.operations.URShiftActionItem; import com.jpexs.decompiler.flash.action.parser.ActionParseException; import com.jpexs.decompiler.flash.action.swf4.ActionIf; +import com.jpexs.decompiler.flash.action.swf4.ActionPush; import com.jpexs.decompiler.flash.action.swf4.ConstantIndex; import com.jpexs.decompiler.flash.action.swf5.ActionConstantPool; import com.jpexs.decompiler.flash.ecma.Null; @@ -1872,18 +1873,63 @@ public class ActionScript2Parser { return retTree; } - public List actionsFromTree(List tree, List constantPool) throws CompilationException { + private List generateActionList(List tree, List constantPool) throws CompilationException { ActionSourceGenerator gen = new ActionSourceGenerator(swfVersion, constantPool); + SourceGeneratorLocalData localData = new SourceGeneratorLocalData(new HashMap<>(), 0, Boolean.FALSE, 0); + return gen.generate(localData, tree); + } + + public List actionsFromTree(List tree, List constantPoolDraft) throws CompilationException { List ret = new ArrayList<>(); - SourceGeneratorLocalData localData = new SourceGeneratorLocalData( - new HashMap<>(), 0, Boolean.FALSE, 0); - List srcList = gen.generate(localData, tree); + + List srcList = generateActionList(tree, constantPoolDraft); + + List orderedConstantPool = new ArrayList<>(); + + boolean canChangeConstantIndices; + int lastIndex = constantPoolDraft.size() - 1; + if (lastIndex <= ActionPush.MAX_CONSTANT_INDEX_TYPE8) { + //can change constant indices as ActionPush contains always 1 byte per constant + canChangeConstantIndices = true; + } else { + //variable number bytes per ActionPush constant, + //must generate again to make relative offsets in jumps work + canChangeConstantIndices = false; + } + + //create ordered constant pool, update constantindices if they can be changed + for (GraphSourceItem src : srcList) { + if (src instanceof ActionPush) { + ActionPush ap = (ActionPush) src; + for (int i = 0; i < ap.values.size(); i++) { + Object val = ap.values.get(i); + if (val instanceof ConstantIndex) { + ConstantIndex ci = (ConstantIndex) val; + String cval = constantPoolDraft.get(ci.index); + int orderedIndex = orderedConstantPool.indexOf(cval); + if (orderedIndex == -1) { + orderedIndex = orderedConstantPool.size(); + orderedConstantPool.add(cval); + } + if (canChangeConstantIndices) { + ci.index = orderedIndex; + } + } + } + } + } + + if (!canChangeConstantIndices) { + //generate again, as number of bytes per ActionPush can change + srcList = generateActionList(tree, orderedConstantPool); + } + for (GraphSourceItem s : srcList) { if (s instanceof Action) { ret.add((Action) s); } } - ret.add(0, new ActionConstantPool(constantPool)); + ret.add(0, new ActionConstantPool(orderedConstantPool)); return ret; } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/ActionSourceGenerator.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/ActionSourceGenerator.java index 7ffe49060..5f2d04bf5 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/ActionSourceGenerator.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/ActionSourceGenerator.java @@ -724,12 +724,12 @@ public class ActionSourceGenerator implements SourceGenerator { if (pass == 1 && isFunc) { //Add methods in first pass FunctionActionItem fi = (FunctionActionItem) en.getValue(); ifbody.add(new ActionPush(new RegisterNumber(traitsStatic.get(t) ? 1 : 2))); - ifbody.add(new ActionPush(getName(en.getKey()))); + ifbody.add(pushConst(getName(en.getKey()))); ifbody.addAll(toActionList(fi.toSource(localData, this))); ifbody.add(new ActionSetMember()); } else if (pass == 2 && !isFunc) { //add variables in second pass ifbody.add(new ActionPush(new RegisterNumber(traitsStatic.get(t) ? 1 : 2))); - ifbody.add(new ActionPush(getName(en.getKey()))); + ifbody.add(pushConst(getName(en.getKey()))); ifbody.addAll(toActionList(en.getValue().toSource(localData, this))); ifbody.add(new ActionSetMember()); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionPush.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionPush.java index 8c9d813c6..183caf9aa 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionPush.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionPush.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.action.swf4; import com.jpexs.decompiler.flash.BaseLocalData; @@ -62,6 +63,12 @@ public class ActionPush extends Action { public List constantPool; + /** + * Maximum constant index for storing in type 8, greater indices must be + * stored in type 9 + */ + public static final int MAX_CONSTANT_INDEX_TYPE8 = 255; + public ActionPush(int actionLength, SWFInputStream sis, int version) throws IOException { super(0x96, actionLength); int type; @@ -151,7 +158,7 @@ public class ActionPush extends Action { } } else if (o instanceof ConstantIndex) { int cIndex = ((ConstantIndex) o).index; - if (cIndex < 256) { + if (cIndex <= MAX_CONSTANT_INDEX_TYPE8) { sos.writeUI8(8); sos.writeUI8(cIndex); } else {