[JS IR] Make backend work with new shared boxes

This commit is contained in:
Roman Artemev
2020-06-18 13:57:36 +03:00
committed by romanart
parent 596c3d1af8
commit a0cccdf75c
3 changed files with 57 additions and 148 deletions
@@ -91,7 +91,7 @@ class JsIrBackendContext(
val declarationLevelJsModules = mutableListOf<IrDeclarationWithName>() val declarationLevelJsModules = mutableListOf<IrDeclarationWithName>()
private val internalPackageFragmentDescriptor = EmptyPackageFragmentDescriptor(builtIns.builtInsModule, FqName("kotlin.js.internal")) private val internalPackageFragmentDescriptor = EmptyPackageFragmentDescriptor(builtIns.builtInsModule, FqName("kotlin.js.internal"))
val implicitDeclarationFile by lazy2 { val implicitDeclarationFile = run {
IrFileImpl(object : SourceManager.FileEntry { IrFileImpl(object : SourceManager.FileEntry {
override val name = "<implicitDeclarations>" override val name = "<implicitDeclarations>"
override val maxOffset = UNDEFINED_OFFSET override val maxOffset = UNDEFINED_OFFSET
@@ -125,8 +125,6 @@ class JsIrBackendContext(
implicitDeclarationFile.declarations += this implicitDeclarationFile.declarations += this
} }
override val sharedVariablesManager = JsSharedVariablesManager(irBuiltIns, implicitDeclarationFile)
override val mapping = JsMapping() override val mapping = JsMapping()
override val declarationFactory = JsDeclarationFactory(mapping) override val declarationFactory = JsDeclarationFactory(mapping)
@@ -162,8 +160,11 @@ class JsIrBackendContext(
private val coroutinePackage = module.getPackage(COROUTINE_PACKAGE_FQNAME) private val coroutinePackage = module.getPackage(COROUTINE_PACKAGE_FQNAME)
private val coroutineIntrinsicsPackage = module.getPackage(COROUTINE_INTRINSICS_PACKAGE_FQNAME) private val coroutineIntrinsicsPackage = module.getPackage(COROUTINE_INTRINSICS_PACKAGE_FQNAME)
val dynamicType: IrDynamicType = IrDynamicTypeImpl(null, emptyList(), Variance.INVARIANT)
val intrinsics = JsIntrinsics(irBuiltIns, this) val intrinsics = JsIntrinsics(irBuiltIns, this)
override val sharedVariablesManager = JsSharedVariablesManager(this)
override val internalPackageFqn = JS_PACKAGE_FQNAME override val internalPackageFqn = JS_PACKAGE_FQNAME
private val operatorMap = referenceOperators() private val operatorMap = referenceOperators()
@@ -176,8 +177,6 @@ class JsIrBackendContext(
return numbers + listOf(Name.identifier("String"), Name.identifier("Boolean")) return numbers + listOf(Name.identifier("String"), Name.identifier("Boolean"))
} }
val dynamicType: IrDynamicType = IrDynamicTypeImpl(null, emptyList(), Variance.INVARIANT)
fun getOperatorByName(name: Name, type: IrSimpleType) = operatorMap[name]?.get(type.classifier) fun getOperatorByName(name: Name, type: IrSimpleType) = operatorMap[name]?.get(type.classifier)
override val ir = object : Ir<JsIrBackendContext>(this, irModuleFragment) { override val ir = object : Ir<JsIrBackendContext>(this, irModuleFragment) {
@@ -5,34 +5,25 @@
package org.jetbrains.kotlin.ir.backend.js package org.jetbrains.kotlin.ir.backend.js
import org.jetbrains.kotlin.backend.common.ir.DeclarationFactory
import org.jetbrains.kotlin.backend.common.ir.SharedVariablesManager import org.jetbrains.kotlin.backend.common.ir.SharedVariablesManager
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl
import org.jetbrains.kotlin.ir.descriptors.* import org.jetbrains.kotlin.ir.descriptors.*
import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrGetValue import org.jetbrains.kotlin.ir.expressions.IrGetValue
import org.jetbrains.kotlin.ir.expressions.IrSetVariable import org.jetbrains.kotlin.ir.expressions.IrSetVariable
import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
import org.jetbrains.kotlin.ir.util.defaultType
import org.jetbrains.kotlin.name.Name
class JsSharedVariablesManager(val builtIns: IrBuiltIns, val implicitDeclarationsFile: IrPackageFragment) : SharedVariablesManager { class JsSharedVariablesManager(context: JsIrBackendContext) : SharedVariablesManager {
private val builtIns: IrBuiltIns = context.irBuiltIns
private val createBox: IrSimpleFunctionSymbol = context.intrinsics.createSharedBox.symbol
private val readBox: IrSimpleFunctionSymbol = context.intrinsics.readSharedBox.symbol
private val writeBox: IrSimpleFunctionSymbol = context.intrinsics.writeSharedBox.symbol
private val dynamicType = context.dynamicType
override fun declareSharedVariable(originalDeclaration: IrVariable): IrVariable { override fun declareSharedVariable(originalDeclaration: IrVariable): IrVariable {
val valueType = originalDeclaration.type val valueType = originalDeclaration.type
@@ -42,16 +33,14 @@ class JsSharedVariablesManager(val builtIns: IrBuiltIns, val implicitDeclaration
valueType valueType
) )
val constructorSymbol = closureBoxConstructorDeclaration.symbol
val irCall = val irCall =
IrConstructorCallImpl( IrCallImpl(
initializer.startOffset, initializer.endOffset, initializer.startOffset, initializer.endOffset,
closureBoxType, constructorSymbol, dynamicType, createBox,
valueArgumentsCount = 1, valueArgumentsCount = 1,
typeArgumentsCount = 0, typeArgumentsCount = 1
constructorTypeArgumentsCount = 0
).apply { ).apply {
putTypeArgument(0, valueType)
putValueArgument(0, initializer) putValueArgument(0, initializer)
} }
@@ -62,7 +51,7 @@ class JsSharedVariablesManager(val builtIns: IrBuiltIns, val implicitDeclaration
originalDeclaration.origin, originalDeclaration.origin,
IrVariableSymbolImpl(descriptor), IrVariableSymbolImpl(descriptor),
originalDeclaration.name, originalDeclaration.name,
irCall.type, dynamicType,
isVar = false, isVar = false,
isConst = false, isConst = false,
isLateinit = false isLateinit = false
@@ -75,130 +64,51 @@ class JsSharedVariablesManager(val builtIns: IrBuiltIns, val implicitDeclaration
override fun defineSharedValue(originalDeclaration: IrVariable, sharedVariableDeclaration: IrVariable) = sharedVariableDeclaration override fun defineSharedValue(originalDeclaration: IrVariable, sharedVariableDeclaration: IrVariable) = sharedVariableDeclaration
override fun getSharedValue(sharedVariableSymbol: IrVariableSymbol, originalGet: IrGetValue) = IrGetFieldImpl( override fun getSharedValue(sharedVariableSymbol: IrVariableSymbol, originalGet: IrGetValue): IrExpression {
originalGet.startOffset, originalGet.endOffset,
closureBoxFieldDeclaration.symbol, return IrCallImpl(
originalGet.type,
IrGetValueImpl(
originalGet.startOffset, originalGet.startOffset,
originalGet.endOffset, originalGet.endOffset,
closureBoxType, originalGet.type,
sharedVariableSymbol, readBox,
typeArgumentsCount = 1,
valueArgumentsCount = 1,
originalGet.origin originalGet.origin
), ).apply {
originalGet.origin putTypeArgument(0, originalGet.type)
) putValueArgument(
0, IrGetValueImpl(
override fun setSharedValue(sharedVariableSymbol: IrVariableSymbol, originalSet: IrSetVariable): IrExpression = originalGet.startOffset,
IrSetFieldImpl( originalGet.endOffset,
originalSet.startOffset, dynamicType,
originalSet.endOffset, sharedVariableSymbol,
closureBoxFieldDeclaration.symbol, originalGet.origin
IrGetValueImpl( )
originalSet.startOffset, )
originalSet.endOffset,
closureBoxType,
sharedVariableSymbol,
originalSet.origin
),
originalSet.value,
originalSet.type,
originalSet.origin
)
private val boxTypeName = "\$closureBox\$"
private val closureBoxClassDeclaration by lazy {
createClosureBoxClassDeclaration()
}
private val closureBoxConstructorDeclaration by lazy {
createClosureBoxConstructorDeclaration()
}
private val closureBoxFieldDeclaration by lazy {
closureBoxPropertyDeclaration
}
private val closureBoxPropertyDeclaration by lazy {
createClosureBoxPropertyDeclaration()
}
private lateinit var closureBoxType: IrType
private fun createClosureBoxClassDeclaration(): IrClass {
val descriptor = WrappedClassDescriptor()
val declaration = IrClassImpl(
UNDEFINED_OFFSET, UNDEFINED_OFFSET, JsLoweredDeclarationOrigin.JS_CLOSURE_BOX_CLASS_DECLARATION, IrClassSymbolImpl(descriptor),
Name.identifier(boxTypeName), ClassKind.CLASS, Visibilities.PUBLIC, Modality.FINAL
)
descriptor.bind(declaration)
declaration.parent = implicitDeclarationsFile
// TODO: substitute
closureBoxType = IrSimpleTypeImpl(declaration.symbol, false, emptyList(), emptyList())
declaration.thisReceiver =
JsIrBuilder.buildValueParameter(Name.special("<this>"), -1, closureBoxType, IrDeclarationOrigin.INSTANCE_RECEIVER).apply {
parent = declaration
}
implicitDeclarationsFile.declarations += declaration
return declaration
}
private fun createClosureBoxPropertyDeclaration(): IrField {
val descriptor = WrappedFieldDescriptor()
val symbol = IrFieldSymbolImpl(descriptor)
val fieldName = Name.identifier("v")
return IrFieldImpl(
UNDEFINED_OFFSET,
UNDEFINED_OFFSET,
DeclarationFactory.FIELD_FOR_OUTER_THIS,
symbol,
fieldName,
builtIns.anyNType,
Visibilities.PUBLIC,
isFinal = false,
isExternal = false,
isStatic = false
).also {
descriptor.bind(it)
it.parent = closureBoxClassDeclaration
closureBoxClassDeclaration.declarations += it
} }
} }
private fun createClosureBoxConstructorDeclaration(): IrConstructor { override fun setSharedValue(sharedVariableSymbol: IrVariableSymbol, originalSet: IrSetVariable): IrExpression {
val descriptor = WrappedClassConstructorDescriptor() return IrCallImpl(
val symbol = IrConstructorSymbolImpl(descriptor) originalSet.startOffset,
originalSet.endOffset,
val declaration = IrConstructorImpl( builtIns.unitType,
UNDEFINED_OFFSET, UNDEFINED_OFFSET, JsLoweredDeclarationOrigin.JS_CLOSURE_BOX_CLASS_DECLARATION, symbol, writeBox,
Name.special("<init>"), Visibilities.PUBLIC, closureBoxClassDeclaration.defaultType, typeArgumentsCount = 1,
isInline = false, isExternal = false, isPrimary = true, isExpect = false valueArgumentsCount = 2,
) originalSet.origin
).apply {
descriptor.bind(declaration) putTypeArgument(0, originalSet.value.type)
declaration.parent = closureBoxClassDeclaration putValueArgument(
0, IrGetValueImpl(
val parameterDeclaration = createClosureBoxConstructorParameterDeclaration(declaration) originalSet.startOffset,
originalSet.endOffset,
declaration.valueParameters += parameterDeclaration dynamicType,
sharedVariableSymbol,
val receiver = JsIrBuilder.buildGetValue(closureBoxClassDeclaration.thisReceiver!!.symbol) originalSet.origin
val value = JsIrBuilder.buildGetValue(parameterDeclaration.symbol) )
)
val setField = JsIrBuilder.buildSetField(closureBoxFieldDeclaration.symbol, receiver, value, closureBoxFieldDeclaration.type) putValueArgument(1, originalSet.value)
declaration.body = IrBlockBodyImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, listOf(setField))
closureBoxClassDeclaration.declarations += declaration
return declaration
}
private fun createClosureBoxConstructorParameterDeclaration(irConstructor: IrConstructor): IrValueParameter {
return JsIrBuilder.buildValueParameter("p", 0, closureBoxPropertyDeclaration.type).also {
it.parent = irConstructor
} }
} }
} }
@@ -61,7 +61,7 @@ class WasmBackendContext(
builtIns.builtInsModule, FqName("kotlin.wasm.internal") builtIns.builtInsModule, FqName("kotlin.wasm.internal")
) )
override val sharedVariablesManager = JsSharedVariablesManager(irBuiltIns, internalPackageFragment) override val sharedVariablesManager = JsSharedVariablesManager(TODO("..."))
val wasmSymbols: WasmSymbols = WasmSymbols(this@WasmBackendContext, symbolTable) val wasmSymbols: WasmSymbols = WasmSymbols(this@WasmBackendContext, symbolTable)
override val ir = object : Ir<WasmBackendContext>(this, irModuleFragment) { override val ir = object : Ir<WasmBackendContext>(this, irModuleFragment) {