diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsLoweringPhases.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsLoweringPhases.kt index 27996aa4c1b..38f073be178 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsLoweringPhases.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsLoweringPhases.kt @@ -340,7 +340,7 @@ private val autoboxingTransformerPhase = makeJsModulePhase( private val blockDecomposerLoweringPhase = makeCustomJsModulePhase( { context, module -> - BlockDecomposerLowering(context).lower(module) + JsBlockDecomposerLowering(context).lower(module) module.patchDeclarationParents() }, name = "BlockDecomposerLowering", @@ -384,14 +384,14 @@ private val staticMembersLoweringPhase = makeJsModulePhase( description = "Move static member declarations to top-level" ) -private val objectDeclarationLoweringPhase = makeJsModulePhase( - ::ObjectDeclarationLowering, +private val objectDeclarationLoweringPhase = makeCustomJsModulePhase( + { context, module -> ObjectDeclarationLowering(context, context.objectToGetInstanceFunction).lower(module) }, name = "ObjectDeclarationLowering", description = "Create lazy object instance generator functions" ) -private val objectUsageLoweringPhase = makeJsModulePhase( - ::ObjectUsageLowering, +private val objectUsageLoweringPhase = makeCustomJsModulePhase( + { context, module -> ObjectUsageLowering(context, context.objectToGetInstanceFunction).lower(module) }, name = "ObjectUsageLowering", description = "Transform IrGetObjectValue into instance generator call" ) @@ -449,4 +449,4 @@ val jsPhases = namedIrModulePhase( callsLoweringPhase then staticMembersLoweringPhase then validateIrAfterLowering -) +) \ No newline at end of file diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsSharedVariablesManager.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsSharedVariablesManager.kt index bc4a8336495..b13b06d6d1f 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsSharedVariablesManager.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsSharedVariablesManager.kt @@ -36,7 +36,7 @@ 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: IrFile) : SharedVariablesManager { +class JsSharedVariablesManager(val builtIns: IrBuiltIns, val implicitDeclarationsFile: IrPackageFragment) : SharedVariablesManager { override fun declareSharedVariable(originalDeclaration: IrVariable): IrVariable { val valueType = originalDeclaration.type diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/AutoboxingTransformer.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/AutoboxingTransformer.kt index 91ca5d0717b..4dd202da6dc 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/AutoboxingTransformer.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/AutoboxingTransformer.kt @@ -85,7 +85,7 @@ class AutoboxingTransformer(val context: JsIrBackendContext) : AbstractValueUsag if (actualType.isUnit() && !expectedType.isUnit()) { // Don't materialize Unit if value is known to be proper Unit on runtime if (!this.isGetUnit()) { - val unitValue = JsIrBuilder.buildGetObjectValue(actualType, context.symbolTable.referenceClass(context.builtIns.unit)) + val unitValue = JsIrBuilder.buildGetObjectValue(actualType, context.irBuiltIns.unitClass) return JsIrBuilder.buildComposite(actualType, listOf(this, unitValue)) } } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/BlockDecomposerLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/BlockDecomposerLowering.kt index d7c6c489e43..e95be193448 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/BlockDecomposerLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/BlockDecomposerLowering.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.ir.backend.js.lower +import org.jetbrains.kotlin.backend.common.CommonBackendContext import org.jetbrains.kotlin.backend.common.DeclarationContainerLoweringPass import org.jetbrains.kotlin.backend.common.ir.isElseBranch import org.jetbrains.kotlin.ir.IrElement @@ -21,9 +22,17 @@ import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.utils.addIfNotNull -class BlockDecomposerLowering(context: JsIrBackendContext) : DeclarationContainerLoweringPass { +class JsBlockDecomposerLowering(val context: JsIrBackendContext) : AbstractBlockDecomposerLowering(context) { + override fun unreachableExpression(): IrExpression = + JsIrBuilder.buildCall(context.intrinsics.unreachable.symbol, context.irBuiltIns.nothingType) +} - private val decomposerTransformer = BlockDecomposerTransformer(context) +abstract class AbstractBlockDecomposerLowering(context: CommonBackendContext) : DeclarationContainerLoweringPass { + + // Expression with Nothing type to be inserted in places of unreachable expression + abstract fun unreachableExpression(): IrExpression + + private val decomposerTransformer = BlockDecomposerTransformer(context, ::unreachableExpression) private val nothingType = context.irBuiltIns.nothingType override fun lower(irDeclarationContainer: IrDeclarationContainer) { @@ -80,7 +89,10 @@ class BlockDecomposerLowering(context: JsIrBackendContext) : DeclarationContaine } } -class BlockDecomposerTransformer(private val context: JsIrBackendContext) : IrElementTransformerVoid() { +class BlockDecomposerTransformer( + private val context: CommonBackendContext, + private val unreachableExpression: () -> IrExpression +) : IrElementTransformerVoid() { private lateinit var function: IrFunction private var tmpVarCounter: Int = 0 @@ -92,9 +104,8 @@ class BlockDecomposerTransformer(private val context: JsIrBackendContext) : IrEl private val nothingType = context.irBuiltIns.nothingNType private val unitType = context.irBuiltIns.unitType - private val unitValue get() = JsIrBuilder.buildGetObjectValue(unitType, context.symbolTable.referenceClass(context.builtIns.unit)) + private val unitValue get() = JsIrBuilder.buildGetObjectValue(unitType, context.irBuiltIns.unitClass) - private val unreachableFunction = context.intrinsics.unreachable private val booleanNotSymbol = context.irBuiltIns.booleanNotSymbol override fun visitFunction(declaration: IrFunction): IrStatement { @@ -429,13 +440,13 @@ class BlockDecomposerTransformer(private val context: JsIrBackendContext) : IrEl override fun visitSetField(expression: IrSetField) = expression.asExpression(unitValue) override fun visitBreakContinue(jump: IrBreakContinue) = - jump.asExpression(JsIrBuilder.buildCall(unreachableFunction.symbol, nothingType)) + jump.asExpression(unreachableExpression()) override fun visitThrow(expression: IrThrow) = - expression.asExpression(JsIrBuilder.buildCall(unreachableFunction.symbol, nothingType)) + expression.asExpression(unreachableExpression()) override fun visitReturn(expression: IrReturn) = - expression.asExpression(JsIrBuilder.buildCall(unreachableFunction.symbol, nothingType)) + expression.asExpression(unreachableExpression()) override fun visitVariable(declaration: IrVariable) = declaration.asExpression(unitValue) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/BridgesConstruction.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/BridgesConstruction.kt index 8eb224467e7..dd0e9c30f56 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/BridgesConstruction.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/BridgesConstruction.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.ir.backend.js.lower import org.jetbrains.kotlin.backend.common.ClassLoweringPass +import org.jetbrains.kotlin.backend.common.CommonBackendContext import org.jetbrains.kotlin.backend.common.bridges.FunctionHandle import org.jetbrains.kotlin.backend.common.bridges.generateBridges import org.jetbrains.kotlin.backend.common.ir.copyTo @@ -49,7 +50,7 @@ import org.jetbrains.kotlin.ir.util.* // fun foo(t: Any?) = foo(t as Int) // Constructed bridge // } // -class BridgesConstruction(val context: JsIrBackendContext) : ClassLoweringPass { +class BridgesConstruction(val context: CommonBackendContext) : ClassLoweringPass { private val specialBridgeMethods = SpecialBridgeMethods(context) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/EnumClassLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/EnumClassLowering.kt index 8797a0b08de..c2ded075a6c 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/EnumClassLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/EnumClassLowering.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.ir.backend.js.lower +import org.jetbrains.kotlin.backend.common.CommonBackendContext import org.jetbrains.kotlin.backend.common.DeclarationContainerLoweringPass import org.jetbrains.kotlin.backend.common.FileLoweringPass import org.jetbrains.kotlin.backend.common.descriptors.WrappedClassConstructorDescriptor @@ -101,7 +102,7 @@ private fun createEntryAccessorName(enumName: String, enumEntry: IrEnumEntry) = private fun IrEnumEntry.getType(irClass: IrClass) = (correspondingClass ?: irClass).defaultType -class EnumClassConstructorLowering(val context: JsIrBackendContext) : DeclarationContainerLoweringPass { +class EnumClassConstructorLowering(val context: CommonBackendContext) : DeclarationContainerLoweringPass { override fun lower(irDeclarationContainer: IrDeclarationContainer) { irDeclarationContainer.transformDeclarationsFlat { declaration -> if (declaration is IrClass && declaration.isEnumClass && @@ -113,7 +114,7 @@ class EnumClassConstructorLowering(val context: JsIrBackendContext) : Declaratio } } -class EnumClassConstructorTransformer(val context: JsIrBackendContext, private val irClass: IrClass) { +class EnumClassConstructorTransformer(val context: CommonBackendContext, private val irClass: IrClass) { private val builder = context.createIrBuilder(irClass.symbol) private val enumEntries = irClass.declarations.filterIsInstance() private val loweredEnumConstructors = HashMap() diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ObjectLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ObjectLowering.kt index 999e891eacc..3c6b1f27856 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ObjectLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ObjectLowering.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.ir.backend.js.lower +import org.jetbrains.kotlin.backend.common.CommonBackendContext import org.jetbrains.kotlin.backend.common.DeclarationContainerLoweringPass import org.jetbrains.kotlin.backend.common.FileLoweringPass import org.jetbrains.kotlin.backend.common.lower.createIrBuilder @@ -19,9 +20,11 @@ import org.jetbrains.kotlin.ir.builders.declarations.buildField import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrDeclarationContainer import org.jetbrains.kotlin.ir.declarations.IrFile +import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.ir.expressions.IrBlockBody import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrGetObjectValue +import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.types.makeNullable import org.jetbrains.kotlin.ir.util.defaultType import org.jetbrains.kotlin.ir.util.isEffectivelyExternal @@ -31,13 +34,16 @@ import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.name.Name -class ObjectDeclarationLowering(val context: JsIrBackendContext) : DeclarationContainerLoweringPass { +class ObjectDeclarationLowering( + val context: CommonBackendContext, + val objectToGetInstanceFunction: MutableMap +) : DeclarationContainerLoweringPass { override fun lower(irDeclarationContainer: IrDeclarationContainer) { irDeclarationContainer.transformDeclarationsFlat { declaration -> if (declaration !is IrClass || declaration.kind != ClassKind.OBJECT || declaration.isEffectivelyExternal()) return@transformDeclarationsFlat null - val getInstanceFun = getOrCreateGetInstanceFunction(context, declaration) + val getInstanceFun = getOrCreateGetInstanceFunction(objectToGetInstanceFunction, declaration) val instanceField = buildField { name = Name.identifier(declaration.name.asString() + "_instance") @@ -70,20 +76,23 @@ class ObjectDeclarationLowering(val context: JsIrBackendContext) : DeclarationCo } } -class ObjectUsageLowering(val context: JsIrBackendContext) : FileLoweringPass { +class ObjectUsageLowering( + val context: CommonBackendContext, + val objectToGetInstanceFunction: MutableMap +) : FileLoweringPass { override fun lower(irFile: IrFile) { irFile.transformChildrenVoid(object : IrElementTransformerVoid() { override fun visitGetObjectValue(expression: IrGetObjectValue): IrExpression { val obj: IrClass = expression.symbol.owner if (obj.isEffectivelyExternal()) return expression - return JsIrBuilder.buildCall(getOrCreateGetInstanceFunction(context, obj).symbol) + return JsIrBuilder.buildCall(getOrCreateGetInstanceFunction(objectToGetInstanceFunction, obj).symbol) } }) } } -fun getOrCreateGetInstanceFunction(context: JsIrBackendContext, obj: IrClass) = - context.objectToGetInstanceFunction.getOrPut(obj.symbol) { +fun getOrCreateGetInstanceFunction(objectToGetInstanceFunction: MutableMap, obj: IrClass) = + objectToGetInstanceFunction.getOrPut(obj.symbol) { JsIrBuilder.buildFunction( obj.name.asString() + "_getInstance", returnType = obj.defaultType, diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/StaticMembersLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/StaticMembersLowering.kt index 8c8a819741f..d420edf2f17 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/StaticMembersLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/StaticMembersLowering.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.ir.backend.js.lower +import org.jetbrains.kotlin.backend.common.CommonBackendContext import org.jetbrains.kotlin.backend.common.FileLoweringPass import org.jetbrains.kotlin.backend.common.ir.addChild import org.jetbrains.kotlin.ir.IrElement @@ -17,7 +18,7 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid // Move static member declarations from classes to top level -class StaticMembersLowering(val context: JsIrBackendContext) : FileLoweringPass { +class StaticMembersLowering(val context: CommonBackendContext) : FileLoweringPass { override fun lower(irFile: IrFile) { val staticDeclarationsInClasses = mutableListOf() diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/inline/ReturnableBlockLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/inline/ReturnableBlockLowering.kt index f07a4888948..78ecc5c8187 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/inline/ReturnableBlockLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/inline/ReturnableBlockLowering.kt @@ -5,9 +5,9 @@ package org.jetbrains.kotlin.ir.backend.js.lower.inline +import org.jetbrains.kotlin.backend.common.CommonBackendContext import org.jetbrains.kotlin.backend.common.FileLoweringPass import org.jetbrains.kotlin.ir.IrStatement -import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder import org.jetbrains.kotlin.ir.declarations.IrDeclaration import org.jetbrains.kotlin.ir.declarations.IrDeclarationParent @@ -69,7 +69,7 @@ import org.jetbrains.kotlin.ir.visitors.IrElementTransformer * } * */ -class ReturnableBlockLowering(val context: JsIrBackendContext) : FileLoweringPass { +class ReturnableBlockLowering(val context: CommonBackendContext) : FileLoweringPass { override fun lower(irFile: IrFile) { irFile.transform(ReturnableBlockTransformer(context), ReturnableBlockLoweringContext(irFile)) } @@ -81,7 +81,7 @@ private class ReturnableBlockLoweringContext(val containingDeclaration: IrDeclar } private class ReturnableBlockTransformer( - val context: JsIrBackendContext + val context: CommonBackendContext ) : IrElementTransformer { override fun visitReturn(expression: IrReturn, data: ReturnableBlockLoweringContext): IrExpression {