This commit is contained in:
Igor Chevdar
2021-09-09 11:43:21 +05:00
parent feeeb16377
commit 23a02be169
3 changed files with 66 additions and 10 deletions
@@ -41,6 +41,10 @@ internal val IrFunction.isFileInitializer: Boolean
|| origin == DECLARATION_ORIGIN_FILE_THREAD_LOCAL_INITIALIZER
|| origin == DECLARATION_ORIGIN_FILE_STANDALONE_THREAD_LOCAL_INITIALIZER
internal val IrFunction.isModuleInitializer: Boolean
get() = origin == DECLARATION_ORIGIN_MODULE_GLOBAL_INITIALIZER
|| origin == DECLARATION_ORIGIN_MODULE_THREAD_LOCAL_INITIALIZER
internal fun IrBuilderWithScope.irCallFileInitializer(initializer: IrFunctionSymbol) =
irCall(initializer)
@@ -82,16 +86,18 @@ internal class FileInitializersLowering(val context: Context) : FileLoweringPass
)
else null
irFile.simpleFunctions().forEach {
val body = it.body ?: return@forEach
val statements = (body as IrBlockBody).statements
context.createIrBuilder(it.symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET).run {
// The order of calling initializers: first global, then thread-local.
// It is ok for a thread local top level property to reference a global, but not vice versa.
threadLocalInitFunction?.let { statements.add(0, irCallFileInitializer(it.symbol)) }
globalInitFunction?.let { statements.add(0, irCallFileInitializer(it.symbol)) }
}
}
irFile.simpleFunctions()
.filterNot { it.isModuleInitializer }
.forEach {
val body = it.body ?: return@forEach
val statements = (body as IrBlockBody).statements
context.createIrBuilder(it.symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET).run {
// The order of calling initializers: first global, then thread-local.
// It is ok for a thread local top level property to reference a global, but not vice versa.
threadLocalInitFunction?.let { statements.add(0, irCallFileInitializer(it.symbol)) }
globalInitFunction?.let { statements.add(0, irCallFileInitializer(it.symbol)) }
}
}
}
private fun buildInitFileFunction(irFile: IrFile, name: String, origin: IrDeclarationOrigin) = context.irFactory.buildFun {
@@ -1523,6 +1523,12 @@ standaloneTest("initializers_eagerInitializationThreadLocal2") {
source = "codegen/initializers/eagerInitializationThreadLocal2.kt"
}
standaloneTest("initializers_testInfrastructure") {
enabled = project.globalTestArgs.contains('-Xir-property-lazy-initialization=enable') || isExperimentalMM
source = "codegen/initializers/testInfrastructure.kt"
flags = ["-tr"]
}
standaloneTest("initializers_workers1") {
expectedFail = (project.testTarget == 'wasm32') // Workers are not supported
source = "codegen/initializers/workers1.kt"
@@ -0,0 +1,44 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
// FILE: lib.kt
var z1 = false
var z2 = false
var t1 = false
var t2 = false
// FILE: lib2.kt
import kotlin.test.*
private val x = foo()
private fun foo(): Int {
z1 = true
return 42
}
@Test
fun test1() {
t1 = true
assertTrue(z1)
assertTrue(t2 || !z2)
}
// FILE: main.kt
import kotlin.test.*
private val x = foo()
private fun foo(): Int {
z2 = true
return 42
}
@Test
fun test2() {
t2 = true
assertTrue(z2)
assertTrue(t1 || !z1)
}