Split exception table on finally insertion before non-local return

in nested try blocks without finally

 #KT-31653 Fixed
This commit is contained in:
Mikhael Bogdanov
2019-06-12 14:11:02 +02:00
parent c335015c05
commit 26032e4297
14 changed files with 368 additions and 20 deletions
@@ -64,7 +64,12 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor {
}
}
public static void processInlineFunFinallyBlocks(@NotNull MethodNode inlineFun, int lambdaTryCatchBlockNodes, int finallyParamOffset) {
public static void processInlineFunFinallyBlocks(
@NotNull MethodNode inlineFun,
int lambdaTryCatchBlockNodes,
int finallyParamOffset,
boolean properFinallySplit
) {
int index = 0;
List<TryCatchBlockNodeInfo> inlineFunTryBlockInfo = new ArrayList<>();
for (TryCatchBlockNode block : inlineFun.tryCatchBlocks) {
@@ -77,13 +82,14 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor {
}
if (hasFinallyBlocks(inlineFunTryBlockInfo)) {
new InternalFinallyBlockInliner(inlineFun, inlineFunTryBlockInfo, localVars, finallyParamOffset)
new InternalFinallyBlockInliner(inlineFun, inlineFunTryBlockInfo, localVars, finallyParamOffset, properFinallySplit)
.processInlineFunFinallyBlocks();
}
}
@NotNull
private final MethodNode inlineFun;
private final boolean properFinallySplit;
//lambdaTryCatchBlockNodes is number of TryCatchBlockNodes that was inlined with lambdas into function
@@ -92,10 +98,12 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor {
@NotNull MethodNode inlineFun,
@NotNull List<TryCatchBlockNodeInfo> inlineFunTryBlockInfo,
@NotNull List<LocalVarNodeWrapper> localVariableInfo,
int finallyParamOffset
int finallyParamOffset,
boolean properFinallySplit
) {
super(finallyParamOffset);
this.inlineFun = inlineFun;
this.properFinallySplit = properFinallySplit;
for (TryCatchBlockNodeInfo block : inlineFunTryBlockInfo) {
getTryBlocksMetaInfo().addNewInterval(block);
}
@@ -162,7 +170,7 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor {
checkClusterInvariant(clustersFromInnermost);
int originalDepthIndex = 0;
List<TryCatchBlockNodeInfo> nestedUnsplitBlocksWithoutFinally = new ArrayList();
while (tryCatchBlockIterator.hasNext()) {
TryBlockCluster<TryCatchBlockNodeInfo> clusterToFindFinally = tryCatchBlockIterator.next();
List<TryCatchBlockNodeInfo> clusterBlocks = clusterToFindFinally.getBlocks();
@@ -170,7 +178,10 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor {
FinallyBlockInfo finallyInfo =
findFinallyBlockBody(nodeWithDefaultHandlerIfExists, getTryBlocksMetaInfo().getAllIntervals());
if (finallyInfo == null) continue;
if (finallyInfo == null) {
nestedUnsplitBlocksWithoutFinally.addAll(clusterToFindFinally.getBlocks());
continue;
}
if (nodeWithDefaultHandlerIfExists.getOnlyCopyNotProcess()) {
//lambdas finally generated before non-local return instruction,
@@ -220,8 +231,13 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor {
//Copying finally body before non-local return instruction
insertNodeBefore(finallyBlockCopy, inlineFun, instrInsertFinallyBefore);
updateExceptionTable(clusterBlocks, newFinallyStart, newFinallyEnd,
tryCatchBlockInlinedInFinally, labelsInsideFinally, (LabelNode) insertedBlockEnd.info);
nestedUnsplitBlocksWithoutFinally.addAll(clusterBlocks);
updateExceptionTable(
properFinallySplit ? nestedUnsplitBlocksWithoutFinally : clusterBlocks, newFinallyStart, newFinallyEnd,
tryCatchBlockInlinedInFinally, labelsInsideFinally, (LabelNode) insertedBlockEnd.info
);
nestedUnsplitBlocksWithoutFinally.clear();
}
//skip just inserted finally
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.codegen.optimization.common.*
import org.jetbrains.kotlin.codegen.optimization.fixStack.peek
import org.jetbrains.kotlin.codegen.optimization.fixStack.top
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.ParameterDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
@@ -123,7 +124,8 @@ class MethodInliner(
if (inliningContext.isRoot) {
val remapValue = remapper.remap(parameters.argsSizeOnStack + 1).value
InternalFinallyBlockInliner.processInlineFunFinallyBlocks(
resultNode, lambdasFinallyBlocks, (remapValue as StackValue.Local).index
resultNode, lambdasFinallyBlocks, (remapValue as StackValue.Local).index,
languageVersionSettings.supportsFeature(LanguageFeature.ProperFinally)
)
}