[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

View File

@@ -91,7 +91,7 @@ class JsIrBackendContext(
val declarationLevelJsModules = mutableListOf<IrDeclarationWithName>()
private val internalPackageFragmentDescriptor = EmptyPackageFragmentDescriptor(builtIns.builtInsModule, FqName("kotlin.js.internal"))
val implicitDeclarationFile by lazy2 {
val implicitDeclarationFile = run {
IrFileImpl(object : SourceManager.FileEntry {
override val name = "<implicitDeclarations>"
override val maxOffset = UNDEFINED_OFFSET
@@ -125,8 +125,6 @@ class JsIrBackendContext(
implicitDeclarationFile.declarations += this
}
override val sharedVariablesManager = JsSharedVariablesManager(irBuiltIns, implicitDeclarationFile)
override val mapping = JsMapping()
override val declarationFactory = JsDeclarationFactory(mapping)
@@ -162,8 +160,11 @@ class JsIrBackendContext(
private val coroutinePackage = module.getPackage(COROUTINE_PACKAGE_FQNAME)
private val coroutineIntrinsicsPackage = module.getPackage(COROUTINE_INTRINSICS_PACKAGE_FQNAME)
val dynamicType: IrDynamicType = IrDynamicTypeImpl(null, emptyList(), Variance.INVARIANT)
val intrinsics = JsIntrinsics(irBuiltIns, this)
override val sharedVariablesManager = JsSharedVariablesManager(this)
override val internalPackageFqn = JS_PACKAGE_FQNAME
private val operatorMap = referenceOperators()
@@ -176,8 +177,6 @@ class JsIrBackendContext(
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)
override val ir = object : Ir<JsIrBackendContext>(this, irModuleFragment) {

View File

@@ -5,34 +5,25 @@
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.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.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.descriptors.*
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrGetValue
import org.jetbrains.kotlin.ir.expressions.IrSetVariable
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.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.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 {
val valueType = originalDeclaration.type
@@ -42,16 +33,14 @@ class JsSharedVariablesManager(val builtIns: IrBuiltIns, val implicitDeclaration
valueType
)
val constructorSymbol = closureBoxConstructorDeclaration.symbol
val irCall =
IrConstructorCallImpl(
IrCallImpl(
initializer.startOffset, initializer.endOffset,
closureBoxType, constructorSymbol,
dynamicType, createBox,
valueArgumentsCount = 1,
typeArgumentsCount = 0,
constructorTypeArgumentsCount = 0
typeArgumentsCount = 1
).apply {
putTypeArgument(0, valueType)
putValueArgument(0, initializer)
}
@@ -62,7 +51,7 @@ class JsSharedVariablesManager(val builtIns: IrBuiltIns, val implicitDeclaration
originalDeclaration.origin,
IrVariableSymbolImpl(descriptor),
originalDeclaration.name,
irCall.type,
dynamicType,
isVar = false,
isConst = false,
isLateinit = false
@@ -75,130 +64,51 @@ class JsSharedVariablesManager(val builtIns: IrBuiltIns, val implicitDeclaration
override fun defineSharedValue(originalDeclaration: IrVariable, sharedVariableDeclaration: IrVariable) = sharedVariableDeclaration
override fun getSharedValue(sharedVariableSymbol: IrVariableSymbol, originalGet: IrGetValue) = IrGetFieldImpl(
originalGet.startOffset, originalGet.endOffset,
closureBoxFieldDeclaration.symbol,
originalGet.type,
IrGetValueImpl(
override fun getSharedValue(sharedVariableSymbol: IrVariableSymbol, originalGet: IrGetValue): IrExpression {
return IrCallImpl(
originalGet.startOffset,
originalGet.endOffset,
closureBoxType,
sharedVariableSymbol,
originalGet.type,
readBox,
typeArgumentsCount = 1,
valueArgumentsCount = 1,
originalGet.origin
),
originalGet.origin
)
override fun setSharedValue(sharedVariableSymbol: IrVariableSymbol, originalSet: IrSetVariable): IrExpression =
IrSetFieldImpl(
originalSet.startOffset,
originalSet.endOffset,
closureBoxFieldDeclaration.symbol,
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
).apply {
putTypeArgument(0, originalGet.type)
putValueArgument(
0, IrGetValueImpl(
originalGet.startOffset,
originalGet.endOffset,
dynamicType,
sharedVariableSymbol,
originalGet.origin
)
)
}
}
private fun createClosureBoxConstructorDeclaration(): IrConstructor {
val descriptor = WrappedClassConstructorDescriptor()
val symbol = IrConstructorSymbolImpl(descriptor)
val declaration = IrConstructorImpl(
UNDEFINED_OFFSET, UNDEFINED_OFFSET, JsLoweredDeclarationOrigin.JS_CLOSURE_BOX_CLASS_DECLARATION, symbol,
Name.special("<init>"), Visibilities.PUBLIC, closureBoxClassDeclaration.defaultType,
isInline = false, isExternal = false, isPrimary = true, isExpect = false
)
descriptor.bind(declaration)
declaration.parent = closureBoxClassDeclaration
val parameterDeclaration = createClosureBoxConstructorParameterDeclaration(declaration)
declaration.valueParameters += parameterDeclaration
val receiver = JsIrBuilder.buildGetValue(closureBoxClassDeclaration.thisReceiver!!.symbol)
val value = JsIrBuilder.buildGetValue(parameterDeclaration.symbol)
val setField = JsIrBuilder.buildSetField(closureBoxFieldDeclaration.symbol, receiver, value, closureBoxFieldDeclaration.type)
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
override fun setSharedValue(sharedVariableSymbol: IrVariableSymbol, originalSet: IrSetVariable): IrExpression {
return IrCallImpl(
originalSet.startOffset,
originalSet.endOffset,
builtIns.unitType,
writeBox,
typeArgumentsCount = 1,
valueArgumentsCount = 2,
originalSet.origin
).apply {
putTypeArgument(0, originalSet.value.type)
putValueArgument(
0, IrGetValueImpl(
originalSet.startOffset,
originalSet.endOffset,
dynamicType,
sharedVariableSymbol,
originalSet.origin
)
)
putValueArgument(1, originalSet.value)
}
}
}

View File

@@ -61,7 +61,7 @@ class WasmBackendContext(
builtIns.builtInsModule, FqName("kotlin.wasm.internal")
)
override val sharedVariablesManager = JsSharedVariablesManager(irBuiltIns, internalPackageFragment)
override val sharedVariablesManager = JsSharedVariablesManager(TODO("..."))
val wasmSymbols: WasmSymbols = WasmSymbols(this@WasmBackendContext, symbolTable)
override val ir = object : Ir<WasmBackendContext>(this, irModuleFragment) {