[JS IR & WASM] Fix executing init blocks for enums with nested objects

This commit is contained in:
Sergej Jaskiewicz
2021-10-13 17:06:32 +03:00
committed by Space
parent 8e0e2fe52c
commit 9e5520bba8
11 changed files with 164 additions and 34 deletions
@@ -755,7 +755,8 @@ private val staticMembersLoweringPhase = makeDeclarationTransformerPhase(
private val objectDeclarationLoweringPhase = makeDeclarationTransformerPhase(
::ObjectDeclarationLowering,
name = "ObjectDeclarationLowering",
description = "Create lazy object instance generator functions"
description = "Create lazy object instance generator functions",
prerequisite = setOf(enumClassCreateInitializerLoweringPhase)
)
private val invokeStaticInitializersPhase = makeBodyLoweringPhase(
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
class ObjectDeclarationLowering(
val context: JsCommonBackendContext
@@ -34,6 +35,11 @@ class ObjectDeclarationLowering(
private var IrClass.instanceField by context.mapping.objectToInstanceField
private var IrClass.syntheticPrimaryConstructor by context.mapping.classToSyntheticPrimaryConstructor
/**
* If the object being lowered is nested inside an enum class, we want to also initialize the enum entries when initializing the object.
*/
private var IrClass.initEntryInstancesFun: IrSimpleFunction? by context.mapping.enumClassToInitEntryInstancesFun
override fun transformFlat(declaration: IrDeclaration): List<IrDeclaration>? {
if (declaration !is IrClass || declaration.kind != ClassKind.OBJECT || declaration.isEffectivelyExternal())
return null
@@ -54,8 +60,12 @@ class ObjectDeclarationLowering(
val primaryConstructor = declaration.primaryConstructor ?: declaration.syntheticPrimaryConstructor!!
val initEntryInstancesFun = declaration.parent.safeAs<IrClass>()?.initEntryInstancesFun
getInstanceFun.body = context.irFactory.createBlockBody(UNDEFINED_OFFSET, UNDEFINED_OFFSET) {
statements += context.createIrBuilder(getInstanceFun.symbol).irBlockBody(getInstanceFun) {
if (initEntryInstancesFun != null)
+irCall(initEntryInstancesFun)
+irIfThen(
irEqualsNull(irGetField(null, instanceField)),
// Instance field initialized inside constructor
@@ -421,7 +421,8 @@ private val builtInsLoweringPhase = makeWasmModulePhase(
private val objectDeclarationLoweringPhase = makeWasmModulePhase(
::ObjectDeclarationLowering,
name = "ObjectDeclarationLowering",
description = "Create lazy object instance generator functions"
description = "Create lazy object instance generator functions",
prerequisite = setOf(enumClassCreateInitializerLoweringPhase)
)
private val objectUsageLoweringPhase = makeWasmModulePhase(