Support finally blocks in non-local returns
This commit is contained in:
@@ -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<out T : BaseExpressionCodegen>(
|
||||
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<out T : BaseExpressionCodegen>(
|
||||
return result
|
||||
}
|
||||
|
||||
fun generateAndInsertFinallyBlocks(
|
||||
intoNode: MethodNode,
|
||||
insertPoints: List<MethodInliner.PointForExternalFinallyBlocks>,
|
||||
offsetForFinallyLocalVar: Int
|
||||
) {
|
||||
if (!sourceCompiler.hasFinallyBlocks()) return
|
||||
|
||||
val extensionPoints = HashMap<AbstractInsnNode, MethodInliner.PointForExternalFinallyBlocks>()
|
||||
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 {
|
||||
|
||||
+22
-74
@@ -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<MethodInliner.PointForExternalFinallyBlocks>,
|
||||
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<MethodInliner.PointForExternalFinallyBlocks>,
|
||||
offsetForFinallyLocalVar: Int
|
||||
) {
|
||||
if (!codegen.hasFinallyBlocks()) return
|
||||
override fun hasFinallyBlocks() = codegen.hasFinallyBlocks()
|
||||
|
||||
val extensionPoints = HashMap<AbstractInsnNode, MethodInliner.PointForExternalFinallyBlocks>()
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
+26
-7
@@ -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<StackValue, BlockInfo>, 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 {
|
||||
|
||||
+6
-2
@@ -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
|
||||
|
||||
+18
-10
@@ -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<MethodInliner.PointForExternalFinallyBlocks>,
|
||||
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
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
inline fun test(s: () -> Int): Int =
|
||||
try {
|
||||
val i = s()
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// FILE: 1.kt
|
||||
|
||||
package test
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// FILE: 1.kt
|
||||
|
||||
package test
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// FILE: 1.kt
|
||||
|
||||
package test
|
||||
|
||||
Vendored
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// FILE: 1.kt
|
||||
// WITH_RUNTIME
|
||||
package test
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// FILE: 1.kt
|
||||
// WITH_RUNTIME
|
||||
package test
|
||||
|
||||
Vendored
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// FILE: 1.kt
|
||||
|
||||
package test
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// FILE: 1.kt
|
||||
|
||||
package test
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// FILE: 1.kt
|
||||
|
||||
package test
|
||||
|
||||
Vendored
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// FILE: 1.kt
|
||||
|
||||
package test
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// FILE: 1.kt
|
||||
|
||||
package test
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// FILE: 1.kt
|
||||
|
||||
package test
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// FILE: 1.kt
|
||||
|
||||
package test
|
||||
|
||||
Vendored
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// FILE: 1.kt
|
||||
|
||||
package test
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// FILE: 1.kt
|
||||
|
||||
package test
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// FILE: 1.kt
|
||||
|
||||
package test
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// FILE: 1.kt
|
||||
|
||||
package test
|
||||
|
||||
Vendored
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// FILE: 1.kt
|
||||
|
||||
package test
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// FILE: 1.kt
|
||||
|
||||
package test
|
||||
|
||||
Vendored
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// FILE: 1.kt
|
||||
|
||||
package test
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// FILE: 1.kt
|
||||
|
||||
package test
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// FILE: 1.kt
|
||||
|
||||
package test
|
||||
|
||||
Vendored
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// FILE: 1.kt
|
||||
|
||||
package test
|
||||
|
||||
Vendored
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// FILE: 1.kt
|
||||
|
||||
package test
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// FILE: 1.kt
|
||||
|
||||
package test
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// FILE: 1.kt
|
||||
|
||||
package test
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// FILE: 1.kt
|
||||
|
||||
package test
|
||||
|
||||
Vendored
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// FILE: 1.kt
|
||||
|
||||
package test
|
||||
|
||||
Vendored
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// FILE: 1.kt
|
||||
|
||||
package test
|
||||
|
||||
Vendored
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// FILE: 1.kt
|
||||
|
||||
package test
|
||||
|
||||
Vendored
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// FILE: 1.kt
|
||||
|
||||
package test
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// FILE: 1.kt
|
||||
//WITH_RUNTIME
|
||||
package test
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// NO_CHECK_LAMBDA_INLINING
|
||||
// FILE: 1.kt
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// NO_CHECK_LAMBDA_INLINING
|
||||
// FILE: 1.kt
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// FILE: 1.kt
|
||||
|
||||
package test
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// FILE: 1.kt
|
||||
|
||||
inline fun <R> test(s: () -> R): R {
|
||||
|
||||
Reference in New Issue
Block a user