[K/Wasm] Refactor the fix for the non-capturing lambda singletons
This commit is contained in:
+8
-7
@@ -475,12 +475,6 @@ private val wasmVarargExpressionLoweringPhase = makeIrModulePhase(
|
||||
description = "Lower varargs"
|
||||
)
|
||||
|
||||
private val fieldInitializersLoweringPhase = makeIrModulePhase(
|
||||
::FieldInitializersLowering,
|
||||
name = "FieldInitializersLowering",
|
||||
description = "Move field initializers to start function"
|
||||
)
|
||||
|
||||
private val builtInsLoweringPhase0 = makeIrModulePhase(
|
||||
::BuiltInsLowering,
|
||||
name = "BuiltInsLowering0",
|
||||
@@ -505,7 +499,7 @@ private val objectDeclarationLoweringPhase = makeIrModulePhase(
|
||||
::ObjectDeclarationLowering,
|
||||
name = "ObjectDeclarationLowering",
|
||||
description = "Create lazy object instance generator functions",
|
||||
prerequisite = setOf(enumClassCreateInitializerLoweringPhase)
|
||||
prerequisite = setOf(enumClassCreateInitializerLoweringPhase, staticCallableReferenceLoweringPhase)
|
||||
)
|
||||
|
||||
private val objectUsageLoweringPhase = makeIrModulePhase(
|
||||
@@ -606,6 +600,13 @@ private val inlineObjectsWithPureInitializationLoweringPhase = makeIrModulePhase
|
||||
prerequisite = setOf(purifyObjectInstanceGettersLoweringPhase)
|
||||
)
|
||||
|
||||
private val fieldInitializersLoweringPhase = makeIrModulePhase(
|
||||
::FieldInitializersLowering,
|
||||
name = "FieldInitializersLowering",
|
||||
description = "Move field initializers to start function",
|
||||
prerequisite = setOf(purifyObjectInstanceGettersLoweringPhase)
|
||||
)
|
||||
|
||||
val constEvaluationPhase = makeIrModulePhase(
|
||||
{ context ->
|
||||
val configuration = IrInterpreterConfiguration(
|
||||
|
||||
+2
-3
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.backend.wasm.dce
|
||||
|
||||
import org.jetbrains.kotlin.backend.wasm.WasmBackendContext
|
||||
import org.jetbrains.kotlin.backend.wasm.ir2wasm.*
|
||||
import org.jetbrains.kotlin.backend.wasm.lower.isFunctionReferenceInstanceField
|
||||
import org.jetbrains.kotlin.backend.wasm.utils.*
|
||||
import org.jetbrains.kotlin.ir.backend.js.dce.UsefulDeclarationProcessor
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.*
|
||||
@@ -49,7 +48,7 @@ internal class WasmUsefulDeclarationProcessor(
|
||||
}
|
||||
|
||||
override fun visitSetField(expression: IrSetField, data: IrDeclaration) {
|
||||
if (!expression.symbol.owner.run { isObjectInstanceField() || isFunctionReferenceInstanceField() }) {
|
||||
if (!expression.symbol.owner.isObjectInstanceField()) {
|
||||
super.visitSetField(expression, data)
|
||||
}
|
||||
}
|
||||
@@ -57,7 +56,7 @@ internal class WasmUsefulDeclarationProcessor(
|
||||
override fun visitGetField(expression: IrGetField, data: IrDeclaration) {
|
||||
val field = expression.symbol.owner
|
||||
|
||||
if (field.isObjectInstanceField() || field.isFunctionReferenceInstanceField()) {
|
||||
if (field.isObjectInstanceField()) {
|
||||
field.type.classOrFail.owner.primaryConstructor?.enqueue(field, "object lazy initialization")
|
||||
}
|
||||
|
||||
|
||||
+1
-4
@@ -6,14 +6,11 @@
|
||||
package org.jetbrains.kotlin.backend.wasm.dce
|
||||
|
||||
import org.jetbrains.kotlin.backend.wasm.WasmBackendContext
|
||||
import org.jetbrains.kotlin.backend.wasm.lower.isFunctionReferenceInstanceField
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.isObjectInstanceField
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrBlockBody
|
||||
import org.jetbrains.kotlin.ir.expressions.IrSetField
|
||||
import org.jetbrains.kotlin.ir.types.classOrFail
|
||||
import org.jetbrains.kotlin.ir.util.primaryConstructor
|
||||
import org.jetbrains.kotlin.ir.util.transformFlat
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||
@@ -57,7 +54,7 @@ class WasmUselessDeclarationsRemover(
|
||||
|
||||
private fun IrSimpleFunction.removeUnusedObjectsInitializers() {
|
||||
(body as? IrBlockBody)?.statements?.removeIf {
|
||||
it is IrSetField && it.symbol.owner.run { isObjectInstanceField() || isFunctionReferenceInstanceField() } && it.symbol.owner !in usefulDeclarations
|
||||
it is IrSetField && it.symbol.owner.isObjectInstanceField() && it.symbol.owner !in usefulDeclarations
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
-2
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.backend.common.lower.at
|
||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.backend.wasm.WasmBackendContext
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.isObjectInstanceField
|
||||
import org.jetbrains.kotlin.ir.builders.irSetField
|
||||
import org.jetbrains.kotlin.ir.declarations.IrField
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
@@ -55,9 +56,11 @@ class FieldInitializersLowering(val context: WasmBackendContext) : FileLoweringP
|
||||
}
|
||||
|
||||
val initializerStatement = builder.at(initValue).irSetField(null, declaration, initValue)
|
||||
val statements = startFunctionBody.statements
|
||||
|
||||
when (declaration.fqNameWhenAvailable) {
|
||||
stringPoolFqName -> startFunctionBody.statements.add(0, initializerStatement)
|
||||
when {
|
||||
declaration.fqNameWhenAvailable == stringPoolFqName -> statements.add(0, initializerStatement)
|
||||
declaration.isObjectInstanceField() -> statements.add(if (statements.size >= 1) 1 else 0, initializerStatement)
|
||||
else -> startFunctionBody.statements.add(initializerStatement)
|
||||
}
|
||||
|
||||
|
||||
+4
-40
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.backend.common.getOrPut
|
||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.backend.wasm.WasmBackendContext
|
||||
import org.jetbrains.kotlin.backend.wasm.lower.WasmPropertyReferenceLowering.Companion.DECLARATION_ORIGIN_KPROPERTIES_FOR_DELEGATION
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.CallableReferenceLowering.Companion.FUNCTION_REFERENCE_IMPL
|
||||
@@ -21,6 +22,7 @@ import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetFieldImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetObjectValueImpl
|
||||
import org.jetbrains.kotlin.ir.types.makeNullable
|
||||
import org.jetbrains.kotlin.ir.util.constructedClass
|
||||
import org.jetbrains.kotlin.ir.util.defaultType
|
||||
@@ -31,20 +33,11 @@ import org.jetbrains.kotlin.name.Name
|
||||
|
||||
class WasmStaticCallableReferenceLowering(val context: WasmBackendContext) : FileLoweringPass {
|
||||
override fun lower(irFile: IrFile) {
|
||||
val irFields = mutableSetOf<IrField>()
|
||||
val firstKProperty = irFile.declarations.indexOfFirst { it.origin == DECLARATION_ORIGIN_KPROPERTIES_FOR_DELEGATION }
|
||||
|
||||
irFile.transformChildrenVoid(object : IrElementTransformerVoid() {
|
||||
override fun visitClass(declaration: IrClass): IrStatement {
|
||||
declaration.transformChildrenVoid()
|
||||
if (declaration.isSyntheticSingleton) {
|
||||
val functionReferenceField = declaration.getOrCreateInstanceField().apply {
|
||||
parent = irFile
|
||||
initializer = context.createIrBuilder(symbol).run {
|
||||
irExprBody(irCall(declaration.primaryConstructor!!))
|
||||
}
|
||||
}
|
||||
irFields.add(functionReferenceField)
|
||||
declaration.kind = ClassKind.OBJECT
|
||||
}
|
||||
return declaration
|
||||
}
|
||||
@@ -54,39 +47,10 @@ class WasmStaticCallableReferenceLowering(val context: WasmBackendContext) : Fil
|
||||
if (!constructedClass.isSyntheticSingleton)
|
||||
return super.visitConstructorCall(expression)
|
||||
|
||||
val instanceField = constructedClass.getOrCreateInstanceField()
|
||||
return IrGetFieldImpl(expression.startOffset, expression.endOffset, instanceField.symbol, expression.type)
|
||||
return IrGetObjectValueImpl(expression.startOffset, expression.endOffset, expression.type, constructedClass.symbol)
|
||||
}
|
||||
})
|
||||
|
||||
// Should be placed before KProperty initializations
|
||||
if (firstKProperty != -1) {
|
||||
irFile.declarations.addAll(firstKProperty, irFields)
|
||||
} else {
|
||||
irFile.declarations.addAll(irFields)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun IrClass.getOrCreateInstanceField(): IrField = context.mapping.functionToInstanceField.getOrPut(this) {
|
||||
val klass = this
|
||||
context.irFactory.buildField {
|
||||
name = Name.identifier(klass.name.asString() + "_instance")
|
||||
type = klass.defaultType.makeNullable()
|
||||
isStatic = true
|
||||
isFinal = true
|
||||
origin = FUNCTION_REFERENCE_SINGLETON_FIELD
|
||||
visibility = DescriptorVisibilities.PRIVATE
|
||||
}.apply {
|
||||
initializer = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val FUNCTION_REFERENCE_SINGLETON_FIELD by IrDeclarationOriginImpl
|
||||
|
||||
fun IrField.isFunctionReferenceInstanceField(): Boolean {
|
||||
return origin == FUNCTION_REFERENCE_SINGLETON_FIELD
|
||||
}
|
||||
|
||||
val IrClass.isSyntheticSingleton: Boolean
|
||||
|
||||
Reference in New Issue
Block a user