fix: improve exception handler remove (#703)

This commit is contained in:
Skylot
2019-07-22 18:24:43 +03:00
parent 6b76a3c787
commit 3ae8359408
6 changed files with 50 additions and 8 deletions
@@ -303,13 +303,11 @@ public class MethodNode extends LineAttrNode implements ILoadable, ICodeNode {
// resolve nested try blocks:
// inner block contains all handlers from outer block => remove these handlers from inner block
// each handler must be only in one try/catch block
for (TryCatchBlock ct1 : catches) {
for (TryCatchBlock ct2 : catches) {
if (ct1 != ct2 && ct2.containsAllHandlers(ct1)) {
for (ExceptionHandler h : ct1.getHandlers()) {
ct2.removeHandler(mth, h);
h.setTryBlock(ct1);
}
for (TryCatchBlock outerTry : catches) {
for (TryCatchBlock innerTry : catches) {
if (outerTry != innerTry
&& innerTry.containsAllHandlers(outerTry)) {
innerTry.removeSameHandlers(outerTry);
}
}
}
@@ -522,6 +520,10 @@ public class MethodNode extends LineAttrNode implements ILoadable, ICodeNode {
return handler;
}
public boolean clearExceptionHandlers() {
return exceptionHandlers.removeIf(ExceptionHandler::isRemoved);
}
public Iterable<ExceptionHandler> getExceptionHandlers() {
return exceptionHandlers;
}
@@ -32,6 +32,8 @@ public class ExceptionHandler {
private TryCatchBlock tryBlock;
private boolean isFinally;
private boolean removed = false;
public ExceptionHandler(int addr, @Nullable ClassInfo type) {
this.handleOffset = addr;
addCatchType(type);
@@ -138,6 +140,14 @@ public class ExceptionHandler {
this.isFinally = isFinally;
}
public boolean isRemoved() {
return removed;
}
public void markForRemove() {
this.removed = true;
}
@Override
public boolean equals(Object o) {
if (this == o) {
@@ -52,6 +52,17 @@ public class TryCatchBlock {
return addedHandler;
}
/**
* Use only before BlockSplitter
*/
public void removeSameHandlers(TryCatchBlock outerTry) {
for (ExceptionHandler handler : outerTry.getHandlers()) {
if (handlers.remove(handler)) {
handler.setTryBlock(outerTry);
}
}
}
public void removeHandler(MethodNode mth, ExceptionHandler handler) {
for (Iterator<ExceptionHandler> it = handlers.iterator(); it.hasNext();) {
ExceptionHandler h = it.next();
@@ -78,9 +89,14 @@ public class TryCatchBlock {
}
SplitterBlockAttr splitter = handler.getHandlerBlock().get(AType.SPLITTER_BLOCK);
if (splitter != null) {
splitter.getBlock().remove(AType.SPLITTER_BLOCK);
BlockNode splitterBlock = splitter.getBlock();
splitterBlock.remove(AType.SPLITTER_BLOCK);
for (BlockNode successor : splitterBlock.getSuccessors()) {
successor.remove(AType.SPLITTER_BLOCK);
}
}
}
handler.markForRemove();
}
private void removeWholeBlock(MethodNode mth) {
@@ -43,9 +43,12 @@ public class MarkFinallyVisitor extends AbstractVisitor {
return;
}
try {
mth.clearExceptionHandlers();
for (ExceptionHandler excHandler : mth.getExceptionHandlers()) {
processExceptionHandler(mth, excHandler);
}
mth.clearExceptionHandlers();
} catch (Exception e) {
LOG.warn("Undo finally extract visitor, mth: {}", mth, e);
try {
@@ -69,6 +69,16 @@ public class FileUtils {
}
}
public static boolean deleteDir(File dir) {
File[] content = dir.listFiles();
if (content != null) {
for (File file : content) {
deleteDir(file);
}
}
return dir.delete();
}
private static final Path TEMP_ROOT_DIR = createTempRootDir();
private static Path createTempRootDir() {
@@ -1 +1,2 @@
/ExternalTests.java
/*Tmp.java