mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-09-26 13:41:10 +00:00
memory usage optimizations
This commit is contained in:
@@ -48,7 +48,9 @@ public class IdentifiersDeobfuscation {
|
||||
|
||||
public static final String VALID_NEXT_CHARACTERS = VALID_FIRST_CHARACTERS + "\\p{Nl}\\p{Mn}\\p{Mc}\\p{Nd}\\p{Pc}";
|
||||
|
||||
public static final Pattern IDENTIFIER_PATTERN = Pattern.compile("^[" + VALID_FIRST_CHARACTERS + "][" + VALID_NEXT_CHARACTERS + "]*$");
|
||||
private static final Pattern VALID_NAME_PATTERN = Pattern.compile("^[a-zA-Z_\\$][a-zA-Z0-9_\\$]*$");
|
||||
|
||||
private static final Pattern IDENTIFIER_PATTERN = Pattern.compile("^[" + VALID_FIRST_CHARACTERS + "][" + VALID_NEXT_CHARACTERS + "]*$");
|
||||
|
||||
public static final String FOO_CHARACTERS = "bcdfghjklmnpqrstvwz";
|
||||
|
||||
@@ -88,8 +90,9 @@ public class IdentifiersDeobfuscation {
|
||||
return false;
|
||||
}
|
||||
String[] reservedWords = as3 ? reservedWordsAS3 : reservedWordsAS2;
|
||||
s = s.trim();
|
||||
for (String rw : reservedWords) {
|
||||
if (rw.equals(s.trim())) {
|
||||
if (rw.equals(s)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -240,7 +243,7 @@ public class IdentifiersDeobfuscation {
|
||||
}
|
||||
|
||||
// simple fast test
|
||||
if (s.matches("^[a-zA-Z_\\$][a-zA-Z0-9_\\$]*$")) {
|
||||
if (VALID_NAME_PATTERN.matcher(s).matches()) {
|
||||
return true;
|
||||
}
|
||||
// unicode test
|
||||
|
||||
@@ -527,7 +527,7 @@ public class ABC {
|
||||
class_info = new ArrayList<>(class_count);
|
||||
for (int i = 0; i < class_count; i++) {
|
||||
ais.newDumpLevel("class", "class_info");
|
||||
ClassInfo ci = new ClassInfo();
|
||||
ClassInfo ci = new ClassInfo(null); // do not create Traits in constructor
|
||||
ci.cinit_index = ais.readU30("cinit_index");
|
||||
ci.static_traits = ais.readTraits("static_traits");
|
||||
class_info.add(ci);
|
||||
@@ -537,7 +537,7 @@ public class ABC {
|
||||
script_info = new ArrayList<>(script_count);
|
||||
for (int i = 0; i < script_count; i++) {
|
||||
ais.newDumpLevel("script", "script_info");
|
||||
ScriptInfo si = new ScriptInfo();
|
||||
ScriptInfo si = new ScriptInfo(null); // do not create Traits in constructor
|
||||
si.init_index = ais.readU30("init_index");
|
||||
si.traits = ais.readTraits("traits");
|
||||
script_info.add(si);
|
||||
@@ -548,7 +548,7 @@ public class ABC {
|
||||
bodies = new ArrayList<>(bodies_count);
|
||||
for (int i = 0; i < bodies_count; i++) {
|
||||
ais.newDumpLevel("method_body", "method_body_info");
|
||||
MethodBody mb = new MethodBody();
|
||||
MethodBody mb = new MethodBody(null, null, null); // do not create Traits in constructor
|
||||
mb.method_info = ais.readU30("method_info");
|
||||
mb.max_stack = ais.readU30("max_stack");
|
||||
mb.max_regs = ais.readU30("max_regs");
|
||||
|
||||
@@ -50,6 +50,8 @@ public class ABCInputStream implements AutoCloseable {
|
||||
public static final boolean DEBUG_READ = false;
|
||||
|
||||
public DumpInfo dumpInfo;
|
||||
|
||||
private byte[] stringDataBuffer = new byte[256];
|
||||
|
||||
public void startBuffer() {
|
||||
if (bufferOs == null) {
|
||||
@@ -251,7 +253,8 @@ public class ABCInputStream implements AutoCloseable {
|
||||
}
|
||||
|
||||
private long readLong() throws IOException {
|
||||
byte[] readBuffer = safeRead(8);
|
||||
safeRead(8, stringDataBuffer);
|
||||
byte[] readBuffer = stringDataBuffer;
|
||||
return (((long) readBuffer[7] << 56)
|
||||
+ ((long) (readBuffer[6] & 255) << 48)
|
||||
+ ((long) (readBuffer[5] & 255) << 40)
|
||||
@@ -270,12 +273,10 @@ public class ABCInputStream implements AutoCloseable {
|
||||
return ret;
|
||||
}
|
||||
|
||||
private byte[] safeRead(int count) throws IOException {
|
||||
byte[] ret = new byte[count];
|
||||
private void safeRead(int count, byte[] data) throws IOException {
|
||||
for (int i = 0; i < count; i++) {
|
||||
ret[i] = (byte) readInternal();
|
||||
data[i] = (byte) readInternal();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public Namespace readNamespace(String name) throws IOException {
|
||||
@@ -423,8 +424,7 @@ public class ABCInputStream implements AutoCloseable {
|
||||
public Traits readTraits(String name) throws IOException {
|
||||
newDumpLevel(name, "Traits");
|
||||
int count = readU30("count");
|
||||
Traits traits = new Traits();
|
||||
traits.traits = new ArrayList<>();
|
||||
Traits traits = new Traits(count);
|
||||
for (int i = 0; i < count; i++) {
|
||||
traits.traits.add(readTrait("trait"));
|
||||
}
|
||||
@@ -456,7 +456,7 @@ public class ABCInputStream implements AutoCloseable {
|
||||
|
||||
public InstanceInfo readInstanceInfo(String name) throws IOException {
|
||||
newDumpLevel(name, "instance_info");
|
||||
InstanceInfo ret = new InstanceInfo();
|
||||
InstanceInfo ret = new InstanceInfo(null); // do not create Traits in constructor
|
||||
ret.name_index = readU30("name_index");
|
||||
ret.super_index = readU30("super_index");
|
||||
ret.flags = readInternal();
|
||||
@@ -477,8 +477,19 @@ public class ABCInputStream implements AutoCloseable {
|
||||
public String readString(String name) throws IOException {
|
||||
newDumpLevel(name, "String");
|
||||
int length = readU30Internal();
|
||||
byte[] b = safeRead(length);
|
||||
String r = new String(b, Utf8Helper.charset);
|
||||
|
||||
// avoid creating new byte array every time
|
||||
if (stringDataBuffer.length < length) {
|
||||
int newLength = stringDataBuffer.length * 2;
|
||||
while (newLength < length) {
|
||||
newLength *= 2;
|
||||
}
|
||||
|
||||
stringDataBuffer = new byte[newLength];
|
||||
}
|
||||
|
||||
safeRead(length, stringDataBuffer);
|
||||
String r = new String(stringDataBuffer, 0, length, Utf8Helper.charset);
|
||||
endDumpLevel(r);
|
||||
return r;
|
||||
}
|
||||
|
||||
-1
@@ -1619,7 +1619,6 @@ public class AVM2SourceGenerator implements SourceGenerator {
|
||||
MethodBody mbody = new MethodBody();
|
||||
|
||||
if (needsActivation) {
|
||||
mbody.traits = new Traits();
|
||||
int slotId = 1;
|
||||
for (int i = 1; i < slotNames.size(); i++) {
|
||||
TraitSlotConst tsc = new TraitSlotConst();
|
||||
|
||||
@@ -24,10 +24,18 @@ public class ClassInfo {
|
||||
|
||||
public int cinit_index; //MethodInfo - static initializer
|
||||
|
||||
public Traits static_traits = new Traits();
|
||||
public Traits static_traits;
|
||||
|
||||
public boolean deleted;
|
||||
|
||||
public ClassInfo() {
|
||||
static_traits = new Traits();
|
||||
}
|
||||
|
||||
public ClassInfo(Traits traits) {
|
||||
static_traits = traits;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "method_index=" + cinit_index + "\r\n" + static_traits.toString();
|
||||
|
||||
@@ -39,7 +39,7 @@ public class InstanceInfo {
|
||||
|
||||
public int iinit_index; // MethodInfo - constructor
|
||||
|
||||
public Traits instance_traits = new Traits();
|
||||
public Traits instance_traits;
|
||||
|
||||
public static final int CLASS_SEALED = 1; //not dynamic
|
||||
|
||||
@@ -51,6 +51,14 @@ public class InstanceInfo {
|
||||
|
||||
public boolean deleted;
|
||||
|
||||
public InstanceInfo() {
|
||||
instance_traits = new Traits();
|
||||
}
|
||||
|
||||
public InstanceInfo(Traits traits) {
|
||||
instance_traits = traits;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "name_index=" + name_index + " super_index=" + super_index + " flags=" + flags + " protectedNS=" + protectedNS + " interfaces=" + Helper.intArrToString(interfaces) + " method_index=" + iinit_index + "\r\n" + instance_traits.toString();
|
||||
|
||||
@@ -39,17 +39,18 @@ public class MetadataInfo {
|
||||
}
|
||||
|
||||
public String toString(AVM2ConstantPool constants) {
|
||||
String s = "name=" + constants.getString(name_index);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("name=").append(constants.getString(name_index));
|
||||
if (keys.length > 0) {
|
||||
s += "\r\n";
|
||||
sb.append("\r\n");
|
||||
}
|
||||
for (int i = 0; i < keys.length; i++) {
|
||||
if (keys[i] == 0) {
|
||||
s += "\"" + constants.getString(values[i]) + "\"\r\n";
|
||||
sb.append("\"").append(constants.getString(values[i])).append("\"\r\n");
|
||||
} else {
|
||||
s += "\"" + constants.getString(keys[i]) + "\"=\"" + constants.getString(values[i]) + "\"\r\n";
|
||||
sb.append("\"").append(constants.getString(keys[i])).append("\"=\"").append(constants.getString(values[i])).append("\"\r\n");
|
||||
}
|
||||
}
|
||||
return s;
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import com.jpexs.decompiler.flash.abc.types.traits.Traits;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
|
||||
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Internal;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFField;
|
||||
import com.jpexs.decompiler.graph.Graph;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
@@ -64,18 +65,32 @@ public final class MethodBody implements Cloneable {
|
||||
public int max_scope_depth;
|
||||
|
||||
@SWFField
|
||||
private byte[] codeBytes = new byte[0];
|
||||
private byte[] codeBytes;
|
||||
|
||||
private AVM2Code code;
|
||||
|
||||
public ABCException[] exceptions = new ABCException[0];
|
||||
public ABCException[] exceptions;
|
||||
|
||||
public Traits traits = new Traits();
|
||||
public Traits traits;
|
||||
|
||||
@Internal
|
||||
public transient List<GraphTargetItem> convertedItems;
|
||||
|
||||
@Internal
|
||||
public transient Throwable convertException;
|
||||
|
||||
public MethodBody() {
|
||||
this.traits = new Traits();
|
||||
this.codeBytes = new byte[0];
|
||||
this.exceptions = new ABCException[0];
|
||||
}
|
||||
|
||||
public MethodBody(Traits traits, byte[] codeBytes, ABCException[] exceptions) {
|
||||
this.traits = traits;
|
||||
this.codeBytes = codeBytes;
|
||||
this.exceptions = exceptions;
|
||||
}
|
||||
|
||||
public synchronized void setCodeBytes(byte codeBytes[]) {
|
||||
this.codeBytes = codeBytes;
|
||||
this.code = null;
|
||||
|
||||
@@ -280,10 +280,10 @@ public class Multiname {
|
||||
return "";
|
||||
}
|
||||
if (name_index == 0) {
|
||||
return (isAttribute() ? "@*" : "*");
|
||||
return isAttribute() ? "@*" : "*";
|
||||
} else {
|
||||
String name = constants.getString(name_index);
|
||||
if ((fullyQualifiedNames != null) && fullyQualifiedNames.contains(name)) {
|
||||
if (fullyQualifiedNames != null && fullyQualifiedNames.contains(name)) {
|
||||
return getNameWithNamespace(constants, raw);
|
||||
}
|
||||
return (isAttribute() ? "@" : "") + (raw ? name : IdentifiersDeobfuscation.printIdentifier(true, name));
|
||||
|
||||
@@ -32,13 +32,13 @@ public class NamespaceSet {
|
||||
}
|
||||
|
||||
public String toString(AVM2ConstantPool constants) {
|
||||
String s = "";
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < this.namespaces.length; i++) {
|
||||
if (i > 0) {
|
||||
s += ", ";
|
||||
sb.append(", ");
|
||||
}
|
||||
s += constants.getNamespace(namespaces[i]).getNameWithKind(constants);
|
||||
sb.append(constants.getNamespace(namespaces[i]).getNameWithKind(constants));
|
||||
}
|
||||
return s;
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,8 +31,16 @@ public class ScriptInfo {
|
||||
|
||||
public int init_index; //MethodInfo
|
||||
|
||||
public Traits traits = new Traits();
|
||||
public Traits traits;
|
||||
|
||||
public ScriptInfo() {
|
||||
traits = new Traits();
|
||||
}
|
||||
|
||||
public ScriptInfo(Traits traits) {
|
||||
this.traits = traits;
|
||||
}
|
||||
|
||||
public List<MyEntry<ClassPath, ScriptPack>> getPacks(ABC abc, int scriptIndex) {
|
||||
List<MyEntry<ClassPath, ScriptPack>> ret = new ArrayList<>();
|
||||
|
||||
@@ -52,8 +60,8 @@ public class ScriptInfo {
|
||||
Namespace ns = name.getNamespace(abc.constants);
|
||||
if ((ns.kind == Namespace.KIND_PACKAGE_INTERNAL)
|
||||
|| (ns.kind == Namespace.KIND_PACKAGE)) {
|
||||
String packageName = ns.getName(abc.constants, false); //assume not null package
|
||||
String objectName = name.getName(abc.constants, new ArrayList<String>(), false);
|
||||
String packageName = ns.getName(abc.constants, false); // assume not null package
|
||||
String objectName = name.getName(abc.constants, null, false);
|
||||
List<Integer> traitIndices = new ArrayList<>();
|
||||
|
||||
traitIndices.add(j);
|
||||
|
||||
@@ -30,13 +30,15 @@ import java.util.List;
|
||||
|
||||
public abstract class Trait implements Serializable {
|
||||
|
||||
private static final int[] EMPTY_METADATA_ARRAY = new int[0];
|
||||
|
||||
public int name_index;
|
||||
|
||||
public int kindType;
|
||||
|
||||
public int kindFlags;
|
||||
|
||||
public int[] metadata = new int[0];
|
||||
public int[] metadata = EMPTY_METADATA_ARRAY;
|
||||
|
||||
public long fileOffset;
|
||||
|
||||
|
||||
@@ -34,8 +34,16 @@ import java.util.logging.Logger;
|
||||
|
||||
public class Traits implements Serializable {
|
||||
|
||||
public List<Trait> traits = new ArrayList<>();
|
||||
public List<Trait> traits;
|
||||
|
||||
public Traits() {
|
||||
traits = new ArrayList<>();
|
||||
}
|
||||
|
||||
public Traits(int initialCapacity) {
|
||||
traits = new ArrayList<>(initialCapacity);
|
||||
}
|
||||
|
||||
public void delete(ABC abc, boolean d) {
|
||||
for (Trait t : traits) {
|
||||
t.delete(abc, d);
|
||||
|
||||
Reference in New Issue
Block a user