JVM IR: don't use descriptors to map suspend function types

This commit is contained in:
Alexander Udalov
2019-09-05 09:30:56 +02:00
parent 34d2d7374c
commit d6cb857c97
4 changed files with 23 additions and 14 deletions
@@ -86,9 +86,12 @@ class JvmBackendContext(
val descriptor = state.module.getPackage(fqName.parent()).memberScope.getContributedClassifier(
fqName.shortName(), NoLookupLocation.FROM_BACKEND
) as ClassDescriptor? ?: error("Class is not found: $fqName")
return symbolTable.referenceClass(descriptor)
return referenceClass(descriptor)
}
internal fun referenceClass(descriptor: ClassDescriptor): IrClassSymbol =
symbolTable.referenceClass(descriptor)
override fun log(message: () -> String) {
/*TODO*/
if (inVerbosePhase) {
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.ir.util.fields
import org.jetbrains.kotlin.ir.util.functions
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
import org.jetbrains.kotlin.storage.LockBasedStorageManager
import org.jetbrains.kotlin.types.Variance
@@ -38,6 +39,7 @@ class JvmSymbols(
) : Symbols<JvmBackendContext>(context, symbolTable) {
private val storageManager = LockBasedStorageManager(this::class.java.simpleName)
private val kotlinPackage: IrPackageFragment = createPackage(FqName("kotlin"))
private val kotlinCoroutinesPackage: IrPackageFragment = createPackage(FqName("kotlin.coroutines"))
private val kotlinJvmPackage: IrPackageFragment = createPackage(FqName("kotlin.jvm"))
private val kotlinJvmInternalPackage: IrPackageFragment = createPackage(FqName("kotlin.jvm.internal"))
private val kotlinJvmFunctionsPackage: IrPackageFragment = createPackage(FqName("kotlin.jvm.functions"))
@@ -78,6 +80,7 @@ class JvmSymbols(
}.apply {
parent = when (fqName.parent().asString()) {
"kotlin" -> kotlinPackage
"kotlin.coroutines" -> kotlinCoroutinesPackage
"kotlin.jvm.internal" -> kotlinJvmInternalPackage
"kotlin.jvm.functions" -> kotlinJvmFunctionsPackage
"java.lang" -> javaLangPackage
@@ -154,6 +157,11 @@ class JvmSymbols(
}
}
val continuationClass: IrClassSymbol =
createClass(DescriptorUtils.CONTINUATION_INTERFACE_FQ_NAME_RELEASE, ClassKind.INTERFACE) { klass ->
klass.addTypeParameter("T", irBuiltIns.anyNType, Variance.IN_VARIANCE)
}
val lambdaClass: IrClassSymbol = createClass(FqName("kotlin.jvm.internal.Lambda")) { klass ->
klass.addConstructor().apply {
addValueParameter("arity", irBuiltIns.intType)
@@ -7,8 +7,6 @@ package org.jetbrains.kotlin.backend.jvm.codegen
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor
import org.jetbrains.kotlin.builtins.isSuspendFunctionType
import org.jetbrains.kotlin.builtins.transformSuspendFunctionToRuntimeFunctionType
import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.codegen.JvmCodegenUtil
import org.jetbrains.kotlin.codegen.signature.AsmTypeFactory
@@ -22,6 +20,7 @@ import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.types.impl.originalKotlinType
import org.jetbrains.kotlin.ir.util.defaultType
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
import org.jetbrains.kotlin.ir.util.isSuspendFunction
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
import org.jetbrains.kotlin.load.kotlin.computeExpandedTypeForInlineClass
import org.jetbrains.kotlin.load.kotlin.mapBuiltInType
@@ -67,11 +66,13 @@ class IrTypeMapper(private val context: JvmBackendContext) {
error("Unexpected type: $type (original Kotlin type=$kotlinType of ${kotlinType?.let { it::class }})")
}
// TODO: rewrite this part to produce the correct Type without the fake descriptor
if (type.toKotlinType().isSuspendFunctionType) {
return context.state.typeMapper.mapType(
transformSuspendFunctionToRuntimeFunctionType(type.toKotlinType(), isReleaseCoroutines = true), sw, mode
)
if (type.isSuspendFunction()) {
val arguments =
type.arguments.dropLast(1).map { (it as IrTypeProjection).type } +
context.ir.symbols.continuationClass.typeWith((type.arguments.last() as IrTypeProjection).type) +
context.irBuiltIns.anyNType
val runtimeFunctionType = context.referenceClass(context.builtIns.getFunction(arguments.size - 1)).typeWith(arguments)
return mapType(runtimeFunctionType, mode, sw)
}
with(typeSystem) {
@@ -13,10 +13,7 @@ import org.jetbrains.kotlin.ir.types.IrSimpleType
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.IrTypeArgument
import org.jetbrains.kotlin.ir.types.classOrNull
import org.jetbrains.kotlin.ir.util.defaultType
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
import org.jetbrains.kotlin.ir.util.isLocalClass
import org.jetbrains.kotlin.ir.util.parentAsClass
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.org.objectweb.asm.Type
@@ -63,7 +60,7 @@ private fun IrSimpleType.buildPossiblyInnerType(classifier: IrClass?, index: Int
val toIndex = classifier.typeParameters.size + index
if (!classifier.isInner) {
assert(toIndex == arguments.size || classifier.isLocalClass()) {
"${arguments.size - toIndex} trailing arguments were found in $this type"
"${arguments.size - toIndex} trailing arguments were found in this type: ${render()}"
}
return PossiblyInnerIrType(classifier, arguments.subList(index, arguments.size), null)
@@ -78,7 +75,7 @@ private fun IrSimpleType.buildPossiblyInnerType(classifier: IrClass?, index: Int
internal val IrTypeParameter.representativeUpperBound: IrType
get() {
assert(superTypes.isNotEmpty()) { "Upper bounds should not be empty: $this" }
assert(superTypes.isNotEmpty()) { "Upper bounds should not be empty: ${render()}" }
return superTypes.firstOrNull {
val irClass = it.classOrNull?.owner ?: return@firstOrNull false