JVM_IR: refactor JvmSharedVariablesManager

This commit is contained in:
pyos
2020-03-02 14:51:59 +01:00
committed by Dmitry Petrov
parent ed96b81a42
commit 68745ec43f
3 changed files with 66 additions and 177 deletions
@@ -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()
@@ -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
}