JVM: hide ExpressionCodegen in finally block generation during inlining
This commit is contained in:
@@ -68,6 +68,13 @@ open class FrameMapBase<T : Any> {
|
||||
return Mark(currentSize)
|
||||
}
|
||||
|
||||
fun skipTo(target: Int): Mark {
|
||||
return mark().also {
|
||||
if (currentSize < target)
|
||||
currentSize = target
|
||||
}
|
||||
}
|
||||
|
||||
inner class Mark(private val myIndex: Int) {
|
||||
|
||||
fun dropTo() {
|
||||
|
||||
@@ -113,7 +113,7 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
|
||||
|
||||
val infos = MethodInliner.processReturns(adapter, sourceCompiler.getContextLabels(), null)
|
||||
generateAndInsertFinallyBlocks(
|
||||
adapter, infos, (remapper.remap(parameters.argsSizeOnStack + 1).value as StackValue.Local).index
|
||||
adapter, infos, (remapper.remap(parameters.argsSizeOnStack).value as StackValue.Local).index
|
||||
)
|
||||
if (!sourceCompiler.isFinallyMarkerRequired) {
|
||||
removeFinallyMarkers(adapter)
|
||||
@@ -165,37 +165,25 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
|
||||
|
||||
val extension = extensionPoints[curInstr]
|
||||
if (extension != null) {
|
||||
val start = Label()
|
||||
var nextFreeLocalIndex = processor.nextFreeLocalIndex
|
||||
for (local in processor.localVarsMetaInfo.currentIntervals) {
|
||||
val size = Type.getType(local.node.desc).size
|
||||
nextFreeLocalIndex = max(offsetForFinallyLocalVar + local.node.index + size, nextFreeLocalIndex)
|
||||
}
|
||||
|
||||
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 = max(interval.node.index + 1, marker)
|
||||
}
|
||||
while (frameMap.currentSize < max(processor.nextFreeLocalIndex, offsetForFinallyLocalVar + marker)) {
|
||||
frameMap.enterTemp(Type.INT_TYPE)
|
||||
}
|
||||
|
||||
sourceCompiler.generateFinallyBlocksIfNeeded(
|
||||
finallyCodegen, extension.returnType, extension.finallyIntervalEnd.label, extension.jumpTarget
|
||||
val mark = codegen.frameMap.skipTo(nextFreeLocalIndex)
|
||||
sourceCompiler.generateFinallyBlocks(
|
||||
finallyNode, curFinallyDepth, extension.returnType, extension.finallyIntervalEnd.label, extension.jumpTarget
|
||||
)
|
||||
|
||||
//Exception table for external try/catch/finally blocks will be generated in original codegen after exiting this method
|
||||
mark.dropTo()
|
||||
insertNodeBefore(finallyNode, intoNode, curInstr)
|
||||
|
||||
val splitBy = SimpleInterval(start.info as LabelNode, extension.finallyIntervalEnd)
|
||||
processor.tryBlocksMetaInfo.splitAndRemoveCurrentIntervals(splitBy, true)
|
||||
processor.localVarsMetaInfo.splitAndRemoveCurrentIntervals(splitBy, true)
|
||||
|
||||
mark.dropTo()
|
||||
}
|
||||
|
||||
curInstr = curInstr.next
|
||||
|
||||
+3
-7
@@ -295,19 +295,15 @@ class PsiSourceCompilerForInline(
|
||||
|
||||
override fun hasFinallyBlocks() = codegen.hasFinallyBlocks()
|
||||
|
||||
override fun generateFinallyBlocksIfNeeded(codegen: BaseExpressionCodegen, returnType: Type, afterReturnLabel: Label, target: Label?) {
|
||||
override fun generateFinallyBlocks(finallyNode: MethodNode, curFinallyDepth: Int, returnType: Type, afterReturnLabel: Label, target: Label?) {
|
||||
// TODO use the target label for non-local break/continue
|
||||
require(codegen is ExpressionCodegen)
|
||||
codegen.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)
|
||||
}
|
||||
}.generateFinallyBlocksIfNeeded(returnType, null, afterReturnLabel)
|
||||
}
|
||||
|
||||
override val isCallInsideSameModuleAsCallee: Boolean
|
||||
get() = JvmCodegenUtil.isCallInsideSameModuleAsDeclared(functionDescriptor, codegen.getContext(), codegen.state.outDirectory)
|
||||
|
||||
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.codegen.inline
|
||||
|
||||
import com.intellij.psi.PsiFile
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.kotlin.codegen.BaseExpressionCodegen
|
||||
import org.jetbrains.kotlin.codegen.inline.coroutines.FOR_INLINE_SUFFIX
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||
@@ -17,7 +16,6 @@ import org.jetbrains.kotlin.incremental.components.ScopeKind
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.org.objectweb.asm.Label
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.Method
|
||||
@@ -48,12 +46,7 @@ interface SourceCompilerForInline {
|
||||
|
||||
fun hasFinallyBlocks(): Boolean
|
||||
|
||||
fun createCodegenForExternalFinallyBlockGenerationOnNonLocalReturn(
|
||||
finallyNode: MethodNode,
|
||||
curFinallyDepth: Int
|
||||
): BaseExpressionCodegen
|
||||
|
||||
fun generateFinallyBlocksIfNeeded(codegen: BaseExpressionCodegen, returnType: Type, afterReturnLabel: Label, target: Label?)
|
||||
fun generateFinallyBlocks(finallyNode: MethodNode, curFinallyDepth: Int, returnType: Type, afterReturnLabel: Label, target: Label?)
|
||||
|
||||
val isCallInsideSameModuleAsCallee: Boolean
|
||||
|
||||
|
||||
Reference in New Issue
Block a user