Split exception table on finally insertion before non-local return
in nested try blocks without finally #KT-31653 Fixed
This commit is contained in:
+23
-7
@@ -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)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user