diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/interpreter/IrInterpreter.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/interpreter/IrInterpreter.kt index 1a854728848..b908ec253d0 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/interpreter/IrInterpreter.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/interpreter/IrInterpreter.kt @@ -38,7 +38,7 @@ class IrInterpreter(irModule: IrModuleFragment) { private val stackTrace = mutableListOf() - private val mapOfEnums = mutableMapOf, Common>() + private val mapOfEnums = mutableMapOf, Complex>() private fun Any?.getType(defaultType: IrType): IrType { return when (this) { @@ -624,6 +624,18 @@ class IrInterpreter(irModule: IrModuleFragment) { val enumEntry = expression.symbol.owner val enumSignature = Pair(enumEntry.parentAsClass, enumEntry.name.asString()) mapOfEnums[enumSignature]?.let { return Code.NEXT.apply { data.pushReturnValue(it) } } + + val enumClass = enumEntry.symbol.owner.parentAsClass + if (enumClass.hasAnnotation(evaluateIntrinsicAnnotation)) { + val valueOfFun = enumClass.declarations.single { it.nameForIrSerialization.asString() == "valueOf" } as IrFunction + val enumName = Variable(valueOfFun.valueParameters.first().descriptor, enumEntry.name.asString().toState(irBuiltIns.stringType)) + val newFrame = InterpreterFrame(mutableListOf(enumName)) + return Wrapper.getEnumEntry(enumClass)!!.invokeMethod(valueOfFun, newFrame).apply { + if (this == Code.NEXT) mapOfEnums[enumSignature] = newFrame.peekReturnValue() as Wrapper + data.pushReturnValue(newFrame) + } + } + return interpretEnumEntry(enumEntry, data).apply { if (this == Code.NEXT) mapOfEnums[enumSignature] = data.peekReturnValue() as Common } diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/interpreter/stack/State.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/interpreter/stack/State.kt index 786cff16e59..7a12dd8f3a2 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/interpreter/stack/State.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/interpreter/stack/State.kt @@ -6,9 +6,7 @@ package org.jetbrains.kotlin.backend.common.interpreter.stack import org.jetbrains.kotlin.backend.common.interpreter.* -import org.jetbrains.kotlin.backend.common.interpreter.builtins.CompileTimeFunction import org.jetbrains.kotlin.backend.common.interpreter.builtins.evaluateIntrinsicAnnotation -import org.jetbrains.kotlin.backend.common.interpreter.builtins.unaryFunctions import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor @@ -17,8 +15,6 @@ import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.declarations.IrProperty import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl -import org.jetbrains.kotlin.ir.expressions.IrGetValue -import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.* @@ -192,6 +188,15 @@ class Wrapper(val value: Any, override val irClass: IrClass) : Complex(irClass, return MethodHandles.lookup().findStatic(jvmClassName, irFunction.name.asString(), methodType) } + fun getEnumEntry(enumClass: IrClass): MethodHandle? { + val intrinsicName = enumClass.getEvaluateIntrinsicValue() + if (intrinsicName?.isEmpty() == true) return null + val enumClassName = Class.forName(intrinsicName!!) + + val methodType = MethodType.methodType(enumClassName, String::class.java) + return MethodHandles.lookup().findStatic(enumClassName, "valueOf", methodType) + } + private fun IrFunction.getMethodType(): MethodType { val argsClasses = this.valueParameters.map { it.type.getClass(this.isValueParameterPrimitiveAsObject(it.index)) } return if (this is IrFunctionImpl) {