Initial support of non-local return in IR

This commit is contained in:
Mikhael Bogdanov
2019-04-04 14:40:53 +02:00
parent 3f9154a4a1
commit 694a7c329d
21 changed files with 34 additions and 31 deletions
@@ -268,7 +268,7 @@ internal fun getMarkedReturnLabelOrNull(returnInsn: AbstractInsnNode): String? {
return null
}
internal fun generateGlobalReturnFlag(iv: InstructionAdapter, labelName: String) {
fun generateGlobalReturnFlag(iv: InstructionAdapter, labelName: String) {
iv.invokestatic(NON_LOCAL_RETURN, labelName, "()V", false)
}
@@ -16,10 +16,7 @@ import org.jetbrains.kotlin.codegen.*
import org.jetbrains.kotlin.codegen.AsmUtil.*
import org.jetbrains.kotlin.codegen.ExpressionCodegen.putReifiedOperationMarkerIfTypeIsReifiedParameter
import org.jetbrains.kotlin.codegen.StackValue.*
import org.jetbrains.kotlin.codegen.inline.NameGenerator
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeParametersUsages
import org.jetbrains.kotlin.codegen.inline.TypeParameterMappings
import org.jetbrains.kotlin.codegen.inline.*
import org.jetbrains.kotlin.codegen.intrinsics.JavaClassProperty
import org.jetbrains.kotlin.codegen.pseudoInsns.fakeAlwaysFalseIfeq
import org.jetbrains.kotlin.codegen.pseudoInsns.fakeAlwaysTrueIfeq
@@ -674,15 +671,40 @@ class ExpressionCodegen(
}
override fun visitReturn(expression: IrReturn, data: BlockInfo): StackValue {
val value = expression.value.apply {
gen(this, returnType, data)
val owner = expression.returnTargetSymbol.owner
val isNonLocalReturn = owner != irFunction
if (isNonLocalReturn && state.isInlineDisabled) {
//TODO: state.diagnostics.report(Errors.NON_LOCAL_RETURN_IN_DISABLED_INLINE.on(expression))
genThrow(
mv, "java/lang/UnsupportedOperationException",
"Non-local returns are not allowed with inlining disabled"
)
return none()
}
val actualReturn =
if (isNonLocalReturn) {
typeMapper.mapReturnType(owner.descriptor)
} else {
returnType
}
expression.value.apply {
gen(this, actualReturn, data)
}
val afterReturnLabel = Label()
generateFinallyBlocksIfNeeded(returnType, afterReturnLabel, data)
generateFinallyBlocksIfNeeded(actualReturn, afterReturnLabel, data)
expression.markLineNumber(startOffset = true)
mv.areturn(returnType)
if (isNonLocalReturn) {
val nonLocalReturnType = typeMapper.mapReturnType(owner.descriptor)
val labelName = (owner as IrFunction).name.asString()
generateGlobalReturnFlag(mv, labelName)
mv.areturn(nonLocalReturnType)
} else {
mv.areturn(actualReturn)
}
mv.mark(afterReturnLabel)
mv.nop()/*TODO check RESTORE_STACK_IN_TRY_CATCH processor*/
return expression.onStack
@@ -115,8 +115,7 @@ class IrExpressionLambdaImpl(
) : ExpressionLambda(typeMapper, isCrossInline), IrExpressionLambda {
override fun isReturnFromMe(labelName: String): Boolean {
//TODO("not implemented")
return false
return false //always false
}
override val lambdaClassType: Type = Type.getObjectType("test123")
@@ -88,7 +88,7 @@ class IrSourceCompilerForInline(
asmMethod: Method
): SMAPAndMethodNode {
assert(callableDescriptor == callElement.descriptor.original)
val irFunction = ((callElement as IrCall).symbol.owner as IrFunction).let { irFunction ->
val irFunction = (callElement as IrCall).symbol.owner.let { irFunction ->
if (!callDefault) irFunction
else {
/*TODO: get rid of hack*/
@@ -160,8 +160,7 @@ class IrSourceCompilerForInline(
get() = callElement.descriptor as FunctionDescriptor
override fun getContextLabels(): Set<String> {
//TODO
return emptySet()
return setOf(codegen.irFunction.name.asString())
}
override fun initializeInlineFunctionContext(functionDescriptor: FunctionDescriptor) {
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
inline fun run2(block: () -> Unit) = block()
class A {
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// FILE: 1.kt
package test
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// FILE: 1.kt
package test
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// FILE: 1.kt
package test
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// FILE: 1.kt
package test
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// FILE: 1.kt
package test
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// FILE: 1.kt
package test
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// FILE: 1.kt
package test
@@ -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 foo(f: () -> Unit) {
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// FILE: 1.kt
package test
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// FILE: 1.kt
package test
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// FILE: 1.kt
package test
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// FILE: 1.kt
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
// MODULE: lib
// FILE: lib.kt
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// FILE: 1.kt
package test