JVM IR: Remove usages of PSI in coroutines codegen

Instead, use IR based reporter.
This commit is contained in:
Ilmir Usmanov
2023-01-10 23:43:20 +01:00
committed by Space Team
parent dfeabea0ab
commit c7bc439661
2 changed files with 19 additions and 28 deletions
@@ -5,14 +5,12 @@
package org.jetbrains.kotlin.backend.jvm.codegen package org.jetbrains.kotlin.backend.jvm.codegen
import org.jetbrains.kotlin.backend.common.CodegenUtil
import org.jetbrains.kotlin.backend.jvm.InlineClassAbi import org.jetbrains.kotlin.backend.jvm.InlineClassAbi
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.ir.* import org.jetbrains.kotlin.backend.jvm.ir.*
import org.jetbrains.kotlin.backend.jvm.unboxInlineClass import org.jetbrains.kotlin.backend.jvm.unboxInlineClass
import org.jetbrains.kotlin.codegen.ClassBuilder import org.jetbrains.kotlin.codegen.ClassBuilder
import org.jetbrains.kotlin.codegen.coroutines.CoroutineTransformerMethodVisitor import org.jetbrains.kotlin.codegen.coroutines.CoroutineTransformerMethodVisitor
import org.jetbrains.kotlin.codegen.coroutines.reportSuspensionPointInsideMonitor
import org.jetbrains.kotlin.config.JVMConfigurationKeys import org.jetbrains.kotlin.config.JVMConfigurationKeys
import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
@@ -21,11 +19,8 @@ import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrGetValue import org.jetbrains.kotlin.ir.expressions.IrGetValue
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.allOverridden import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.util.file import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmBackendErrors
import org.jetbrains.kotlin.ir.util.isSuspend
import org.jetbrains.kotlin.ir.util.parentAsClass
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.org.objectweb.asm.MethodVisitor import org.jetbrains.org.objectweb.asm.MethodVisitor
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.tree.MethodNode import org.jetbrains.org.objectweb.asm.tree.MethodNode
@@ -41,24 +36,17 @@ internal fun MethodNode.acceptWithStateMachine(
val state = context.state val state = context.state
val languageVersionSettings = state.languageVersionSettings val languageVersionSettings = state.languageVersionSettings
assert(languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines)) { "Experimental coroutines are unsupported in JVM_IR backend" } assert(languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines)) { "Experimental coroutines are unsupported in JVM_IR backend" }
val element = if (irFunction.isSuspend)
irFunction.psiElement ?: classCodegen.irClass.psiElement
else
context.suspendLambdaToOriginalFunctionMap[classCodegen.irClass.attributeOwnerId]!!.psiElement
val lineNumber = if (irFunction.isSuspend) { val lineNumber = if (irFunction.startOffset >= 0) {
val irFile = irFunction.file // if it suspend function like `suspend fun foo(...)`
if (irFunction.startOffset >= 0) { irFunction.file.fileEntry.getLineNumber(irFunction.startOffset) + 1
// if it suspend function like `suspend fun foo(...)` } else {
irFile.fileEntry.getLineNumber(irFunction.startOffset) + 1 val klass = classCodegen.irClass
} else { if (klass.startOffset >= 0) {
val klass = classCodegen.irClass // if it suspend lambda transformed into class `runSuspend { .... }`
if (klass.startOffset >= 0) { irFunction.file.fileEntry.getLineNumber(klass.startOffset) + 1
// if it suspend lambda transformed into class `runSuspend { .... }` } else error("Cannot determine lineNumber of element ${irFunction.render()}")
irFile.fileEntry.getLineNumber(klass.startOffset) + 1 }
} else 0
}
} else element?.let { CodegenUtil.getLineNumberForElement(it, false) } ?: 0
val visitor = CoroutineTransformerMethodVisitor( val visitor = CoroutineTransformerMethodVisitor(
methodVisitor, access, name, desc, signature, exceptions.toTypedArray(), methodVisitor, access, name, desc, signature, exceptions.toTypedArray(),
@@ -68,7 +56,10 @@ internal fun MethodNode.acceptWithStateMachine(
disableTailCallOptimizationForFunctionReturningUnit = irFunction.isSuspend && irFunction.suspendFunctionOriginal().let { disableTailCallOptimizationForFunctionReturningUnit = irFunction.isSuspend && irFunction.suspendFunctionOriginal().let {
it.returnType.isUnit() && it.anyOfOverriddenFunctionsReturnsNonUnit() it.returnType.isUnit() && it.anyOfOverriddenFunctionsReturnsNonUnit()
}, },
reportSuspensionPointInsideMonitor = { reportSuspensionPointInsideMonitor(element as KtElement, state, it) }, reportSuspensionPointInsideMonitor = {
classCodegen.context.ktDiagnosticReporter.at(irFunction, classCodegen.irClass)
.report(JvmBackendErrors.SUSPENSION_POINT_INSIDE_MONITOR, it)
},
lineNumber = lineNumber, lineNumber = lineNumber,
sourceFile = classCodegen.irClass.file.name, // SuspendLambda.invokeSuspend is not suspend sourceFile = classCodegen.irClass.file.name, // SuspendLambda.invokeSuspend is not suspend
needDispatchReceiver = irFunction.isSuspend && (irFunction.dispatchReceiverParameter != null needDispatchReceiver = irFunction.isSuspend && (irFunction.dispatchReceiverParameter != null
@@ -4,10 +4,10 @@ compiler/testData/compileKotlinAgainstCustomBinaries/suspensionPointInMonitor/so
compiler/testData/compileKotlinAgainstCustomBinaries/suspensionPointInMonitor/source.kt:14:13: error: a suspension point at SourceKt$test$2.invokeSuspend(source.kt:17) is inside a critical section compiler/testData/compileKotlinAgainstCustomBinaries/suspensionPointInMonitor/source.kt:14:13: error: a suspension point at SourceKt$test$2.invokeSuspend(source.kt:17) is inside a critical section
builder { builder {
^ ^
compiler/testData/compileKotlinAgainstCustomBinaries/suspensionPointInMonitor/source.kt:50:34: error: a suspension point at SourceKt$withCrossinline$c$1.invokeSuspend(source.kt:52) is inside a critical section
val c : suspend () -> Unit = {
^
compiler/testData/compileKotlinAgainstCustomBinaries/suspensionPointInMonitor/source.kt:49:1: error: a suspension point at SourceKt$test$3$invokeSuspend$$inlined$withCrossinline$2.invokeSuspend(source.kt:60) is inside a critical section compiler/testData/compileKotlinAgainstCustomBinaries/suspensionPointInMonitor/source.kt:49:1: error: a suspension point at SourceKt$test$3$invokeSuspend$$inlined$withCrossinline$2.invokeSuspend(source.kt:60) is inside a critical section
inline fun withCrossinline(crossinline a: suspend () -> Unit): suspend () -> Unit { inline fun withCrossinline(crossinline a: suspend () -> Unit): suspend () -> Unit {
^ ^
compiler/testData/compileKotlinAgainstCustomBinaries/suspensionPointInMonitor/source.kt:50:34: error: a suspension point at SourceKt$withCrossinline$c$1.invokeSuspend(source.kt:52) is inside a critical section
val c : suspend () -> Unit = {
^
COMPILATION_ERROR COMPILATION_ERROR