JVM_IR: wrap inline class objects in unboxed refs

This commit is contained in:
pyos
2020-03-02 15:06:32 +01:00
committed by Dmitry Petrov
parent 68745ec43f
commit 13b04e63be
4 changed files with 21 additions and 12 deletions
@@ -69,7 +69,6 @@ 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, irBuiltIns)
override val mapping: Mapping = DefaultMapping() override val mapping: Mapping = DefaultMapping()
@@ -77,6 +76,8 @@ class JvmBackendContext(
override val ir = JvmIr(irModuleFragment, this.symbolTable) override val ir = JvmIr(irModuleFragment, this.symbolTable)
override val sharedVariablesManager = JvmSharedVariablesManager(state.module, ir.symbols, irBuiltIns)
val irIntrinsics by lazy { IrIntrinsicMethods(irBuiltIns, ir.symbols) } val irIntrinsics by lazy { IrIntrinsicMethods(irBuiltIns, ir.symbols) }
private val localClassType = mutableMapOf<IrAttributeContainer, Type>() private val localClassType = mutableMapOf<IrAttributeContainer, Type>()
@@ -7,6 +7,8 @@ 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.createImplicitParameterDeclarationWithWrappedDescriptor import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor
import org.jetbrains.kotlin.backend.jvm.JvmSymbols
import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.InlineClassAbi
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
@@ -27,6 +29,7 @@ import org.jetbrains.kotlin.name.Name
class JvmSharedVariablesManager( class JvmSharedVariablesManager(
module: ModuleDescriptor, module: ModuleDescriptor,
val symbols: JvmSymbols,
val irBuiltIns: IrBuiltIns val irBuiltIns: IrBuiltIns
) : SharedVariablesManager { ) : SharedVariablesManager {
private val jvmInternalPackage = IrExternalPackageFragmentImpl( private val jvmInternalPackage = IrExternalPackageFragmentImpl(
@@ -83,7 +86,7 @@ class JvmSharedVariablesManager(
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(InlineClassAbi.unboxType(valueType) ?: valueType)
val typeArguments = provider.refClass.typeParameters.map { valueType } val typeArguments = provider.refClass.typeParameters.map { valueType }
val refType = provider.refClass.typeWith(typeArguments) val refType = provider.refClass.typeWith(typeArguments)
val refConstructorCall = IrConstructorCallImpl.fromSymbolOwner(refType, provider.refConstructor.symbol).apply { val refConstructorCall = IrConstructorCallImpl.fromSymbolOwner(refType, provider.refConstructor.symbol).apply {
@@ -116,18 +119,29 @@ class JvmSharedVariablesManager(
} }
} }
private fun unsafeCoerce(value: IrExpression, from: IrType, to: IrType): IrExpression =
IrCallImpl(value.startOffset, value.endOffset, to, symbols.unsafeCoerceIntrinsic).apply {
putTypeArgument(0, from)
putTypeArgument(1, to)
putValueArgument(0, value)
}
override fun getSharedValue(sharedVariableSymbol: IrVariableSymbol, originalGet: IrGetValue): IrExpression = override fun getSharedValue(sharedVariableSymbol: IrVariableSymbol, originalGet: IrGetValue): IrExpression =
with(originalGet) { with(originalGet) {
val provider = getProvider(symbol.owner.type) val unboxedType = InlineClassAbi.unboxType(symbol.owner.type)
val provider = getProvider(unboxedType ?: symbol.owner.type)
val receiver = IrGetValueImpl(startOffset, endOffset, sharedVariableSymbol) val receiver = IrGetValueImpl(startOffset, endOffset, sharedVariableSymbol)
IrGetFieldImpl(startOffset, endOffset, provider.elementField.symbol, type, receiver, origin) val unboxedRead = IrGetFieldImpl(startOffset, endOffset, provider.elementField.symbol, unboxedType ?: type, receiver, origin)
unboxedType?.let { unsafeCoerce(unboxedRead, it, symbol.owner.type) } ?: unboxedRead
} }
override fun setSharedValue(sharedVariableSymbol: IrVariableSymbol, originalSet: IrSetVariable): IrExpression = override fun setSharedValue(sharedVariableSymbol: IrVariableSymbol, originalSet: IrSetVariable): IrExpression =
with(originalSet) { with(originalSet) {
val provider = getProvider(symbol.owner.type) val unboxedType = InlineClassAbi.unboxType(symbol.owner.type)
val unboxedValue = unboxedType?.let { unsafeCoerce(value, symbol.owner.type, it) } ?: value
val provider = getProvider(unboxedType ?: symbol.owner.type)
val receiver = IrGetValueImpl(startOffset, endOffset, sharedVariableSymbol) val receiver = IrGetValueImpl(startOffset, endOffset, sharedVariableSymbol)
IrSetFieldImpl(startOffset, endOffset, provider.elementField.symbol, receiver, value, type, origin) IrSetFieldImpl(startOffset, endOffset, provider.elementField.symbol, receiver, unboxedValue, type, origin)
} }
} }
@@ -1,6 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// TODO: JVM_IR uses ObjectRef instead of IntRef for the value
fun test(): UInt { fun test(): UInt {
val c: UInt val c: UInt
run { run {
@@ -1,6 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// TODO: JVM_IR uses ObjectRef instead of IntRef for the value
fun test(): UInt { fun test(): UInt {
var c: UInt var c: UInt
run { run {