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
|
||||
}
|
||||
|
||||
internal fun generateGlobalReturnFlag(iv: InstructionAdapter, labelName: String) {
|
||||
fun generateGlobalReturnFlag(iv: InstructionAdapter, labelName: String) {
|
||||
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.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
|
||||
|
||||
+1
-2
@@ -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")
|
||||
|
||||
+2
-3
@@ -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
@@ -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
|
||||
|
||||
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,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// NO_CHECK_LAMBDA_INLINING
|
||||
// FILE: 1.kt
|
||||
|
||||
|
||||
Vendored
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// MODULE: lib
|
||||
// FILE: lib.kt
|
||||
|
||||
|
||||
Vendored
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// FILE: 1.kt
|
||||
|
||||
package test
|
||||
|
||||
Reference in New Issue
Block a user