[JS IR BE] Commonize JS lowerings

This commit is contained in:
Svyatoslav Kuzmich
2019-08-07 14:16:48 +03:00
parent 7bc739359b
commit 1891fa1bf1
9 changed files with 52 additions and 29 deletions
@@ -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
)
)
@@ -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
@@ -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))
}
}
@@ -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)
@@ -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)
@@ -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<IrEnumEntry>()
private val loweredEnumConstructors = HashMap<IrConstructorSymbol, IrConstructor>()
@@ -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<IrClassSymbol, IrSimpleFunction>
) : 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<IrClassSymbol, IrSimpleFunction>
) : 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<IrClassSymbol, IrSimpleFunction>, obj: IrClass) =
objectToGetInstanceFunction.getOrPut(obj.symbol) {
JsIrBuilder.buildFunction(
obj.name.asString() + "_getInstance",
returnType = obj.defaultType,
@@ -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<IrDeclaration>()
@@ -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<ReturnableBlockLoweringContext> {
override fun visitReturn(expression: IrReturn, data: ReturnableBlockLoweringContext): IrExpression {