From 30aeb8dc0a3687f321e3d793922bf316ab51ffe0 Mon Sep 17 00:00:00 2001 From: Mikhael Bogdanov Date: Thu, 4 Apr 2019 17:08:16 +0200 Subject: [PATCH] Support finally blocks in non-local returns --- .../kotlin/codegen/inline/InlineCodegen.kt | 68 ++++++++++++- .../codegen/inline/SourceCompilerForInline.kt | 96 +++++-------------- .../codegen/inline/inlineCodegenUtils.kt | 14 +-- .../backend/jvm/codegen/ExpressionCodegen.kt | 33 +++++-- .../backend/jvm/codegen/FunctionCodegen.kt | 8 +- .../jvm/codegen/IrSourceCompilerForInline.kt | 28 ++++-- .../tryCatchInExpressions/splitTry.kt | 1 - .../boxInline/nonLocalReturns/kt8948.kt | 1 - .../tryFinally/callSite/callSite.kt | 1 - .../tryFinally/callSite/callSiteComplex.kt | 1 - .../callSite/exceptionTableSplit.kt | 1 - .../callSite/exceptionTableSplitNoReturn.kt | 1 - .../tryFinally/callSite/finallyInFinally.kt | 1 - .../tryFinally/chained/intReturn.kt | 1 - .../tryFinally/chained/intReturnComplex.kt | 1 - .../tryFinally/chained/intReturnComplex2.kt | 1 - .../tryFinally/chained/nestedLambda.kt | 1 - .../tryFinally/declSite/complex.kt | 1 - .../tryFinally/declSite/intReturn.kt | 1 - .../tryFinally/declSite/intReturnComplex.kt | 1 - .../tryFinally/declSite/longReturn.kt | 1 - .../tryFinally/declSite/nested.kt | 1 - .../tryFinally/declSite/returnInTry.kt | 1 - .../declSite/returnInTryAndFinally.kt | 1 - .../tryFinally/declSite/severalInTry.kt | 1 - .../declSite/severalInTryComplex.kt | 1 - .../tryFinally/declSite/voidInlineFun.kt | 1 - .../tryFinally/declSite/voidNonLocal.kt | 1 - .../tryFinally/exceptionTable/forInFinally.kt | 1 - .../exceptionTable/innerAndExternal.kt | 1 - .../exceptionTable/innerAndExternalNested.kt | 1 - .../exceptionTable/innerAndExternalSimple.kt | 1 - .../tryFinally/exceptionTable/nested.kt | 1 - .../exceptionTable/severalCatchClause.kt | 1 - .../tryFinally/exceptionTable/simpleThrow.kt | 1 - .../tryFinally/exceptionTable/synchonized.kt | 1 - .../exceptionTable/throwInFinally.kt | 1 - .../tryFinally/kt20433_void.kt | 1 - .../nonLocalReturns/tryFinally/kt26384_2.kt | 1 - .../nonLocalReturns/tryFinally/kt28546.kt | 1 - .../nonLocalReturns/tryFinally/kt6956.kt | 1 - .../nonLocalReturns/tryFinally/kt7273.kt | 1 - 42 files changed, 146 insertions(+), 137 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.kt index 9171326da2a..7a68d3837f2 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.kt @@ -41,6 +41,7 @@ import org.jetbrains.kotlin.serialization.deserialization.descriptors.Deserializ import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.isFunctionLiteral import org.jetbrains.kotlin.types.expressions.LabelResolver +import org.jetbrains.org.objectweb.asm.Label import org.jetbrains.org.objectweb.asm.Opcodes import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter @@ -279,7 +280,7 @@ abstract class InlineCodegen( val labels = sourceCompiler.getContextLabels() val infos = MethodInliner.processReturns(adapter, ReturnLabelOwner { labels.contains(it) }, true, null) - sourceCompiler.generateAndInsertFinallyBlocks( + generateAndInsertFinallyBlocks( adapter, infos, (remapper.remap(parameters.argsSizeOnStack + 1).value as StackValue.Local).index ) if (!sourceCompiler.isFinallyMarkerRequired()) { @@ -299,6 +300,71 @@ abstract class InlineCodegen( return result } + fun generateAndInsertFinallyBlocks( + intoNode: MethodNode, + insertPoints: List, + offsetForFinallyLocalVar: Int + ) { + if (!sourceCompiler.hasFinallyBlocks()) return + + val extensionPoints = HashMap() + for (insertPoint in insertPoints) { + extensionPoints.put(insertPoint.beforeIns, insertPoint) + } + + val processor = DefaultProcessor(intoNode, offsetForFinallyLocalVar) + + var curFinallyDepth = 0 + var curInstr: AbstractInsnNode? = intoNode.instructions.first + while (curInstr != null) { + processor.processInstruction(curInstr, true) + if (isFinallyStart(curInstr)) { + //TODO depth index calc could be more precise + curFinallyDepth = getConstant(curInstr.previous) + } + + val extension = extensionPoints[curInstr] + if (extension != null) { + val start = Label() + + val finallyNode = createEmptyMethodNode() + finallyNode.visitLabel(start) + + val finallyCodegen = + sourceCompiler.createCodegenForExternalFinallyBlockGenerationOnNonLocalReturn(finallyNode, curFinallyDepth) + + val frameMap = finallyCodegen.frameMap + val mark = frameMap.mark() + var marker = -1 + val intervals = processor.localVarsMetaInfo.currentIntervals + for (interval in intervals) { + marker = Math.max(interval.node.index + 1, marker) + } + while (frameMap.currentSize < Math.max(processor.nextFreeLocalIndex, offsetForFinallyLocalVar + marker)) { + frameMap.enterTemp(Type.INT_TYPE) + } + + sourceCompiler.generateFinallyBlocksIfNeeded(finallyCodegen, extension.returnType, extension.finallyIntervalEnd.label) + + //Exception table for external try/catch/finally blocks will be generated in original codegen after exiting this method + insertNodeBefore(finallyNode, intoNode, curInstr) + + val splitBy = SimpleInterval(start.info as LabelNode, extension.finallyIntervalEnd) + processor.tryBlocksMetaInfo.splitAndRemoveCurrentIntervals(splitBy, true) + + //processor.getLocalVarsMetaInfo().splitAndRemoveIntervalsFromCurrents(splitBy); + + mark.dropTo() + } + + curInstr = curInstr.next + } + + processor.substituteTryBlockNodes(intoNode) + + //processor.substituteLocalVarTable(intoNode); + } + protected abstract fun generateAssertFieldIfNeeded(info: RootInliningContext) private fun isInlinedToInlineFunInKotlinRuntime(): Boolean { diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/SourceCompilerForInline.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/SourceCompilerForInline.kt index fbd6bf45954..14d1ee8127a 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/SourceCompilerForInline.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/SourceCompilerForInline.kt @@ -28,10 +28,7 @@ import org.jetbrains.org.objectweb.asm.MethodVisitor import org.jetbrains.org.objectweb.asm.Opcodes import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.commons.Method -import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode -import org.jetbrains.org.objectweb.asm.tree.LabelNode import org.jetbrains.org.objectweb.asm.tree.MethodNode -import java.util.* import kotlin.properties.Delegates interface SourceCompilerForInline { @@ -64,11 +61,14 @@ interface SourceCompilerForInline { asmMethod: Method ): SMAPAndMethodNode - fun generateAndInsertFinallyBlocks( - intoNode: MethodNode, - insertPoints: List, - offsetForFinallyLocalVar: Int - ) + fun hasFinallyBlocks(): Boolean + + fun createCodegenForExternalFinallyBlockGenerationOnNonLocalReturn( + finallyNode: MethodNode, + curFinallyDepth: Int + ): BaseExpressionCodegen + + fun generateFinallyBlocksIfNeeded(finallyCodegen: BaseExpressionCodegen, returnType: Type, afterReturnLabel: Label) fun isCallInsideSameModuleAsDeclared(functionDescriptor: FunctionDescriptor): Boolean @@ -84,7 +84,8 @@ interface SourceCompilerForInline { } -class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, override val callElement: KtElement) : SourceCompilerForInline { +class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, override val callElement: KtElement) : + SourceCompilerForInline { override val state = codegen.state @@ -314,74 +315,21 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid return SMAPAndMethodNode(node, smap) } - override fun generateAndInsertFinallyBlocks( - intoNode: MethodNode, - insertPoints: List, - offsetForFinallyLocalVar: Int - ) { - if (!codegen.hasFinallyBlocks()) return + override fun hasFinallyBlocks() = codegen.hasFinallyBlocks() - val extensionPoints = HashMap() - for (insertPoint in insertPoints) { - extensionPoints.put(insertPoint.beforeIns, insertPoint) - } - - val processor = DefaultProcessor(intoNode, offsetForFinallyLocalVar) - - var curFinallyDepth = 0 - var curInstr: AbstractInsnNode? = intoNode.instructions.first - while (curInstr != null) { - processor.processInstruction(curInstr, true) - if (isFinallyStart(curInstr)) { - //TODO depth index calc could be more precise - curFinallyDepth = getConstant(curInstr.previous) - } - - val extension = extensionPoints[curInstr] - if (extension != null) { - val start = Label() - - val finallyNode = createEmptyMethodNode() - finallyNode.visitLabel(start) - - val finallyCodegen = ExpressionCodegen( - finallyNode, codegen.frameMap, codegen.returnType, - codegen.getContext(), codegen.state, codegen.parentCodegen - ) - finallyCodegen.addBlockStackElementsForNonLocalReturns(codegen.blockStackElements, curFinallyDepth) - - val frameMap = finallyCodegen.frameMap - val mark = frameMap.mark() - var marker = -1 - val intervals = processor.localVarsMetaInfo.currentIntervals - for (interval in intervals) { - marker = Math.max(interval.node.index + 1, marker) - } - while (frameMap.currentSize < Math.max(processor.nextFreeLocalIndex, offsetForFinallyLocalVar + marker)) { - frameMap.enterTemp(Type.INT_TYPE) - } - - finallyCodegen.generateFinallyBlocksIfNeeded(extension.returnType, null, extension.finallyIntervalEnd.label) - - //Exception table for external try/catch/finally blocks will be generated in original codegen after exiting this method - insertNodeBefore(finallyNode, intoNode, curInstr) - - val splitBy = SimpleInterval(start.info as LabelNode, extension.finallyIntervalEnd) - processor.tryBlocksMetaInfo.splitAndRemoveCurrentIntervals(splitBy, true) - - //processor.getLocalVarsMetaInfo().splitAndRemoveIntervalsFromCurrents(splitBy); - - mark.dropTo() - } - - curInstr = curInstr.next - } - - processor.substituteTryBlockNodes(intoNode) - - //processor.substituteLocalVarTable(intoNode); + override fun generateFinallyBlocksIfNeeded(finallyCodegen: BaseExpressionCodegen, returnType: Type, afterReturnLabel: Label) { + require(finallyCodegen is ExpressionCodegen) + finallyCodegen.generateFinallyBlocksIfNeeded(returnType, null, afterReturnLabel) } + override fun createCodegenForExternalFinallyBlockGenerationOnNonLocalReturn(finallyNode: MethodNode, curFinallyDepth: Int) = + ExpressionCodegen( + finallyNode, codegen.frameMap, codegen.returnType, + codegen.getContext(), codegen.state, codegen.parentCodegen + ).also { + it.addBlockStackElementsForNonLocalReturns(codegen.blockStackElements, curFinallyDepth) + } + override fun isCallInsideSameModuleAsDeclared(functionDescriptor: FunctionDescriptor): Boolean { return JvmCodegenUtil.isCallInsideSameModuleAsDeclared(functionDescriptor, codegen.getContext(), codegen.state.outDirectory) } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/inlineCodegenUtils.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/inlineCodegenUtils.kt index e737e0fecb0..6fb414515f4 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/inlineCodegenUtils.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/inlineCodegenUtils.kt @@ -283,7 +283,7 @@ internal fun getReturnType(opcode: Int): Type { } } -internal fun insertNodeBefore(from: MethodNode, to: MethodNode, beforeNode: AbstractInsnNode) { +fun insertNodeBefore(from: MethodNode, to: MethodNode, beforeNode: AbstractInsnNode) { val iterator = from.instructions.iterator() while (iterator.hasNext()) { val next = iterator.next() @@ -291,7 +291,7 @@ internal fun insertNodeBefore(from: MethodNode, to: MethodNode, beforeNode: Abst } } -internal fun createEmptyMethodNode() = MethodNode(Opcodes.API_VERSION, 0, "fake", "()V", null, null) +fun createEmptyMethodNode() = MethodNode(Opcodes.API_VERSION, 0, "fake", "()V", null, null) internal fun createFakeContinuationMethodNodeForInline(): MethodNode { val methodNode = createEmptyMethodNode() @@ -347,16 +347,16 @@ internal fun buildClassReaderByInternalName(state: GenerationState, internalName return ClassReader(file.contentsToByteArray()) } -internal fun generateFinallyMarker(v: InstructionAdapter, depth: Int, start: Boolean) { +fun generateFinallyMarker(v: InstructionAdapter, depth: Int, start: Boolean) { v.iconst(depth) v.invokestatic(INLINE_MARKER_CLASS_NAME, if (start) INLINE_MARKER_FINALLY_START else INLINE_MARKER_FINALLY_END, "(I)V", false) } -internal fun isFinallyEnd(node: AbstractInsnNode) = isFinallyMarker(node, INLINE_MARKER_FINALLY_END) +fun isFinallyEnd(node: AbstractInsnNode) = isFinallyMarker(node, INLINE_MARKER_FINALLY_END) -internal fun isFinallyStart(node: AbstractInsnNode) = isFinallyMarker(node, INLINE_MARKER_FINALLY_START) +fun isFinallyStart(node: AbstractInsnNode) = isFinallyMarker(node, INLINE_MARKER_FINALLY_START) -internal fun isFinallyMarker(node: AbstractInsnNode?): Boolean = node != null && (isFinallyStart(node) || isFinallyEnd(node)) +fun isFinallyMarker(node: AbstractInsnNode?): Boolean = node != null && (isFinallyStart(node) || isFinallyEnd(node)) private fun isFinallyMarker(node: AbstractInsnNode, name: String): Boolean { if (node !is MethodInsnNode) return false @@ -365,7 +365,7 @@ private fun isFinallyMarker(node: AbstractInsnNode, name: String): Boolean { internal fun isFinallyMarkerRequired(context: MethodContext) = context.isInlineMethodContext || context is InlineLambdaContext -internal fun getConstant(ins: AbstractInsnNode): Int { +fun getConstant(ins: AbstractInsnNode): Int { val opcode = ins.opcode return when (opcode) { in Opcodes.ICONST_0..Opcodes.ICONST_5 -> opcode - Opcodes.ICONST_0 diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt index b2b967ea960..c146a705d74 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt @@ -109,9 +109,12 @@ class ExpressionCodegen( val irFunction: IrFunction, val frame: IrFrameMap, val mv: InstructionAdapter, - val classCodegen: ClassCodegen + val classCodegen: ClassCodegen, + val isInlineLambda: Boolean = false ) : IrElementVisitor, BaseExpressionCodegen { + var finallyDepth = 0 + /*TODO*/ val intrinsics = IrIntrinsicMethods(classCodegen.context.irBuiltIns) @@ -331,7 +334,7 @@ class ExpressionCodegen( } fun generateCall(expression: IrMemberAccessExpression, callable: Callable, data: BlockInfo, isSuperCall: Boolean = false): StackValue { - val callGenerator = getOrCreateCallGenerator(expression, expression.descriptor) + val callGenerator = getOrCreateCallGenerator(expression, expression.descriptor, data) val receiver = expression.dispatchReceiver receiver?.apply { @@ -1123,7 +1126,17 @@ class ExpressionCodegen( private fun genFinallyBlock(tryInfo: TryInfo, tryCatchBlockEnd: Label?, afterJumpLabel: Label?, data: BlockInfo) { assert(tryInfo.gaps.size % 2 == 0) { "Finally block gaps are inconsistent" } tryInfo.gaps.add(markNewLabel()) + finallyDepth++ + if (isFinallyMarkerRequired()) { + generateFinallyMarker(mv, finallyDepth, true) + } gen(tryInfo.tryBlock.finallyExpression!!, data).discard() + + if (isFinallyMarkerRequired()) { + generateFinallyMarker(mv, finallyDepth, false) + } + finallyDepth-- + if (tryCatchBlockEnd != null) { tryInfo.tryBlock.finallyExpression!!.markLineNumber(startOffset = false) mv.goTo(tryCatchBlockEnd) @@ -1131,7 +1144,7 @@ class ExpressionCodegen( tryInfo.gaps.add(afterJumpLabel ?: markNewLabel()) } - private fun generateFinallyBlocksIfNeeded(returnType: Type, afterReturnLabel: Label, data: BlockInfo) { + fun generateFinallyBlocksIfNeeded(returnType: Type, afterReturnLabel: Label, data: BlockInfo) { if (data.hasFinallyBlocks()) { if (Type.VOID_TYPE != returnType) { val returnValIndex = frame.enterTemp(returnType) @@ -1226,7 +1239,8 @@ class ExpressionCodegen( descriptor: CallableDescriptor, element: IrMemberAccessExpression?, typeParameterMappings: TypeParameterMappings?, - isDefaultCompilation: Boolean + isDefaultCompilation: Boolean, + data: BlockInfo ): IrCallGenerator { if (element == null) return IrCallGenerator.DefaultCallGenerator @@ -1240,13 +1254,14 @@ class ExpressionCodegen( return if (isDefaultCompilation) { TODO() } else { - IrInlineCodegen(this, state, original, typeParameterMappings!!, IrSourceCompilerForInline(state, element, this)) + IrInlineCodegen(this, state, original, typeParameterMappings!!, IrSourceCompilerForInline(state, element, this, data)) } } internal fun getOrCreateCallGenerator( memberAccessExpression: IrMemberAccessExpression, - descriptor: CallableDescriptor + descriptor: CallableDescriptor, + data: BlockInfo ): IrCallGenerator { val typeArguments = if (memberAccessExpression.typeArgumentsCount == 0) { @@ -1280,7 +1295,7 @@ class ExpressionCodegen( } } - return getOrCreateCallGenerator(descriptor, memberAccessExpression, mappings, false) + return getOrCreateCallGenerator(descriptor, memberAccessExpression, mappings, false, data) } override val frameMap: IrFrameMap @@ -1311,6 +1326,10 @@ class ExpressionCodegen( override fun markLineNumberAfterInlineIfNeeded() { //TODO } + + fun isFinallyMarkerRequired(): Boolean { + return irFunction.isInline || isInlineLambda + } } fun DefaultCallArgs.generateOnStackIfNeeded(callGenerator: IrCallGenerator, isConstructor: Boolean, codegen: ExpressionCodegen): Boolean { diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/FunctionCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/FunctionCodegen.kt index f2c0f6fcd3a..24d39e0d163 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/FunctionCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/FunctionCodegen.kt @@ -27,7 +27,11 @@ import org.jetbrains.org.objectweb.asm.MethodVisitor import org.jetbrains.org.objectweb.asm.Opcodes import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter -open class FunctionCodegen(private val irFunction: IrFunction, private val classCodegen: ClassCodegen) { +open class FunctionCodegen( + private val irFunction: IrFunction, + private val classCodegen: ClassCodegen, + private val isInlineLambda: Boolean = false +) { val state = classCodegen.state @@ -56,7 +60,7 @@ open class FunctionCodegen(private val irFunction: IrFunction, private val class methodVisitor.visitEnd() } else { val frameMap = createFrameMapWithReceivers(classCodegen.state, irFunction, signature) - ExpressionCodegen(irFunction, frameMap, InstructionAdapter(methodVisitor), classCodegen).generate() + ExpressionCodegen(irFunction, frameMap, InstructionAdapter(methodVisitor), classCodegen, isInlineLambda).generate() } return signature diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrSourceCompilerForInline.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrSourceCompilerForInline.kt index 330bc284124..92ca8281c65 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrSourceCompilerForInline.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrSourceCompilerForInline.kt @@ -18,6 +18,7 @@ package org.jetbrains.kotlin.backend.jvm.codegen import com.intellij.psi.PsiElement import com.intellij.psi.PsiFile +import org.jetbrains.kotlin.codegen.BaseExpressionCodegen import org.jetbrains.kotlin.codegen.ClassBuilder import org.jetbrains.kotlin.codegen.OwnerKind import org.jetbrains.kotlin.codegen.inline.* @@ -37,13 +38,15 @@ import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodGenericSignature import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature import org.jetbrains.org.objectweb.asm.* +import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter import org.jetbrains.org.objectweb.asm.commons.Method import org.jetbrains.org.objectweb.asm.tree.MethodNode class IrSourceCompilerForInline( override val state: GenerationState, override val callElement: IrMemberAccessExpression, - private val codegen: ExpressionCodegen + private val codegen: ExpressionCodegen, + private val data: BlockInfo ) : SourceCompilerForInline { @@ -71,7 +74,7 @@ class IrSourceCompilerForInline( override fun generateLambdaBody(adapter: MethodVisitor, jvmMethodSignature: JvmMethodSignature, lambdaInfo: ExpressionLambda): SMAP { lambdaInfo as? IrExpressionLambdaImpl ?: error("Expecting ir lambda, but $lambdaInfo") - val functionCodegen = object : FunctionCodegen(lambdaInfo.function, codegen.classCodegen) { + val functionCodegen = object : FunctionCodegen(lambdaInfo.function, codegen.classCodegen, true) { override fun createMethod(flags: Int, signature: JvmMethodGenericSignature): MethodVisitor { return adapter } @@ -135,22 +138,27 @@ class IrSourceCompilerForInline( return SMAPAndMethodNode(node!!, SMAP(fakeClassCodegen.getOrCreateSourceMapper().resultMappings)) } - override fun generateAndInsertFinallyBlocks( - intoNode: MethodNode, - insertPoints: List, - offsetForFinallyLocalVar: Int - ) { - //TODO("not implemented") + override fun hasFinallyBlocks() = data.hasFinallyBlocks() + + override fun generateFinallyBlocksIfNeeded(finallyCodegen: BaseExpressionCodegen, returnType: Type, afterReturnLabel: Label) { + require(finallyCodegen is ExpressionCodegen) + finallyCodegen.generateFinallyBlocksIfNeeded(returnType, afterReturnLabel, data) } + override fun createCodegenForExternalFinallyBlockGenerationOnNonLocalReturn(finallyNode: MethodNode, curFinallyDepth: Int) = + ExpressionCodegen( + codegen.irFunction, codegen.frame, InstructionAdapter(finallyNode), codegen.classCodegen, codegen.isInlineLambda + ).also { + it.finallyDepth = curFinallyDepth + } + override fun isCallInsideSameModuleAsDeclared(functionDescriptor: FunctionDescriptor): Boolean { //TODO("not implemented") return true } override fun isFinallyMarkerRequired(): Boolean { - //TODO("not implemented") - return false + return codegen.isFinallyMarkerRequired() } override val compilationContextDescriptor: DeclarationDescriptor diff --git a/compiler/testData/codegen/box/controlStructures/tryCatchInExpressions/splitTry.kt b/compiler/testData/codegen/box/controlStructures/tryCatchInExpressions/splitTry.kt index 25ad2b977d6..c60bde586a1 100644 --- a/compiler/testData/codegen/box/controlStructures/tryCatchInExpressions/splitTry.kt +++ b/compiler/testData/codegen/box/controlStructures/tryCatchInExpressions/splitTry.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR inline fun test(s: () -> Int): Int = try { val i = s() diff --git a/compiler/testData/codegen/boxInline/nonLocalReturns/kt8948.kt b/compiler/testData/codegen/boxInline/nonLocalReturns/kt8948.kt index 7c9f4827d76..a4cffc30e40 100644 --- a/compiler/testData/codegen/boxInline/nonLocalReturns/kt8948.kt +++ b/compiler/testData/codegen/boxInline/nonLocalReturns/kt8948.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // FILE: 1.kt package test diff --git a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/callSite/callSite.kt b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/callSite/callSite.kt index 45070fe6689..0b168a75dbe 100644 --- a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/callSite/callSite.kt +++ b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/callSite/callSite.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // FILE: 1.kt package test diff --git a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/callSite/callSiteComplex.kt b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/callSite/callSiteComplex.kt index a5e563681a9..304d0c1b23b 100644 --- a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/callSite/callSiteComplex.kt +++ b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/callSite/callSiteComplex.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // FILE: 1.kt package test diff --git a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/callSite/exceptionTableSplit.kt b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/callSite/exceptionTableSplit.kt index b0f48b923ae..772ed7e18e3 100644 --- a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/callSite/exceptionTableSplit.kt +++ b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/callSite/exceptionTableSplit.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // FILE: 1.kt // WITH_RUNTIME package test diff --git a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/callSite/exceptionTableSplitNoReturn.kt b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/callSite/exceptionTableSplitNoReturn.kt index 1c0c1042d3d..0144754000f 100644 --- a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/callSite/exceptionTableSplitNoReturn.kt +++ b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/callSite/exceptionTableSplitNoReturn.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // FILE: 1.kt // WITH_RUNTIME package test diff --git a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/callSite/finallyInFinally.kt b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/callSite/finallyInFinally.kt index 090dbc1ab71..32d8b0ebec0 100644 --- a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/callSite/finallyInFinally.kt +++ b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/callSite/finallyInFinally.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // FILE: 1.kt package test diff --git a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/chained/intReturn.kt b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/chained/intReturn.kt index 3a3f521927f..a57aa8087e6 100644 --- a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/chained/intReturn.kt +++ b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/chained/intReturn.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // FILE: 1.kt package test diff --git a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/chained/intReturnComplex.kt b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/chained/intReturnComplex.kt index b3198ede50d..7baefdcce3b 100644 --- a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/chained/intReturnComplex.kt +++ b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/chained/intReturnComplex.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // FILE: 1.kt package test diff --git a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/chained/intReturnComplex2.kt b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/chained/intReturnComplex2.kt index 22388db9ca9..5f930d23e92 100644 --- a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/chained/intReturnComplex2.kt +++ b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/chained/intReturnComplex2.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // FILE: 1.kt package test diff --git a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/chained/nestedLambda.kt b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/chained/nestedLambda.kt index 70c56d63316..c6ad7820683 100644 --- a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/chained/nestedLambda.kt +++ b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/chained/nestedLambda.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // FILE: 1.kt package test diff --git a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/declSite/complex.kt b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/declSite/complex.kt index 70221e97c68..583f141128c 100644 --- a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/declSite/complex.kt +++ b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/declSite/complex.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // FILE: 1.kt package test diff --git a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/declSite/intReturn.kt b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/declSite/intReturn.kt index 8997b59d044..08e00e74ef2 100644 --- a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/declSite/intReturn.kt +++ b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/declSite/intReturn.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // FILE: 1.kt package test diff --git a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/declSite/intReturnComplex.kt b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/declSite/intReturnComplex.kt index bb02a6c7657..4392856e92c 100644 --- a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/declSite/intReturnComplex.kt +++ b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/declSite/intReturnComplex.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // FILE: 1.kt package test diff --git a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/declSite/longReturn.kt b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/declSite/longReturn.kt index b19bad3cbaf..eabc5ffccfc 100644 --- a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/declSite/longReturn.kt +++ b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/declSite/longReturn.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // FILE: 1.kt package test diff --git a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/declSite/nested.kt b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/declSite/nested.kt index 2b2953a052e..d6beb7eaf5c 100644 --- a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/declSite/nested.kt +++ b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/declSite/nested.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // FILE: 1.kt package test diff --git a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/declSite/returnInTry.kt b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/declSite/returnInTry.kt index 90f2ec35d9d..9c81bdedc71 100644 --- a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/declSite/returnInTry.kt +++ b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/declSite/returnInTry.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // FILE: 1.kt package test diff --git a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/declSite/returnInTryAndFinally.kt b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/declSite/returnInTryAndFinally.kt index b4e88b84b53..5e943261554 100644 --- a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/declSite/returnInTryAndFinally.kt +++ b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/declSite/returnInTryAndFinally.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // FILE: 1.kt package test diff --git a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/declSite/severalInTry.kt b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/declSite/severalInTry.kt index 56da977fc43..4dd77538331 100644 --- a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/declSite/severalInTry.kt +++ b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/declSite/severalInTry.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // FILE: 1.kt package test diff --git a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/declSite/severalInTryComplex.kt b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/declSite/severalInTryComplex.kt index 3f0dcb0fec4..49acaa70b09 100644 --- a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/declSite/severalInTryComplex.kt +++ b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/declSite/severalInTryComplex.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // FILE: 1.kt package test diff --git a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/declSite/voidInlineFun.kt b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/declSite/voidInlineFun.kt index 9ec7e17f9f1..924358c4462 100644 --- a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/declSite/voidInlineFun.kt +++ b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/declSite/voidInlineFun.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // FILE: 1.kt package test diff --git a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/declSite/voidNonLocal.kt b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/declSite/voidNonLocal.kt index dfed8897231..3cb24c35d54 100644 --- a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/declSite/voidNonLocal.kt +++ b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/declSite/voidNonLocal.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // FILE: 1.kt package test diff --git a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/exceptionTable/forInFinally.kt b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/exceptionTable/forInFinally.kt index ab9666b28bf..1aba6d9892e 100644 --- a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/exceptionTable/forInFinally.kt +++ b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/exceptionTable/forInFinally.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // FILE: 1.kt package test diff --git a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/exceptionTable/innerAndExternal.kt b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/exceptionTable/innerAndExternal.kt index d473777847d..1458ab657d3 100644 --- a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/exceptionTable/innerAndExternal.kt +++ b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/exceptionTable/innerAndExternal.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // FILE: 1.kt package test diff --git a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/exceptionTable/innerAndExternalNested.kt b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/exceptionTable/innerAndExternalNested.kt index b3bc7f3037d..e97c1169949 100644 --- a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/exceptionTable/innerAndExternalNested.kt +++ b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/exceptionTable/innerAndExternalNested.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // FILE: 1.kt package test diff --git a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/exceptionTable/innerAndExternalSimple.kt b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/exceptionTable/innerAndExternalSimple.kt index 7ebfc86f968..61ba24ab136 100644 --- a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/exceptionTable/innerAndExternalSimple.kt +++ b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/exceptionTable/innerAndExternalSimple.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // FILE: 1.kt package test diff --git a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/exceptionTable/nested.kt b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/exceptionTable/nested.kt index 69f184c7189..e6278519e69 100644 --- a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/exceptionTable/nested.kt +++ b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/exceptionTable/nested.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // FILE: 1.kt package test diff --git a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/exceptionTable/severalCatchClause.kt b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/exceptionTable/severalCatchClause.kt index a64f4b0aa57..ab9be4bd138 100644 --- a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/exceptionTable/severalCatchClause.kt +++ b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/exceptionTable/severalCatchClause.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // FILE: 1.kt package test diff --git a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/exceptionTable/simpleThrow.kt b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/exceptionTable/simpleThrow.kt index fc3a35a42fe..c0c910216b8 100644 --- a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/exceptionTable/simpleThrow.kt +++ b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/exceptionTable/simpleThrow.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // FILE: 1.kt package test diff --git a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/exceptionTable/synchonized.kt b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/exceptionTable/synchonized.kt index e9df12cdcbc..40ecb0de2d4 100644 --- a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/exceptionTable/synchonized.kt +++ b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/exceptionTable/synchonized.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // FILE: 1.kt package test diff --git a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/exceptionTable/throwInFinally.kt b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/exceptionTable/throwInFinally.kt index 6f1ff13d266..5ec79bdf657 100644 --- a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/exceptionTable/throwInFinally.kt +++ b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/exceptionTable/throwInFinally.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // FILE: 1.kt package test diff --git a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/kt20433_void.kt b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/kt20433_void.kt index a522974fa55..c8be6a91d48 100644 --- a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/kt20433_void.kt +++ b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/kt20433_void.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // FILE: 1.kt //WITH_RUNTIME package test diff --git a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/kt26384_2.kt b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/kt26384_2.kt index 586a0bb5ba2..4e363c62c1a 100644 --- a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/kt26384_2.kt +++ b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/kt26384_2.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // NO_CHECK_LAMBDA_INLINING // FILE: 1.kt diff --git a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/kt28546.kt b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/kt28546.kt index 5318e79ce96..ec00c945eed 100644 --- a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/kt28546.kt +++ b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/kt28546.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // NO_CHECK_LAMBDA_INLINING // FILE: 1.kt diff --git a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/kt6956.kt b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/kt6956.kt index 98758c630e1..230950ad26c 100644 --- a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/kt6956.kt +++ b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/kt6956.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // FILE: 1.kt package test diff --git a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/kt7273.kt b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/kt7273.kt index b0307c15596..c5fa8d206bb 100644 --- a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/kt7273.kt +++ b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/kt7273.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // FILE: 1.kt inline fun test(s: () -> R): R {