diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsMapping.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsMapping.kt index c5893825fae..bee8cce355b 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsMapping.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsMapping.kt @@ -26,7 +26,6 @@ class JsMapping : DefaultMapping() { val secondaryConstructorToFactory = DefaultDelegateFactory.newDeclarationToDeclarationMapping() val objectToGetInstanceFunction = DefaultDelegateFactory.newDeclarationToDeclarationMapping() val objectToInstanceField = DefaultDelegateFactory.newDeclarationToDeclarationMapping() - val functionToInstanceField = DefaultDelegateFactory.newDeclarationToDeclarationMapping() val classToSyntheticPrimaryConstructor = DefaultDelegateFactory.newDeclarationToDeclarationMapping() val privateMemberToCorrespondingStatic = DefaultDelegateFactory.newDeclarationToDeclarationMapping() diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmLoweringPhases.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmLoweringPhases.kt index 4c40e8fbb66..876cc78f3ba 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmLoweringPhases.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmLoweringPhases.kt @@ -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( diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/dce/WasmUsefulDeclarationProcessor.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/dce/WasmUsefulDeclarationProcessor.kt index f1296ea4354..43dadecf809 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/dce/WasmUsefulDeclarationProcessor.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/dce/WasmUsefulDeclarationProcessor.kt @@ -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") } diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/dce/WasmUselessDeclarationsRemover.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/dce/WasmUselessDeclarationsRemover.kt index 1e4e0026bef..63cf4e3493f 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/dce/WasmUselessDeclarationsRemover.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/dce/WasmUselessDeclarationsRemover.kt @@ -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 } } } \ No newline at end of file diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/FieldInitializersLowering.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/FieldInitializersLowering.kt index c163b9ed5d6..b8981be63b8 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/FieldInitializersLowering.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/FieldInitializersLowering.kt @@ -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) } diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/WasmStaticCallableReferenceLowering.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/WasmStaticCallableReferenceLowering.kt index 0140811f931..3edf9eafaa0 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/WasmStaticCallableReferenceLowering.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/WasmStaticCallableReferenceLowering.kt @@ -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() - 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 diff --git a/compiler/testData/debug/stepping/anonymousFunction.kt b/compiler/testData/debug/stepping/anonymousFunction.kt index 4f0c7274bb9..d30df8d24ab 100644 --- a/compiler/testData/debug/stepping/anonymousFunction.kt +++ b/compiler/testData/debug/stepping/anonymousFunction.kt @@ -25,7 +25,7 @@ fun box() { // EXPECTATIONS WASM // test.kt:1 $box -// test.kt:7 $box (9, 4) +// test.kt:7 $box // test.kt:4 $eval (27, 30) // test.kt:8 $box$lambda.invoke (9, 9, 9, 9) // String.kt:141 $kotlin.stringLiteral (17, 28, 17) diff --git a/compiler/testData/debug/stepping/dataClass.kt b/compiler/testData/debug/stepping/dataClass.kt index 9487645ee28..eeac542d1c3 100644 --- a/compiler/testData/debug/stepping/dataClass.kt +++ b/compiler/testData/debug/stepping/dataClass.kt @@ -248,7 +248,7 @@ fun box() { // Number2String.kt:61 $kotlin.wasm.internal.utoa32 (28, 14) // Number2String.kt:63 $kotlin.wasm.internal.utoa32 (18, 23, 35, 4) // Number2String.kt:69 $kotlin.wasm.internal.utoaDecSimple (11, 23, 11, 11, 4) -// Assertions.kt:14 $kotlin.assert (11, 18, 4, 11, 18, 4, 11, 18, 4, 11, 18, 4) +// Assertions.kt:14 $kotlin.assert (11, 4, 11, 4, 11, 4, 11, 4) // Assertions.kt:21 $kotlin.assert (9, 8, 9, 8, 9, 8, 9, 8) // Assertions.kt:25 $kotlin.assert (1, 1, 1, 1) // Assertions.kt:15 $kotlin.assert (1, 1, 1, 1) diff --git a/compiler/testData/debug/stepping/functionCallWithLambdaParam.kt b/compiler/testData/debug/stepping/functionCallWithLambdaParam.kt index 7606e040b15..8d53c49d996 100644 --- a/compiler/testData/debug/stepping/functionCallWithLambdaParam.kt +++ b/compiler/testData/debug/stepping/functionCallWithLambdaParam.kt @@ -45,10 +45,10 @@ fun foo(f: () -> Unit) { // EXPECTATIONS WASM // test.kt:1 $box -// test.kt:5 $box (8, 4) +// test.kt:5 $box // test.kt:15 $foo (4, 4) // test.kt:6 $box$lambda.invoke (20, 12, 21) // test.kt:16 $foo (1, 1) -// test.kt:9 $box (10, 4) +// test.kt:9 $box // test.kt:10 $box$lambda.invoke (16, 8, 17) // test.kt:12 $box diff --git a/compiler/testData/debug/stepping/kt42208.kt b/compiler/testData/debug/stepping/kt42208.kt index c20598f99bb..a0cc1071db4 100644 --- a/compiler/testData/debug/stepping/kt42208.kt +++ b/compiler/testData/debug/stepping/kt42208.kt @@ -27,7 +27,6 @@ inline fun foo() = { // EXPECTATIONS WASM // test.kt:1 $box // test.kt:6 $box (4, 4) -// test1.kt:10 $box // test1.kt:11 $box // test.kt:8 $box$lambda.invoke // test.kt:7 $box diff --git a/compiler/testData/debug/stepping/kt42208b.kt b/compiler/testData/debug/stepping/kt42208b.kt index 01fcb1f1589..b80f00c8bf8 100644 --- a/compiler/testData/debug/stepping/kt42208b.kt +++ b/compiler/testData/debug/stepping/kt42208b.kt @@ -30,7 +30,6 @@ inline fun foo() = { // EXPECTATIONS WASM // test.kt:1 $box // test.kt:6 $box -// test1.kt:11 $box // test1.kt:12 $box // test.kt:7 $box // test.kt:9 $box$lambda.invoke diff --git a/compiler/testData/debug/stepping/kt42208c.kt b/compiler/testData/debug/stepping/kt42208c.kt index 93d683e78ff..c1efa8ee685 100644 --- a/compiler/testData/debug/stepping/kt42208c.kt +++ b/compiler/testData/debug/stepping/kt42208c.kt @@ -52,7 +52,6 @@ fun baz(v:(() -> Unit)) { // EXPECTATIONS WASM // test.kt:1 $box // test.kt:6 $box (8, 4) -// test1.kt:12 $box (19, 19) // test1.kt:13 $box (1, 1) // test3.kt:16 $baz (4, 4) // test.kt:10 $box$lambda.invoke diff --git a/compiler/testData/debug/stepping/namedCallableReference.kt b/compiler/testData/debug/stepping/namedCallableReference.kt index 33105c8d5eb..f6618027391 100644 --- a/compiler/testData/debug/stepping/namedCallableReference.kt +++ b/compiler/testData/debug/stepping/namedCallableReference.kt @@ -35,7 +35,7 @@ fun g() {} // EXPECTATIONS WASM // test.kt:1 $box // test.kt:4 $box (12, 4) -// test.kt:5 $box (6, 4) +// test.kt:5 $box // test.kt:9 $f // test.kt:12 $g // test.kt:10 $f diff --git a/compiler/testData/debug/stepping/variablesWithoutInitializer.kt b/compiler/testData/debug/stepping/variablesWithoutInitializer.kt index e4a3e17eaa5..c16d6a2da63 100644 --- a/compiler/testData/debug/stepping/variablesWithoutInitializer.kt +++ b/compiler/testData/debug/stepping/variablesWithoutInitializer.kt @@ -68,7 +68,7 @@ fun box() { // Number2String.kt:61 $kotlin.wasm.internal.utoa32 (28, 14) // Number2String.kt:63 $kotlin.wasm.internal.utoa32 (18, 23, 35, 4) // Number2String.kt:69 $kotlin.wasm.internal.utoaDecSimple (11, 23, 11, 11, 4) -// Assertions.kt:14 $kotlin.assert (11, 18, 4, 11, 18, 4, 11, 18, 4, 11, 18, 4, 11, 18, 4) +// Assertions.kt:14 $kotlin.assert (11, 4, 11, 4, 11, 4, 11, 4, 11, 4) // Assertions.kt:21 $kotlin.assert (9, 8, 9, 8, 9, 8, 9, 8, 9, 8) // Assertions.kt:25 $kotlin.assert (1, 1, 1, 1, 1) // Assertions.kt:15 $kotlin.assert (1, 1, 1, 1, 1)