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