inline constant pool string when the pool is too big

This commit is contained in:
honfika@gmail.com
2015-07-18 15:30:51 +02:00
parent 35cfe219a4
commit a7d57c19a4
11 changed files with 119 additions and 22 deletions

View File

@@ -392,7 +392,7 @@ public abstract class Action implements GraphSourceItem {
return new ByteArrayRange(bytes);
}
public static void setConstantPools(ASMSource src, List<List<String>> constantPools) {
public static void setConstantPools(ASMSource src, List<List<String>> constantPools, boolean tryInline) throws ConstantPoolTooBigException {
try {
ActionList actions = src.getActions();
int poolIdx = 0;
@@ -400,6 +400,24 @@ public abstract class Action implements GraphSourceItem {
if (action instanceof ActionConstantPool) {
ActionConstantPool cPool = (ActionConstantPool) action;
List<String> constantPool = constantPools.get(poolIdx);
int size = ActionConstantPool.calculateSize(constantPool);
if (size > 0xffff && tryInline) {
for (int i = 0; i < constantPool.size(); i++) {
int refCount = actions.getConstantPoolIndexReferenceCount(i);
if (refCount == 1) {
actions.inlineConstantPoolString(i, constantPool.get(i));
constantPool.set(i, "");
}
}
size = ActionConstantPool.calculateSize(constantPool);
}
if (size > 0xffff) {
throw new ConstantPoolTooBigException(poolIdx, size);
}
cPool.constantPool = constantPool;
poolIdx++;

View File

@@ -21,6 +21,8 @@ import com.jpexs.decompiler.flash.action.special.ActionNop;
import com.jpexs.decompiler.flash.action.special.ActionStore;
import com.jpexs.decompiler.flash.action.swf4.ActionIf;
import com.jpexs.decompiler.flash.action.swf4.ActionJump;
import com.jpexs.decompiler.flash.action.swf4.ActionPush;
import com.jpexs.decompiler.flash.action.swf4.ConstantIndex;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
import com.jpexs.decompiler.flash.helpers.FileTextWriter;
@@ -143,6 +145,42 @@ public class ActionList extends ArrayList<Action> {
};
}
public int getConstantPoolIndexReferenceCount(int index) {
int count = 0;
for (Action action : this) {
if (action instanceof ActionPush) {
ActionPush push = (ActionPush) action;
for (Object value : push.values) {
if (value instanceof ConstantIndex) {
ConstantIndex constantIndex = (ConstantIndex) value;
if (constantIndex.index == index) {
count++;
}
}
}
}
}
return count;
}
public void inlineConstantPoolString(int index, String str) {
for (Action action : this) {
if (action instanceof ActionPush) {
ActionPush push = (ActionPush) action;
for (int i = 0; i < push.values.size(); i++) {
Object value = push.values.get(i);
if (value instanceof ConstantIndex) {
ConstantIndex constantIndex = (ConstantIndex) value;
if (constantIndex.index == index) {
push.values.set(i, str);
}
}
}
}
}
}
public void removeNops() {
for (int i = 0; i < size(); i++) {
if (get(i) instanceof ActionNop) {

View File

@@ -0,0 +1,34 @@
/*
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
*/
package com.jpexs.decompiler.flash.action;
/**
*
* @author JPEXS
*/
public class ConstantPoolTooBigException extends Exception {
public int index;
public int size;
public ConstantPoolTooBigException(int index, int size) {
super("Constant pool too big. index=" + index + ", size=" + size);
this.index = index;
this.size = size;
}
}

View File

@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.importers;
import com.jpexs.decompiler.flash.action.ConstantPoolTooBigException;
import com.jpexs.decompiler.flash.action.parser.ActionParseException;
import com.jpexs.decompiler.flash.action.parser.pcode.ASMParser;
import com.jpexs.decompiler.flash.action.parser.script.ActionScript2Parser;
@@ -116,7 +117,11 @@ public class AS2ScriptImporter {
if (new File(fileName).exists()) {
String txt = Helper.readTextFile(fileName);
asm.setConstantPools(Helper.getConstantPoolsFromText(txt));
try {
asm.setConstantPools(Helper.getConstantPoolsFromText(txt));
} catch (ConstantPoolTooBigException ex) {
logger.log(Level.SEVERE, null, ex);
}
asm.setModified();
importCount++;
}

View File

@@ -23,6 +23,7 @@ import com.jpexs.decompiler.flash.SWFOutputStream;
import com.jpexs.decompiler.flash.action.Action;
import com.jpexs.decompiler.flash.action.ActionList;
import com.jpexs.decompiler.flash.action.ActionListReader;
import com.jpexs.decompiler.flash.action.ConstantPoolTooBigException;
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.flash.tags.base.ASMSource;
@@ -212,8 +213,8 @@ public class DefineButtonTag extends ButtonTag implements ASMSource {
}
@Override
public void setConstantPools(List<List<String>> constantPools) {
Action.setConstantPools(this, constantPools);
public void setConstantPools(List<List<String>> constantPools) throws ConstantPoolTooBigException {
Action.setConstantPools(this, constantPools, false);
}
@Override

View File

@@ -23,6 +23,7 @@ import com.jpexs.decompiler.flash.SWFOutputStream;
import com.jpexs.decompiler.flash.action.Action;
import com.jpexs.decompiler.flash.action.ActionList;
import com.jpexs.decompiler.flash.action.ActionListReader;
import com.jpexs.decompiler.flash.action.ConstantPoolTooBigException;
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.flash.tags.base.ASMSource;
@@ -165,8 +166,8 @@ public class DoActionTag extends Tag implements ASMSource {
}
@Override
public void setConstantPools(List<List<String>> constantPools) {
Action.setConstantPools(this, constantPools);
public void setConstantPools(List<List<String>> constantPools) throws ConstantPoolTooBigException {
Action.setConstantPools(this, constantPools, false);
}
@Override

View File

@@ -23,6 +23,7 @@ import com.jpexs.decompiler.flash.SWFOutputStream;
import com.jpexs.decompiler.flash.action.Action;
import com.jpexs.decompiler.flash.action.ActionList;
import com.jpexs.decompiler.flash.action.ActionListReader;
import com.jpexs.decompiler.flash.action.ConstantPoolTooBigException;
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.flash.tags.base.ASMSource;
@@ -163,8 +164,8 @@ public class DoInitActionTag extends Tag implements CharacterIdTag, ASMSource {
}
@Override
public void setConstantPools(List<List<String>> constantPools) {
Action.setConstantPools(this, constantPools);
public void setConstantPools(List<List<String>> constantPools) throws ConstantPoolTooBigException {
Action.setConstantPools(this, constantPools, false);
}
@Override

View File

@@ -19,6 +19,7 @@ package com.jpexs.decompiler.flash.tags.base;
import com.jpexs.decompiler.flash.DisassemblyListener;
import com.jpexs.decompiler.flash.action.Action;
import com.jpexs.decompiler.flash.action.ActionList;
import com.jpexs.decompiler.flash.action.ConstantPoolTooBigException;
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.flash.tags.Tag;
@@ -70,7 +71,7 @@ public interface ASMSource extends Exportable {
public void setActionBytes(byte[] actionBytes);
public void setConstantPools(List<List<String>> constantPools);
public void setConstantPools(List<List<String>> constantPools) throws ConstantPoolTooBigException;
public GraphTextWriter getActionBytesAsHex(GraphTextWriter writer);

View File

@@ -22,6 +22,7 @@ import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.action.Action;
import com.jpexs.decompiler.flash.action.ActionList;
import com.jpexs.decompiler.flash.action.ActionListReader;
import com.jpexs.decompiler.flash.action.ConstantPoolTooBigException;
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.flash.tags.Tag;
@@ -240,8 +241,8 @@ public class BUTTONCONDACTION implements ASMSource, Serializable {
}
@Override
public void setConstantPools(List<List<String>> constantPools) {
Action.setConstantPools(this, constantPools);
public void setConstantPools(List<List<String>> constantPools) throws ConstantPoolTooBigException {
Action.setConstantPools(this, constantPools, false);
}
@Override

View File

@@ -22,6 +22,7 @@ import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.action.Action;
import com.jpexs.decompiler.flash.action.ActionList;
import com.jpexs.decompiler.flash.action.ActionListReader;
import com.jpexs.decompiler.flash.action.ConstantPoolTooBigException;
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.flash.tags.Tag;
@@ -226,8 +227,8 @@ public class CLIPACTIONRECORD implements ASMSource, Serializable {
}
@Override
public void setConstantPools(List<List<String>> constantPools) {
Action.setConstantPools(this, constantPools);
public void setConstantPools(List<List<String>> constantPools) throws ConstantPoolTooBigException {
Action.setConstantPools(this, constantPools, false);
}
@Override