Initial support of non-local return in IR
This commit is contained in:
@@ -268,7 +268,7 @@ internal fun getMarkedReturnLabelOrNull(returnInsn: AbstractInsnNode): String? {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun generateGlobalReturnFlag(iv: InstructionAdapter, labelName: String) {
|
fun generateGlobalReturnFlag(iv: InstructionAdapter, labelName: String) {
|
||||||
iv.invokestatic(NON_LOCAL_RETURN, labelName, "()V", false)
|
iv.invokestatic(NON_LOCAL_RETURN, labelName, "()V", false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+30
-8
@@ -16,10 +16,7 @@ import org.jetbrains.kotlin.codegen.*
|
|||||||
import org.jetbrains.kotlin.codegen.AsmUtil.*
|
import org.jetbrains.kotlin.codegen.AsmUtil.*
|
||||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen.putReifiedOperationMarkerIfTypeIsReifiedParameter
|
import org.jetbrains.kotlin.codegen.ExpressionCodegen.putReifiedOperationMarkerIfTypeIsReifiedParameter
|
||||||
import org.jetbrains.kotlin.codegen.StackValue.*
|
import org.jetbrains.kotlin.codegen.StackValue.*
|
||||||
import org.jetbrains.kotlin.codegen.inline.NameGenerator
|
import org.jetbrains.kotlin.codegen.inline.*
|
||||||
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.intrinsics.JavaClassProperty
|
import org.jetbrains.kotlin.codegen.intrinsics.JavaClassProperty
|
||||||
import org.jetbrains.kotlin.codegen.pseudoInsns.fakeAlwaysFalseIfeq
|
import org.jetbrains.kotlin.codegen.pseudoInsns.fakeAlwaysFalseIfeq
|
||||||
import org.jetbrains.kotlin.codegen.pseudoInsns.fakeAlwaysTrueIfeq
|
import org.jetbrains.kotlin.codegen.pseudoInsns.fakeAlwaysTrueIfeq
|
||||||
@@ -674,15 +671,40 @@ class ExpressionCodegen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitReturn(expression: IrReturn, data: BlockInfo): StackValue {
|
override fun visitReturn(expression: IrReturn, data: BlockInfo): StackValue {
|
||||||
val value = expression.value.apply {
|
val owner = expression.returnTargetSymbol.owner
|
||||||
gen(this, returnType, data)
|
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()
|
val afterReturnLabel = Label()
|
||||||
generateFinallyBlocksIfNeeded(returnType, afterReturnLabel, data)
|
generateFinallyBlocksIfNeeded(actualReturn, afterReturnLabel, data)
|
||||||
|
|
||||||
expression.markLineNumber(startOffset = true)
|
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.mark(afterReturnLabel)
|
||||||
mv.nop()/*TODO check RESTORE_STACK_IN_TRY_CATCH processor*/
|
mv.nop()/*TODO check RESTORE_STACK_IN_TRY_CATCH processor*/
|
||||||
return expression.onStack
|
return expression.onStack
|
||||||
|
|||||||
+1
-2
@@ -115,8 +115,7 @@ class IrExpressionLambdaImpl(
|
|||||||
) : ExpressionLambda(typeMapper, isCrossInline), IrExpressionLambda {
|
) : ExpressionLambda(typeMapper, isCrossInline), IrExpressionLambda {
|
||||||
|
|
||||||
override fun isReturnFromMe(labelName: String): Boolean {
|
override fun isReturnFromMe(labelName: String): Boolean {
|
||||||
//TODO("not implemented")
|
return false //always false
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override val lambdaClassType: Type = Type.getObjectType("test123")
|
override val lambdaClassType: Type = Type.getObjectType("test123")
|
||||||
|
|||||||
+2
-3
@@ -88,7 +88,7 @@ class IrSourceCompilerForInline(
|
|||||||
asmMethod: Method
|
asmMethod: Method
|
||||||
): SMAPAndMethodNode {
|
): SMAPAndMethodNode {
|
||||||
assert(callableDescriptor == callElement.descriptor.original)
|
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
|
if (!callDefault) irFunction
|
||||||
else {
|
else {
|
||||||
/*TODO: get rid of hack*/
|
/*TODO: get rid of hack*/
|
||||||
@@ -160,8 +160,7 @@ class IrSourceCompilerForInline(
|
|||||||
get() = callElement.descriptor as FunctionDescriptor
|
get() = callElement.descriptor as FunctionDescriptor
|
||||||
|
|
||||||
override fun getContextLabels(): Set<String> {
|
override fun getContextLabels(): Set<String> {
|
||||||
//TODO
|
return setOf(codegen.irFunction.name.asString())
|
||||||
return emptySet()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun initializeInlineFunctionContext(functionDescriptor: FunctionDescriptor) {
|
override fun initializeInlineFunctionContext(functionDescriptor: FunctionDescriptor) {
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
inline fun run2(block: () -> Unit) = block()
|
inline fun run2(block: () -> Unit) = block()
|
||||||
|
|
||||||
class A {
|
class A {
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// FILE: 1.kt
|
// FILE: 1.kt
|
||||||
|
|
||||||
package test
|
package test
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// FILE: 1.kt
|
// FILE: 1.kt
|
||||||
|
|
||||||
package test
|
package test
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// FILE: 1.kt
|
// FILE: 1.kt
|
||||||
|
|
||||||
package test
|
package test
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// FILE: 1.kt
|
// FILE: 1.kt
|
||||||
|
|
||||||
package test
|
package test
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// FILE: 1.kt
|
// FILE: 1.kt
|
||||||
|
|
||||||
package test
|
package test
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// FILE: 1.kt
|
// FILE: 1.kt
|
||||||
|
|
||||||
package test
|
package test
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// FILE: 1.kt
|
// FILE: 1.kt
|
||||||
|
|
||||||
package test
|
package test
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// FILE: 1.kt
|
// FILE: 1.kt
|
||||||
|
|
||||||
package test
|
package test
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// FILE: 1.kt
|
// FILE: 1.kt
|
||||||
|
|
||||||
inline fun foo(f: () -> Unit) {
|
inline fun foo(f: () -> Unit) {
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// FILE: 1.kt
|
// FILE: 1.kt
|
||||||
|
|
||||||
package test
|
package test
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// FILE: 1.kt
|
// FILE: 1.kt
|
||||||
|
|
||||||
package test
|
package test
|
||||||
|
|||||||
Vendored
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// FILE: 1.kt
|
// FILE: 1.kt
|
||||||
|
|
||||||
package test
|
package test
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// FILE: 1.kt
|
// FILE: 1.kt
|
||||||
|
|
||||||
package test
|
package test
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// NO_CHECK_LAMBDA_INLINING
|
// NO_CHECK_LAMBDA_INLINING
|
||||||
// FILE: 1.kt
|
// FILE: 1.kt
|
||||||
|
|
||||||
|
|||||||
Vendored
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// MODULE: lib
|
// MODULE: lib
|
||||||
// FILE: lib.kt
|
// FILE: lib.kt
|
||||||
|
|
||||||
|
|||||||
Vendored
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// FILE: 1.kt
|
// FILE: 1.kt
|
||||||
|
|
||||||
package test
|
package test
|
||||||
|
|||||||
Reference in New Issue
Block a user