Fixed: #1627 Previously decompiled scripts not cached

Fixed: SWF is not garbage collected on close in some situations
Fixed: AS1/2 script search does not show all results
This commit is contained in:
Jindra Petřík
2021-03-05 21:22:55 +01:00
parent e308c00601
commit 28380d1d34
12 changed files with 131 additions and 22 deletions
@@ -36,6 +36,7 @@ import com.jpexs.decompiler.flash.abc.avm2.model.StringAVM2Item;
import com.jpexs.decompiler.flash.abc.types.ConvertData;
import com.jpexs.decompiler.flash.abc.types.MethodBody;
import com.jpexs.decompiler.flash.abc.types.Multiname;
import com.jpexs.decompiler.flash.abc.types.ScriptInfo;
import com.jpexs.decompiler.flash.abc.types.traits.Trait;
import com.jpexs.decompiler.flash.abc.types.traits.TraitClass;
import com.jpexs.decompiler.flash.abc.types.traits.TraitMethodGetterSetter;
@@ -348,6 +349,12 @@ public final class SWF implements SWFContainerItem, Timelined {
@Internal
public final AS3Cache as3Cache = new AS3Cache();
@Internal
private Map<String, ASMSource> asmsCacheExportFilenames;
@Internal
private Map<String, ASMSource> asmsCache;
private static final DecompilerPool decompilerPool = new DecompilerPool();
public static final String AS2_PKG_PREFIX = "__Packages.";
@@ -375,6 +382,7 @@ public final class SWF implements SWFContainerItem, Timelined {
DefineSpriteTag spriteTag = (DefineSpriteTag) tag;
for (Tag tag1 : spriteTag.getTags()) {
tag1.setSwf(null);
tag1.setTimelined(null);
}
for (int i = spriteTag.getTags().size() - 1; i >= 0; i--) {
@@ -390,10 +398,15 @@ public final class SWF implements SWFContainerItem, Timelined {
}
tag.setSwf(null);
tag.setTimelined(null);
}
tags.clear();
if (abcList != null) {
for (ABCContainerTag c : abcList) {
c.getABC().free();
}
abcList.clear();
}
@@ -401,8 +414,7 @@ public final class SWF implements SWFContainerItem, Timelined {
swfList.swfs.clear();
}
as2Cache.clear();
as3Cache.clear();
clearScriptCache();
frameCache.clear();
soundCache.clear();
@@ -1703,11 +1715,25 @@ public final class SWF implements SWFContainerItem, Timelined {
}
public Map<String, ASMSource> getASMs(boolean exportFileNames, List<TreeItem> nodesToExport, boolean exportAll) {
if (exportAll) {
if (exportFileNames && asmsCacheExportFilenames != null) {
return asmsCacheExportFilenames;
}
if (!exportFileNames && asmsCache != null) {
return asmsCache;
}
}
Map<String, ASMSource> asmsToExport = new LinkedHashMap<>();
for (TreeItem treeItem : getFirstLevelASMNodes(null)) {
getASMs(exportFileNames, treeItem, nodesToExport, exportAll, asmsToExport, File.separator + getASMPath(exportFileNames, treeItem));
}
if (exportAll) {
if (exportFileNames) {
asmsCacheExportFilenames = asmsToExport;
} else {
asmsCache = asmsToExport;
}
}
return asmsToExport;
}
@@ -2567,6 +2593,13 @@ public final class SWF implements SWFContainerItem, Timelined {
public void clearScriptCache() {
as2Cache.clear();
as3Cache.clear();
if (abcList != null) {
for (ABCContainerTag c : abcList) {
c.getABC().clearPacksCache();
}
}
asmsCache = null;
asmsCacheExportFilenames = null;
IdentifiersDeobfuscation.clearCache();
}
@@ -3003,15 +3036,15 @@ public final class SWF implements SWFContainerItem, Timelined {
timelined.setModified(true);
timelined.resetTimeline();
} else // timeline should be always the swf here
if (removeDependencies) {
removeTagWithDependenciesFromTimeline(tag, timelined.getTimeline());
if (removeDependencies) {
removeTagWithDependenciesFromTimeline(tag, timelined.getTimeline());
timelined.setModified(true);
} else {
boolean modified = removeTagFromTimeline(tag, timelined.getTimeline());
if (modified) {
timelined.setModified(true);
} else {
boolean modified = removeTagFromTimeline(tag, timelined.getTimeline());
if (modified) {
timelined.setModified(true);
}
}
}
}
@Override
@@ -2092,4 +2092,15 @@ public class ABC {
}
return null;
}
public void clearPacksCache() {
for (ScriptInfo si : script_info) {
si.clearPacksCache();
}
}
public void free() {
deobfuscation = null;
abcMethodIndexing = null;
}
}
@@ -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.types;
import com.jpexs.decompiler.flash.abc.ABC;
@@ -57,7 +58,16 @@ public class ScriptInfo {
this.traits = traits;
}
private List<ScriptPack> cachedPacks;
public void clearPacksCache() {
cachedPacks = null;
}
public List<ScriptPack> getPacks(ABC abc, int scriptIndex, String packagePrefix, List<ABC> allAbcs) {
if (packagePrefix == null && cachedPacks != null) {
return new ArrayList<>(cachedPacks);
}
List<ScriptPack> ret = new ArrayList<>();
List<Integer> otherTraits = new ArrayList<>();
@@ -114,6 +124,9 @@ public class ScriptInfo {
ret.add(new ScriptPack(cp, abc, allAbcs, scriptIndex, traitIndices));
}
}
if (packagePrefix == null) {
cachedPacks = new ArrayList<>(ret);
}
return ret;
}
@@ -134,5 +147,8 @@ public class ScriptInfo {
deleted = d;
abc.method_info.get(init_index).delete(abc, d);
traits.delete(abc, d);
if (d) {
clearPacksCache();
}
}
}
@@ -100,13 +100,21 @@ public class ActionScriptSearch {
futures.add(text);
}
for (Future<HighlightedText> future : futures) {
try {
future.get();
} catch (CancellationException ex) {
throw new InterruptedException();
} catch (ExecutionException ex) {
Logger.getLogger(ActionScriptSearch.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
} catch (InterruptedException ex) {
for (Future<HighlightedText> future : futures) {
future.cancel(true);
}
}
return found;
}