Froze enums on creation + tests
This commit is contained in:
+3
@@ -251,6 +251,9 @@ internal class KonanSymbols(context: Context, val symbolTable: SymbolTable): Sym
|
|||||||
val initInstance = symbolTable.referenceSimpleFunction(
|
val initInstance = symbolTable.referenceSimpleFunction(
|
||||||
context.getInternalFunctions("initInstance").single())
|
context.getInternalFunctions("initInstance").single())
|
||||||
|
|
||||||
|
val freeze = symbolTable.referenceSimpleFunction(
|
||||||
|
builtInsPackage("konan", "worker").getContributedFunctions(Name.identifier("freeze"), NoLookupLocation.FROM_BACKEND).single())
|
||||||
|
|
||||||
val getContinuation = symbolTable.referenceSimpleFunction(
|
val getContinuation = symbolTable.referenceSimpleFunction(
|
||||||
context.getInternalFunctions("getContinuation").single())
|
context.getInternalFunctions("getContinuation").single())
|
||||||
|
|
||||||
|
|||||||
+31
-18
@@ -27,15 +27,19 @@ import org.jetbrains.kotlin.backend.konan.descriptors.synthesizedName
|
|||||||
import org.jetbrains.kotlin.backend.common.ir.addSimpleDelegatingConstructor
|
import org.jetbrains.kotlin.backend.common.ir.addSimpleDelegatingConstructor
|
||||||
import org.jetbrains.kotlin.backend.common.ir.createArrayOfExpression
|
import org.jetbrains.kotlin.backend.common.ir.createArrayOfExpression
|
||||||
import org.jetbrains.kotlin.backend.common.ir.createSimpleDelegatingConstructorDescriptor
|
import org.jetbrains.kotlin.backend.common.ir.createSimpleDelegatingConstructorDescriptor
|
||||||
|
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||||
|
import org.jetbrains.kotlin.backend.common.lower.irBlockBody
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ClassConstructorDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.ClassConstructorDescriptorImpl
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
|
import org.jetbrains.kotlin.ir.builders.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.*
|
import org.jetbrains.kotlin.ir.declarations.impl.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.impl.IrAnonymousInitializerSymbolImpl
|
||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
@@ -44,6 +48,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
|||||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||||
import org.jetbrains.kotlin.types.TypeProjectionImpl
|
import org.jetbrains.kotlin.types.TypeProjectionImpl
|
||||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||||
|
import org.jetbrains.kotlin.types.Variance
|
||||||
|
|
||||||
internal class EnumSyntheticFunctionsBuilder(val context: Context) {
|
internal class EnumSyntheticFunctionsBuilder(val context: Context) {
|
||||||
fun buildValuesExpression(startOffset: Int, endOffset: Int,
|
fun buildValuesExpression(startOffset: Int, endOffset: Int,
|
||||||
@@ -367,29 +372,37 @@ internal class EnumClassLowering(val context: Context) : ClassLoweringPass {
|
|||||||
|
|
||||||
private val arrayGetSymbol = context.ir.symbols.array.functions.single { it.descriptor.name == Name.identifier("get") }
|
private val arrayGetSymbol = context.ir.symbols.array.functions.single { it.descriptor.name == Name.identifier("get") }
|
||||||
|
|
||||||
|
private val genericFreezeSymbol = context.ir.symbols.freeze
|
||||||
|
private val arrayType = context.builtIns.getArrayType(Variance.INVARIANT, irClass.defaultType)
|
||||||
|
|
||||||
private fun createValuesPropertyInitializer(enumEntries: List<IrEnumEntry>): IrAnonymousInitializerImpl {
|
private fun createValuesPropertyInitializer(enumEntries: List<IrEnumEntry>): IrAnonymousInitializerImpl {
|
||||||
val startOffset = irClass.startOffset
|
val startOffset = irClass.startOffset
|
||||||
val endOffset = irClass.endOffset
|
val endOffset = irClass.endOffset
|
||||||
|
|
||||||
val statements = enumEntries
|
val symbol = IrAnonymousInitializerSymbolImpl(loweredEnum.implObject.descriptor)
|
||||||
.sortedBy { it.descriptor.name }
|
val irBuilder = context.createIrBuilder(symbol, startOffset, endOffset)
|
||||||
.withIndex()
|
return IrAnonymousInitializerImpl(startOffset, endOffset, DECLARATION_ORIGIN_ENUM, symbol).apply {
|
||||||
.map {
|
body = irBuilder.irBlockBody(irClass) {
|
||||||
val instances = IrGetFieldImpl(startOffset, endOffset,
|
val instances = irTemporary(irGetField(irGet(loweredEnum.implObject.thisReceiver!!.symbol), loweredEnum.valuesField.symbol))
|
||||||
loweredEnum.valuesField.symbol, IrGetValueImpl(startOffset, endOffset, loweredEnum.implObject.thisReceiver!!.symbol))
|
enumEntries
|
||||||
val instance = IrCallImpl(startOffset, endOffset, arrayGetSymbol).apply {
|
.sortedBy { it.descriptor.name }
|
||||||
dispatchReceiver = instances
|
.withIndex()
|
||||||
putValueArgument(0, IrConstImpl(startOffset, endOffset, context.builtIns.intType, IrConstKind.Int, it.index))
|
.forEach {
|
||||||
}
|
val instance = irCall(arrayGetSymbol).apply {
|
||||||
val initializer = it.value.initializerExpression!! as IrCall
|
dispatchReceiver = irGet(instances.symbol)
|
||||||
IrCallImpl(startOffset, endOffset, initInstanceSymbol).apply {
|
putValueArgument(0, irInt(it.index))
|
||||||
putValueArgument(0, instance)
|
}
|
||||||
putValueArgument(1, initializer)
|
val initializer = it.value.initializerExpression!! as IrCall
|
||||||
}
|
+irCall(initInstanceSymbol).apply {
|
||||||
|
putValueArgument(0, instance)
|
||||||
|
putValueArgument(1, initializer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+irCall(genericFreezeSymbol, listOf(arrayType)).apply {
|
||||||
|
extensionReceiver = irGet(instances.symbol)
|
||||||
}
|
}
|
||||||
return IrAnonymousInitializerImpl(startOffset, endOffset, DECLARATION_ORIGIN_ENUM,
|
}
|
||||||
loweredEnum.implObject.descriptor, IrBlockBodyImpl(startOffset, endOffset, statements)
|
}
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createSyntheticValuesMethodBody(declaration: IrFunction): IrBody {
|
private fun createSyntheticValuesMethodBody(declaration: IrFunction): IrBody {
|
||||||
|
|||||||
@@ -704,6 +704,16 @@ task enum_nested(type: RunKonanTest) {
|
|||||||
source = "codegen/enum/nested.kt"
|
source = "codegen/enum/nested.kt"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
task enum_isFrozen(type: RunKonanTest) {
|
||||||
|
goldValue = "true\n"
|
||||||
|
source = "codegen/enum/isFrozen.kt"
|
||||||
|
}
|
||||||
|
|
||||||
|
task enum_loop(type: RunKonanTest) {
|
||||||
|
goldValue = "Z\nZ\n"
|
||||||
|
source = "codegen/enum/loop.kt"
|
||||||
|
}
|
||||||
|
|
||||||
task mangling(type: LinkKonanTest) {
|
task mangling(type: LinkKonanTest) {
|
||||||
goldValue =
|
goldValue =
|
||||||
"Int direct [1, 2, 3, 4]\n" +
|
"Int direct [1, 2, 3, 4]\n" +
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package codegen.enum.isFrozen
|
||||||
|
|
||||||
|
import kotlin.test.*
|
||||||
|
import konan.worker.*
|
||||||
|
|
||||||
|
enum class Zzz(val zzz: String) {
|
||||||
|
Z1("z1"),
|
||||||
|
Z2("z2")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test fun runTest() {
|
||||||
|
println(Zzz.Z1.isFrozen)
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package codegen.enum.loop
|
||||||
|
|
||||||
|
import kotlin.test.*
|
||||||
|
|
||||||
|
enum class Zzz {
|
||||||
|
Z {
|
||||||
|
init {
|
||||||
|
println(Z.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test fun runTest() {
|
||||||
|
println(Zzz.Z)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user