JVM_IR: Support inline suspend functions
Only no state-machine version for now.
This commit is contained in:
+3
@@ -54,6 +54,9 @@ internal fun generateStateMachineForNamedFunction(
|
|||||||
element: KtElement
|
element: KtElement
|
||||||
): MethodVisitor {
|
): MethodVisitor {
|
||||||
assert(irFunction.isSuspend)
|
assert(irFunction.isSuspend)
|
||||||
|
assert(continuationClassBuilder != null) {
|
||||||
|
"Class builder for continuation is null"
|
||||||
|
}
|
||||||
val state = classCodegen.state
|
val state = classCodegen.state
|
||||||
val languageVersionSettings = state.languageVersionSettings
|
val languageVersionSettings = state.languageVersionSettings
|
||||||
assert(languageVersionSettings.isReleaseCoroutines()) { "Experimental coroutines are unsupported in JVM_IR backend" }
|
assert(languageVersionSettings.isReleaseCoroutines()) { "Experimental coroutines are unsupported in JVM_IR backend" }
|
||||||
|
|||||||
+10
-4
@@ -56,7 +56,7 @@ open class FunctionCodegen(
|
|||||||
|
|
||||||
if (irFunction.origin != IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER) {
|
if (irFunction.origin != IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER) {
|
||||||
AnnotationCodegen(classCodegen, context, methodVisitor::visitAnnotation).genAnnotations(
|
AnnotationCodegen(classCodegen, context, methodVisitor::visitAnnotation).genAnnotations(
|
||||||
irFunction,
|
functionView,
|
||||||
signature.asmMethod.returnType
|
signature.asmMethod.returnType
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -70,7 +70,7 @@ open class FunctionCodegen(
|
|||||||
//TODO: investigate this case: annotation here is generated twice in lowered function and in interface method overload
|
//TODO: investigate this case: annotation here is generated twice in lowered function and in interface method overload
|
||||||
irFunction.origin == JvmLoweredDeclarationOrigin.GENERATED_SAM_IMPLEMENTATION
|
irFunction.origin == JvmLoweredDeclarationOrigin.GENERATED_SAM_IMPLEMENTATION
|
||||||
) {
|
) {
|
||||||
generateParameterAnnotations(irFunction, methodVisitor, signature, classCodegen, context)
|
generateParameterAnnotations(functionView, methodVisitor, signature, classCodegen, context)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!state.classBuilderMode.generateBodies || flags.and(Opcodes.ACC_ABSTRACT) != 0 || irFunction.isExternal) {
|
if (!state.classBuilderMode.generateBodies || flags.and(Opcodes.ACC_ABSTRACT) != 0 || irFunction.isExternal) {
|
||||||
@@ -82,8 +82,11 @@ open class FunctionCodegen(
|
|||||||
?: context.suspendLambdaToOriginalFunctionMap[irFunction.parent]?.symbol?.descriptor?.psiElement) as? KtElement
|
?: context.suspendLambdaToOriginalFunctionMap[irFunction.parent]?.symbol?.descriptor?.psiElement) as? KtElement
|
||||||
val continuationClassBuilder = context.continuationClassBuilders[irClass]
|
val continuationClassBuilder = context.continuationClassBuilders[irClass]
|
||||||
methodVisitor = when {
|
methodVisitor = when {
|
||||||
// We do not generate continuation and state-machine for synthetic accessors, in a sence, they are tail-call
|
irFunction.isSuspend &&
|
||||||
irFunction.isSuspend && irFunction.origin != JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR ->
|
// We do not generate continuation and state-machine for synthetic accessors, in a sense, they are tail-call
|
||||||
|
!irFunction.isDefault() &&
|
||||||
|
// TODO: We should generate two versions of inline suspend function: one with state-machine and one without
|
||||||
|
!irFunction.isInline ->
|
||||||
generateStateMachineForNamedFunction(
|
generateStateMachineForNamedFunction(
|
||||||
irFunction, classCodegen, methodVisitor, flags, signature, continuationClassBuilder, element!!
|
irFunction, classCodegen, methodVisitor, flags, signature, continuationClassBuilder, element!!
|
||||||
)
|
)
|
||||||
@@ -101,6 +104,9 @@ open class FunctionCodegen(
|
|||||||
return signature
|
return signature
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun IrFunction.isDefault(): Boolean =
|
||||||
|
origin == IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER || origin == JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR
|
||||||
|
|
||||||
private fun calculateMethodFlags(isStatic: Boolean): Int {
|
private fun calculateMethodFlags(isStatic: Boolean): Int {
|
||||||
if (irFunction.origin == IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER) {
|
if (irFunction.origin == IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER) {
|
||||||
return Opcodes.ACC_PUBLIC or Opcodes.ACC_SYNTHETIC.let {
|
return Opcodes.ACC_PUBLIC or Opcodes.ACC_SYNTHETIC.let {
|
||||||
|
|||||||
+2
-2
@@ -94,8 +94,8 @@ class IrSourceCompilerForInline(
|
|||||||
callDefault: Boolean,
|
callDefault: Boolean,
|
||||||
asmMethod: Method
|
asmMethod: Method
|
||||||
): SMAPAndMethodNode {
|
): SMAPAndMethodNode {
|
||||||
assert(callableDescriptor == callElement.descriptor.original)
|
assert(callableDescriptor == callElement.descriptor.original) { "Expected $callableDescriptor got ${callElement.descriptor.original}" }
|
||||||
assert(codegen.lastLineNumber >= 0)
|
assert(codegen.lastLineNumber >= 0) { "lastLineNumber shall be not negative, but is ${codegen.lastLineNumber}" }
|
||||||
|
|
||||||
val irFunction = getFunctionToInline(callElement as IrCall, jvmSignature, callDefault)
|
val irFunction = getFunctionToInline(callElement as IrCall, jvmSignature, callDefault)
|
||||||
return makeInlineNode(irFunction, FakeClassCodegen(irFunction, codegen.classCodegen), CallSiteMarker(codegen.lastLineNumber))
|
return makeInlineNode(irFunction, FakeClassCodegen(irFunction, codegen.classCodegen), CallSiteMarker(codegen.lastLineNumber))
|
||||||
|
|||||||
+2
-1
@@ -385,6 +385,7 @@ private class AddContinuationLowering(private val context: JvmBackendContext) :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Generate two copies of inline suspend functions
|
||||||
private fun markSuspendFunctions(irFile: IrFile, suspendLambdas: Set<IrFunction>): Set<IrFunction> {
|
private fun markSuspendFunctions(irFile: IrFile, suspendLambdas: Set<IrFunction>): Set<IrFunction> {
|
||||||
val result = hashSetOf<IrFunction>()
|
val result = hashSetOf<IrFunction>()
|
||||||
|
|
||||||
@@ -395,7 +396,7 @@ private class AddContinuationLowering(private val context: JvmBackendContext) :
|
|||||||
|
|
||||||
override fun visitFunction(declaration: IrFunction) {
|
override fun visitFunction(declaration: IrFunction) {
|
||||||
super.visitFunction(declaration)
|
super.visitFunction(declaration)
|
||||||
if (declaration.isSuspend && declaration !in suspendLambdas) {
|
if (declaration.isSuspend && declaration !in suspendLambdas && !declaration.isInline) {
|
||||||
result.add(declaration)
|
result.add(declaration)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
-1
@@ -1,5 +1,4 @@
|
|||||||
// IGNORE_BACKEND: NATIVE
|
// IGNORE_BACKEND: NATIVE
|
||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// WITH_REFLECT
|
// WITH_REFLECT
|
||||||
// WITH_COROUTINES
|
// WITH_COROUTINES
|
||||||
|
|
||||||
|
|||||||
-1
@@ -1,5 +1,4 @@
|
|||||||
// KJS_WITH_FULL_RUNTIME
|
// KJS_WITH_FULL_RUNTIME
|
||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
// WITH_COROUTINES
|
// WITH_COROUTINES
|
||||||
// COMMON_COROUTINES_TEST
|
// COMMON_COROUTINES_TEST
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
// WITH_COROUTINES
|
// WITH_COROUTINES
|
||||||
// COMMON_COROUTINES_TEST
|
// COMMON_COROUTINES_TEST
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
// WITH_COROUTINES
|
// WITH_COROUTINES
|
||||||
// COMMON_COROUTINES_TEST
|
// COMMON_COROUTINES_TEST
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
// WITH_COROUTINES
|
// WITH_COROUTINES
|
||||||
// COMMON_COROUTINES_TEST
|
// COMMON_COROUTINES_TEST
|
||||||
|
|||||||
+2
-3
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
// WITH_COROUTINES
|
// WITH_COROUTINES
|
||||||
// COMMON_COROUTINES_TEST
|
// COMMON_COROUTINES_TEST
|
||||||
@@ -20,8 +19,8 @@ fun box(): String {
|
|||||||
var result = ""
|
var result = ""
|
||||||
|
|
||||||
builder {
|
builder {
|
||||||
result = try { suspendInlineThrow("OK") } catch (e: RuntimeException) { e.message!! }
|
result = try { suspendInlineThrow("O") } catch (e: RuntimeException) { e.message!! }
|
||||||
// result = suspendInline("OK")
|
result += suspendInline("K")
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
// !LANGUAGE: +NewInference
|
// !LANGUAGE: +NewInference
|
||||||
// IGNORE_BACKEND: JVM_IR, NATIVE
|
// IGNORE_BACKEND: NATIVE
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
// WITH_COROUTINES
|
// WITH_COROUTINES
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// WITH_COROUTINES
|
// WITH_COROUTINES
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
// COMMON_COROUTINES_TEST
|
// COMMON_COROUTINES_TEST
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// IGNORE_BACKEND: NATIVE
|
// IGNORE_BACKEND: NATIVE
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
// WITH_COROUTINES
|
// WITH_COROUTINES
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
// WITH_COROUTINES
|
// WITH_COROUTINES
|
||||||
// COMMON_COROUTINES_TEST
|
// COMMON_COROUTINES_TEST
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
// WITH_COROUTINES
|
// WITH_COROUTINES
|
||||||
// COMMON_COROUTINES_TEST
|
// COMMON_COROUTINES_TEST
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// TARGET_BACKEND: JVM
|
// TARGET_BACKEND: JVM
|
||||||
// FULL_JDK
|
// FULL_JDK
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// IGNORE_BACKEND_MULTI_MODULE: JVM_IR
|
// IGNORE_BACKEND_MULTI_MODULE: JVM_IR
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
// WITH_COROUTINES
|
// WITH_COROUTINES
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// IGNORE_BACKEND_MULTI_MODULE: JVM_IR
|
// IGNORE_BACKEND_MULTI_MODULE: JVM_IR
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
// WITH_COROUTINES
|
// WITH_COROUTINES
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// IGNORE_BACKEND_MULTI_MODULE: JVM_IR
|
// IGNORE_BACKEND_MULTI_MODULE: JVM_IR
|
||||||
// FILE: inline.kt
|
// FILE: inline.kt
|
||||||
// COMMON_COROUTINES_TEST
|
// COMMON_COROUTINES_TEST
|
||||||
|
|||||||
Reference in New Issue
Block a user