JVM_IR: refactor JvmSharedVariablesManager
This commit is contained in:
@@ -407,9 +407,6 @@ fun IrClass.createImplicitParameterDeclarationWithWrappedDescriptor() {
|
||||
thisReceiverDescriptor.bind(valueParameter)
|
||||
valueParameter.parent = this
|
||||
}
|
||||
|
||||
assert(typeParameters.isEmpty())
|
||||
assert(descriptor.declaredTypeParameters.isEmpty())
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
|
||||
@@ -69,7 +69,7 @@ class JvmBackendContext(
|
||||
val methodSignatureMapper = MethodSignatureMapper(this)
|
||||
|
||||
override val declarationFactory: JvmDeclarationFactory = JvmDeclarationFactory(methodSignatureMapper, state.languageVersionSettings)
|
||||
override val sharedVariablesManager = JvmSharedVariablesManager(state.module, builtIns, irBuiltIns)
|
||||
override val sharedVariablesManager = JvmSharedVariablesManager(state.module, irBuiltIns)
|
||||
|
||||
override val mapping: Mapping = DefaultMapping()
|
||||
|
||||
|
||||
+65
-173
@@ -6,45 +6,27 @@
|
||||
package org.jetbrains.kotlin.backend.jvm.descriptors
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.ir.SharedVariablesManager
|
||||
import org.jetbrains.kotlin.backend.common.ir.addChild
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.EmptyPackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.buildClass
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.buildConstructor
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.buildField
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.buildValueParameter
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrExternalPackageFragmentImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrTypeParameterImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl
|
||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.descriptors.WrappedTypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.ir.descriptors.WrappedVariableDescriptor
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrExternalPackageFragmentSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrTypeParameterSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
||||
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
|
||||
import org.jetbrains.kotlin.ir.util.defaultType
|
||||
import org.jetbrains.kotlin.ir.util.parentAsClass
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
|
||||
private val SHARED_VARIABLE_ORIGIN = object : IrDeclarationOriginImpl("SHARED_VARIABLE_ORIGIN") {}
|
||||
private val SHARED_VARIABLE_CONSTRUCTOR_CALL_ORIGIN = object : IrStatementOriginImpl("SHARED_VARIABLE_CONSTRUCTOR_CALL") {}
|
||||
|
||||
class JvmSharedVariablesManager(
|
||||
module: ModuleDescriptor,
|
||||
val builtIns: KotlinBuiltIns,
|
||||
val irBuiltIns: IrBuiltIns
|
||||
) : SharedVariablesManager {
|
||||
private val jvmInternalPackage = IrExternalPackageFragmentImpl(
|
||||
@@ -53,106 +35,44 @@ class JvmSharedVariablesManager(
|
||||
)
|
||||
)
|
||||
|
||||
private val refNamespaceClass = buildClass {
|
||||
private val refNamespaceClass = jvmInternalPackage.addClass {
|
||||
name = Name.identifier("Ref")
|
||||
}.apply {
|
||||
parent = jvmInternalPackage
|
||||
jvmInternalPackage.addChild(this)
|
||||
superTypes += irBuiltIns.anyType
|
||||
}
|
||||
|
||||
private abstract class RefProvider {
|
||||
abstract val elementType: IrType
|
||||
abstract val refClass: IrClass
|
||||
abstract fun getRefType(valueType: IrType): IrSimpleType
|
||||
|
||||
// Have to initialize fields lazily in order to refer to refClass.
|
||||
val refConstructor: IrConstructor by lazy {
|
||||
buildConstructor {
|
||||
origin = SHARED_VARIABLE_ORIGIN
|
||||
returnType = refClass.defaultType
|
||||
}.apply {
|
||||
parent = refClass
|
||||
refClass.addMember(this)
|
||||
}
|
||||
private class RefProvider(val refClass: IrClass, elementType: IrType) {
|
||||
val refConstructor = refClass.addConstructor {
|
||||
origin = IrDeclarationOrigin.IR_BUILTINS_STUB
|
||||
}
|
||||
|
||||
val elementField: IrField by lazy {
|
||||
buildField {
|
||||
origin = SHARED_VARIABLE_ORIGIN
|
||||
name = Name.identifier("element")
|
||||
type = elementType
|
||||
}.apply {
|
||||
parent = refClass
|
||||
refClass.addMember(this)
|
||||
}
|
||||
val elementField = refClass.addField {
|
||||
origin = IrDeclarationOrigin.IR_BUILTINS_STUB
|
||||
name = Name.identifier("element")
|
||||
type = elementType
|
||||
}
|
||||
}
|
||||
|
||||
private inner class PrimitiveRefProvider(override val elementType: IrType) : RefProvider() {
|
||||
override val refClass = buildClass {
|
||||
origin = SHARED_VARIABLE_ORIGIN
|
||||
name = Name.identifier(elementType.classOrNull!!.owner.name.asString() + "Ref")
|
||||
}.apply {
|
||||
parent = refNamespaceClass
|
||||
refNamespaceClass.addMember(this)
|
||||
superTypes += irBuiltIns.anyType
|
||||
thisReceiver = buildValueParameter {
|
||||
type = IrSimpleTypeImpl(symbol, hasQuestionMark = false, arguments = emptyList(), annotations = emptyList())
|
||||
name = Name.identifier("$this")
|
||||
}.also {
|
||||
it.parent = this
|
||||
}
|
||||
}
|
||||
|
||||
override fun getRefType(valueType: IrType) = refClass.defaultType
|
||||
}
|
||||
|
||||
private val primitiveRefProviders = irBuiltIns.primitiveIrTypes.associate { primitiveType ->
|
||||
primitiveType.classifierOrFail to PrimitiveRefProvider(primitiveType)
|
||||
val refClass = refNamespaceClass.addClass {
|
||||
origin = IrDeclarationOrigin.IR_BUILTINS_STUB
|
||||
name = Name.identifier(primitiveType.classOrNull!!.owner.name.asString() + "Ref")
|
||||
}.apply {
|
||||
createImplicitParameterDeclarationWithWrappedDescriptor()
|
||||
}
|
||||
primitiveType.classifierOrFail to RefProvider(refClass, primitiveType)
|
||||
}
|
||||
|
||||
private val objectRefProvider = object : RefProvider() {
|
||||
override val refClass = buildClass {
|
||||
origin = SHARED_VARIABLE_ORIGIN
|
||||
private val objectRefProvider = run {
|
||||
val refClass = refNamespaceClass.addClass {
|
||||
origin = IrDeclarationOrigin.IR_BUILTINS_STUB
|
||||
name = Name.identifier("ObjectRef")
|
||||
}.apply {
|
||||
val irClass = this
|
||||
typeParameters +=
|
||||
IrTypeParameterImpl(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||
SHARED_VARIABLE_ORIGIN,
|
||||
IrTypeParameterSymbolImpl(WrappedTypeParameterDescriptor()),
|
||||
Name.identifier("T"),
|
||||
index = 0,
|
||||
variance = Variance.INVARIANT,
|
||||
isReified = false
|
||||
).apply {
|
||||
(descriptor as WrappedTypeParameterDescriptor).bind(this)
|
||||
parent = irClass
|
||||
superTypes.add(irBuiltIns.anyNType)
|
||||
}
|
||||
parent = refNamespaceClass
|
||||
refNamespaceClass.addMember(this)
|
||||
superTypes += irBuiltIns.anyType
|
||||
thisReceiver = buildValueParameter {
|
||||
type = IrSimpleTypeImpl(
|
||||
symbol,
|
||||
hasQuestionMark = false,
|
||||
arguments = listOf(
|
||||
makeTypeProjection(typeParameters[0].defaultType, Variance.INVARIANT)
|
||||
),
|
||||
annotations = emptyList()
|
||||
)
|
||||
name = Name.identifier("$this")
|
||||
}.also {
|
||||
it.parent = this
|
||||
addTypeParameter {
|
||||
name = Name.identifier("T")
|
||||
superTypes.add(irBuiltIns.anyNType)
|
||||
}
|
||||
createImplicitParameterDeclarationWithWrappedDescriptor()
|
||||
}
|
||||
|
||||
override val elementType = refClass.typeParameters[0].defaultType
|
||||
|
||||
override fun getRefType(valueType: IrType) = refClass.typeWith(valueType)
|
||||
RefProvider(refClass, refClass.typeParameters[0].defaultType)
|
||||
}
|
||||
|
||||
private fun getProvider(valueType: IrType): RefProvider =
|
||||
@@ -161,85 +81,57 @@ class JvmSharedVariablesManager(
|
||||
else
|
||||
objectRefProvider
|
||||
|
||||
private fun getElementFieldSymbol(valueType: IrType): IrFieldSymbol {
|
||||
return getProvider(valueType).elementField.symbol
|
||||
}
|
||||
|
||||
override fun declareSharedVariable(originalDeclaration: IrVariable): IrVariable {
|
||||
val valueType = originalDeclaration.type
|
||||
val provider = getProvider(valueType)
|
||||
val refType = provider.getRefType(valueType)
|
||||
val refConstructor = provider.refConstructor
|
||||
|
||||
val refConstructorCall = IrConstructorCallImpl.fromSymbolOwner(
|
||||
refType,
|
||||
refConstructor.symbol,
|
||||
SHARED_VARIABLE_CONSTRUCTOR_CALL_ORIGIN
|
||||
).apply {
|
||||
List(refConstructor.parentAsClass.typeParameters.size) { i ->
|
||||
putTypeArgument(i, valueType)
|
||||
}
|
||||
val typeArguments = provider.refClass.typeParameters.map { valueType }
|
||||
val refType = provider.refClass.typeWith(typeArguments)
|
||||
val refConstructorCall = IrConstructorCallImpl.fromSymbolOwner(refType, provider.refConstructor.symbol).apply {
|
||||
typeArguments.forEachIndexed(::putTypeArgument)
|
||||
}
|
||||
|
||||
return IrVariableImpl(
|
||||
originalDeclaration.startOffset, originalDeclaration.endOffset, originalDeclaration.origin,
|
||||
IrVariableSymbolImpl(WrappedVariableDescriptor()),
|
||||
originalDeclaration.name,
|
||||
refType,
|
||||
originalDeclaration.isVar,
|
||||
originalDeclaration.isConst,
|
||||
isLateinit = false
|
||||
).apply {
|
||||
(descriptor as WrappedVariableDescriptor).bind(this)
|
||||
initializer = refConstructorCall
|
||||
parent = originalDeclaration.parent
|
||||
return with(originalDeclaration) {
|
||||
IrVariableImpl(
|
||||
startOffset, endOffset, origin, IrVariableSymbolImpl(WrappedVariableDescriptor()), name, refType,
|
||||
isVar = false, // writes are remapped to field stores
|
||||
isConst = false, // const vals could not possibly require ref wrappers
|
||||
isLateinit = false
|
||||
).apply {
|
||||
(descriptor as WrappedVariableDescriptor).bind(this)
|
||||
initializer = refConstructorCall
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun defineSharedValue(
|
||||
originalDeclaration: IrVariable,
|
||||
sharedVariableDeclaration: IrVariable
|
||||
): IrStatement {
|
||||
override fun defineSharedValue(originalDeclaration: IrVariable, sharedVariableDeclaration: IrVariable): IrStatement {
|
||||
val initializer = originalDeclaration.initializer ?: return sharedVariableDeclaration
|
||||
|
||||
val valueType = originalDeclaration.type
|
||||
|
||||
val sharedVariableInitialization = IrSetFieldImpl(
|
||||
initializer.startOffset, initializer.endOffset,
|
||||
getElementFieldSymbol(valueType),
|
||||
IrGetValueImpl(initializer.startOffset, initializer.endOffset, sharedVariableDeclaration.symbol),
|
||||
initializer,
|
||||
irBuiltIns.unitType
|
||||
)
|
||||
|
||||
return IrCompositeImpl(
|
||||
originalDeclaration.startOffset, originalDeclaration.endOffset, irBuiltIns.unitType, null,
|
||||
listOf(sharedVariableDeclaration, sharedVariableInitialization)
|
||||
)
|
||||
val initializationStatement = with(initializer) {
|
||||
IrSetVariableImpl(startOffset, endOffset, irBuiltIns.unitType, originalDeclaration.symbol, this, null)
|
||||
}
|
||||
val sharedVariableInitialization = setSharedValue(sharedVariableDeclaration.symbol, initializationStatement)
|
||||
return with(originalDeclaration) {
|
||||
IrCompositeImpl(
|
||||
startOffset, endOffset, irBuiltIns.unitType, null,
|
||||
listOf(sharedVariableDeclaration, sharedVariableInitialization)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getSharedValue(sharedVariableSymbol: IrVariableSymbol, originalGet: IrGetValue): IrExpression =
|
||||
IrTypeOperatorCallImpl(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||
originalGet.type,
|
||||
IrTypeOperator.IMPLICIT_CAST,
|
||||
originalGet.type,
|
||||
IrGetFieldImpl(
|
||||
originalGet.startOffset, originalGet.endOffset,
|
||||
getElementFieldSymbol(originalGet.symbol.owner.type),
|
||||
originalGet.type,
|
||||
IrGetValueImpl(originalGet.startOffset, originalGet.endOffset, sharedVariableSymbol),
|
||||
originalGet.origin
|
||||
)
|
||||
)
|
||||
with(originalGet) {
|
||||
val provider = getProvider(symbol.owner.type)
|
||||
val receiver = IrGetValueImpl(startOffset, endOffset, sharedVariableSymbol)
|
||||
IrGetFieldImpl(startOffset, endOffset, provider.elementField.symbol, type, receiver, origin)
|
||||
}
|
||||
|
||||
override fun setSharedValue(sharedVariableSymbol: IrVariableSymbol, originalSet: IrSetVariable): IrExpression =
|
||||
IrSetFieldImpl(
|
||||
originalSet.startOffset, originalSet.endOffset,
|
||||
getElementFieldSymbol(originalSet.symbol.owner.type),
|
||||
IrGetValueImpl(originalSet.startOffset, originalSet.endOffset, sharedVariableSymbol),
|
||||
originalSet.value,
|
||||
originalSet.type,
|
||||
originalSet.origin
|
||||
)
|
||||
with(originalSet) {
|
||||
val provider = getProvider(symbol.owner.type)
|
||||
val receiver = IrGetValueImpl(startOffset, endOffset, sharedVariableSymbol)
|
||||
IrSetFieldImpl(startOffset, endOffset, provider.elementField.symbol, receiver, value, type, origin)
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun IrDeclarationContainer.addClass(builder: IrClassBuilder.() -> Unit) = buildClass(builder).also {
|
||||
it.parent = this
|
||||
declarations += it
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user