JVM IR: move CollectionToArray creation to JvmSymbols
Also simplify it to use IR builder DSL
This commit is contained in:
@@ -274,7 +274,7 @@ class JvmSymbols(
|
||||
val getOrCreateKotlinClasses: IrSimpleFunctionSymbol =
|
||||
reflection.functions.single { it.owner.name.asString() == "getOrCreateKotlinClasses" }
|
||||
|
||||
val unsafeCoerceIntrinsic =
|
||||
private val unsafeCoerceIntrinsic =
|
||||
buildFun {
|
||||
name = Name.special("<unsafe-coerce>")
|
||||
origin = IrDeclarationOrigin.IR_BUILTINS_STUB
|
||||
@@ -286,4 +286,25 @@ class JvmSymbols(
|
||||
returnType = dst.defaultType
|
||||
}
|
||||
val unsafeCoerceIntrinsicSymbol = unsafeCoerceIntrinsic.symbol
|
||||
|
||||
private val collectionToArrayClass: IrClassSymbol = createClass(FqName("kotlin.jvm.internal.CollectionToArray")) { klass ->
|
||||
klass.origin = JvmLoweredDeclarationOrigin.TO_ARRAY
|
||||
|
||||
val arrayType = irBuiltIns.arrayClass.typeWith(irBuiltIns.anyNType)
|
||||
klass.addFunction("toArray", arrayType, isStatic = true).apply {
|
||||
origin = JvmLoweredDeclarationOrigin.TO_ARRAY
|
||||
addValueParameter("collection", irBuiltIns.collectionClass.owner.typeWith(), JvmLoweredDeclarationOrigin.TO_ARRAY)
|
||||
}
|
||||
klass.addFunction("toArray", arrayType, isStatic = true).apply {
|
||||
origin = JvmLoweredDeclarationOrigin.TO_ARRAY
|
||||
addValueParameter("collection", irBuiltIns.collectionClass.owner.typeWith(), JvmLoweredDeclarationOrigin.TO_ARRAY)
|
||||
addValueParameter("array", arrayType, JvmLoweredDeclarationOrigin.TO_ARRAY)
|
||||
}
|
||||
}.symbol
|
||||
|
||||
val nonGenericToArray: IrSimpleFunctionSymbol =
|
||||
collectionToArrayClass.functions.single { it.owner.name.asString() == "toArray" && it.owner.valueParameters.size == 1 }
|
||||
|
||||
val genericToArray: IrSimpleFunctionSymbol =
|
||||
collectionToArrayClass.functions.single { it.owner.name.asString() == "toArray" && it.owner.valueParameters.size == 2 }
|
||||
}
|
||||
|
||||
+21
-111
@@ -6,25 +6,34 @@
|
||||
package org.jetbrains.kotlin.backend.jvm.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.*
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.WrappedSimpleFunctionDescriptor
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.WrappedTypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.WrappedValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.impl.EmptyPackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.builders.irBlockBody
|
||||
import org.jetbrains.kotlin.ir.builders.irCall
|
||||
import org.jetbrains.kotlin.ir.builders.irReturn
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.*
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrTypeParameterImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrTypeParameterSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.ir.util.defaultType
|
||||
import org.jetbrains.kotlin.ir.util.isClass
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.utils.DFS
|
||||
@@ -36,11 +45,11 @@ internal val toArrayPhase = makeIrFilePhase(
|
||||
)
|
||||
|
||||
private class ToArrayLowering(private val context: JvmBackendContext) : ClassLoweringPass {
|
||||
|
||||
override fun lower(irClass: IrClass) {
|
||||
if (irClass.isJvmInterface || !irClass.isDirectCollectionSubClass()) return
|
||||
|
||||
val irBuiltIns = context.irBuiltIns
|
||||
val symbols = context.ir.symbols
|
||||
|
||||
val toArrayName = Name.identifier("toArray")
|
||||
val genericToArray = irClass.declarations.find { it.isGenericToArray() }
|
||||
@@ -116,7 +125,7 @@ private class ToArrayLowering(private val context: JvmBackendContext) : ClassLow
|
||||
|
||||
irFunction.body = context.createIrBuilder(irFunction.symbol).irBlockBody {
|
||||
+irReturn(
|
||||
irCall(genericToArrayUtilFunction.symbol, genericToArrayUtilFunction.returnType).apply {
|
||||
irCall(symbols.genericToArray, symbols.genericToArray.owner.returnType).apply {
|
||||
putValueArgument(
|
||||
0,
|
||||
IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irFunction.dispatchReceiverParameter!!.symbol)
|
||||
@@ -165,7 +174,7 @@ private class ToArrayLowering(private val context: JvmBackendContext) : ClassLow
|
||||
|
||||
irFunction.body = context.createIrBuilder(irFunction.symbol).irBlockBody {
|
||||
+irReturn(
|
||||
irCall(nonGenericToArrayUtilFunction.symbol, nonGenericToArrayUtilFunction.returnType).apply {
|
||||
irCall(symbols.nonGenericToArray, symbols.nonGenericToArray.owner.returnType).apply {
|
||||
putValueArgument(
|
||||
0,
|
||||
IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irFunction.dispatchReceiverParameter!!.symbol)
|
||||
@@ -179,105 +188,6 @@ private class ToArrayLowering(private val context: JvmBackendContext) : ClassLow
|
||||
}
|
||||
}
|
||||
|
||||
private val kotlinJvmInternalPackageFragment: IrPackageFragment by lazy {
|
||||
IrExternalPackageFragmentImpl(
|
||||
IrExternalPackageFragmentSymbolImpl(
|
||||
EmptyPackageFragmentDescriptor(
|
||||
context.ir.irModule.descriptor,
|
||||
FqName("kotlin.jvm.internal")
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private val collectionUtilClass: IrClass by lazy {
|
||||
val descriptor = WrappedClassDescriptor()
|
||||
IrClassImpl(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||
JvmLoweredDeclarationOrigin.TO_ARRAY,
|
||||
IrClassSymbolImpl(descriptor),
|
||||
Name.identifier("CollectionToArray"),
|
||||
ClassKind.CLASS,
|
||||
Visibilities.PUBLIC,
|
||||
Modality.FINAL,
|
||||
isCompanion = false,
|
||||
isInner = false,
|
||||
isInline = false,
|
||||
isData = false,
|
||||
isExternal = false
|
||||
).apply {
|
||||
descriptor.bind(this)
|
||||
parent = kotlinJvmInternalPackageFragment
|
||||
superTypes.add(context.irBuiltIns.anyType)
|
||||
kotlinJvmInternalPackageFragment.declarations.add(this)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createToArrayUtilFunction(isGeneric: Boolean): IrSimpleFunction {
|
||||
val irBuiltIns = context.irBuiltIns
|
||||
val arrayType = irBuiltIns.arrayClass.typeWith(irBuiltIns.anyNType)
|
||||
|
||||
val utilFunctionDescriptor = WrappedSimpleFunctionDescriptor()
|
||||
return IrFunctionImpl(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||
JvmLoweredDeclarationOrigin.TO_ARRAY,
|
||||
IrSimpleFunctionSymbolImpl(utilFunctionDescriptor),
|
||||
Name.identifier("toArray"),
|
||||
Visibilities.PUBLIC,
|
||||
Modality.FINAL,
|
||||
returnType = arrayType,
|
||||
isInline = false,
|
||||
isExternal = false,
|
||||
isTailrec = false,
|
||||
isSuspend = false
|
||||
).also { irFunction ->
|
||||
utilFunctionDescriptor.bind(irFunction)
|
||||
irFunction.parent = collectionUtilClass
|
||||
|
||||
val collectionParameterDescriptor = WrappedValueParameterDescriptor()
|
||||
irFunction.valueParameters.add(
|
||||
IrValueParameterImpl(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||
JvmLoweredDeclarationOrigin.TO_ARRAY,
|
||||
IrValueParameterSymbolImpl(collectionParameterDescriptor),
|
||||
Name.identifier("collection"),
|
||||
0,
|
||||
irBuiltIns.collectionClass.owner.defaultType,
|
||||
varargElementType = null,
|
||||
isCrossinline = false,
|
||||
isNoinline = false
|
||||
).apply {
|
||||
collectionParameterDescriptor.bind(this)
|
||||
parent = irFunction
|
||||
}
|
||||
)
|
||||
if (isGeneric) {
|
||||
val arrayParameterDescriptor = WrappedValueParameterDescriptor()
|
||||
irFunction.valueParameters.add(
|
||||
IrValueParameterImpl(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||
JvmLoweredDeclarationOrigin.TO_ARRAY,
|
||||
IrValueParameterSymbolImpl(arrayParameterDescriptor),
|
||||
Name.identifier("array"),
|
||||
1,
|
||||
arrayType,
|
||||
varargElementType = null,
|
||||
isCrossinline = false,
|
||||
isNoinline = false
|
||||
).apply {
|
||||
arrayParameterDescriptor.bind(this)
|
||||
parent = irFunction
|
||||
}
|
||||
)
|
||||
}
|
||||
collectionUtilClass.declarations.add(irFunction)
|
||||
}
|
||||
}
|
||||
|
||||
private val nonGenericToArrayUtilFunction: IrSimpleFunction by lazy { createToArrayUtilFunction(false) }
|
||||
private val genericToArrayUtilFunction: IrSimpleFunction by lazy { createToArrayUtilFunction(true) }
|
||||
|
||||
|
||||
private fun IrDeclaration.isGenericToArray(): Boolean {
|
||||
if (this !is IrSimpleFunction) return false
|
||||
val signature = context.state.typeMapper.mapAsmMethod(descriptor)
|
||||
@@ -287,7 +197,7 @@ private class ToArrayLowering(private val context: JvmBackendContext) : ClassLow
|
||||
private fun IrDeclaration.isNonGenericToArray(): Boolean {
|
||||
if (this !is IrSimpleFunction) return false
|
||||
if (this.name.asString() != "toArray") return false
|
||||
if (!typeParameters.isEmpty() || !valueParameters.isEmpty()) return false
|
||||
if (typeParameters.isNotEmpty() || valueParameters.isNotEmpty()) return false
|
||||
if (!returnType.isArray()) return false
|
||||
|
||||
return true
|
||||
|
||||
@@ -115,3 +115,5 @@ fun IrClassifierSymbol.typeWith(arguments: List<IrType>): IrSimpleType =
|
||||
)
|
||||
|
||||
fun IrClass.typeWith(arguments: List<IrType>) = this.symbol.typeWith(arguments)
|
||||
|
||||
fun IrClass.typeWith(vararg arguments: IrType) = this.symbol.typeWith(arguments.toList())
|
||||
|
||||
Reference in New Issue
Block a user