[K2] Add new class to keep track of evaluated const by IrInterpreter
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.config
|
||||
|
||||
import org.jetbrains.kotlin.constant.EvaluatedConstTracker
|
||||
import org.jetbrains.kotlin.incremental.components.EnumWhenTracker
|
||||
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
|
||||
import org.jetbrains.kotlin.incremental.components.InlineConstTracker
|
||||
@@ -91,6 +92,10 @@ object CommonConfigurationKeys {
|
||||
|
||||
@JvmField
|
||||
val IGNORE_CONST_OPTIMIZATION_ERRORS = CompilerConfigurationKey.create<Boolean>("Ignore errors from IrConstTransformer")
|
||||
|
||||
@JvmField
|
||||
val EVALUATED_CONST_TRACKER =
|
||||
CompilerConfigurationKey.create<EvaluatedConstTracker>("Keeps track of all evaluated by IrInterpreter constants")
|
||||
}
|
||||
|
||||
var CompilerConfiguration.languageVersionSettings: LanguageVersionSettings
|
||||
|
||||
@@ -17,8 +17,10 @@
|
||||
package org.jetbrains.kotlin.fir.backend
|
||||
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.constant.EvaluatedConstTracker
|
||||
|
||||
data class Fir2IrConfiguration(
|
||||
val languageVersionSettings: LanguageVersionSettings,
|
||||
val linkViaSignatures: Boolean
|
||||
val linkViaSignatures: Boolean,
|
||||
val evaluatedConstTracker: EvaluatedConstTracker? = null,
|
||||
)
|
||||
|
||||
@@ -432,7 +432,10 @@ class Fir2IrConverter(
|
||||
val interpreter = IrInterpreter(IrInterpreterEnvironment(irModuleFragment.irBuiltins, configuration))
|
||||
val mode = if (intrinsicConstEvaluation) EvaluationMode.ONLY_INTRINSIC_CONST else EvaluationMode.ONLY_BUILTINS
|
||||
irModuleFragment.files.forEach {
|
||||
it.transformChildren(IrConstTransformer(interpreter, it, mode = mode), null)
|
||||
val transformer = IrConstTransformer(
|
||||
interpreter, it, mode = mode
|
||||
)
|
||||
it.transformChildren(transformer, null)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+6
-2
@@ -24,11 +24,15 @@ class ConstEvaluationLowering(
|
||||
private val onWarning: (IrFile, IrElement, IrErrorExpression) -> Unit = { _, _, _ -> },
|
||||
private val onError: (IrFile, IrElement, IrErrorExpression) -> Unit = { _, _, _ -> },
|
||||
) : FileLoweringPass {
|
||||
val interpreter = IrInterpreter(IrInterpreterEnvironment(context.irBuiltIns, configuration), emptyMap())
|
||||
private val interpreter = IrInterpreter(IrInterpreterEnvironment(context.irBuiltIns, configuration), emptyMap())
|
||||
private val evaluatedConstTracker = context.configuration[CommonConfigurationKeys.EVALUATED_CONST_TRACKER]
|
||||
|
||||
override fun lower(irFile: IrFile) {
|
||||
val transformer = IrConstTransformer(
|
||||
interpreter, irFile, mode = EvaluationMode.ONLY_INTRINSIC_CONST, onWarning, onError, suppressErrors
|
||||
interpreter, irFile,
|
||||
mode = EvaluationMode.ONLY_INTRINSIC_CONST,
|
||||
evaluatedConstTracker,
|
||||
onWarning, onError, suppressErrors
|
||||
)
|
||||
irFile.transformChildren(transformer, null)
|
||||
}
|
||||
|
||||
+25
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.ir.interpreter
|
||||
|
||||
import org.jetbrains.kotlin.builtins.PrimitiveType
|
||||
import org.jetbrains.kotlin.builtins.UnsignedType
|
||||
import org.jetbrains.kotlin.constant.*
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
|
||||
@@ -178,3 +179,27 @@ internal fun IrBuiltIns.emptyArrayConstructor(arrayType: IrType): IrConstructorC
|
||||
}
|
||||
return constructorCall
|
||||
}
|
||||
|
||||
internal fun IrConst<*>.toConstantValue(): ConstantValue<*> {
|
||||
val constType = this.type.makeNotNull().removeAnnotations()
|
||||
return when (this.type.getPrimitiveType()) {
|
||||
PrimitiveType.BOOLEAN -> BooleanValue(this.value as Boolean)
|
||||
PrimitiveType.CHAR -> CharValue(this.value as Char)
|
||||
PrimitiveType.BYTE -> ByteValue((this.value as Number).toByte())
|
||||
PrimitiveType.SHORT -> ShortValue((this.value as Number).toShort())
|
||||
PrimitiveType.INT -> IntValue((this.value as Number).toInt())
|
||||
PrimitiveType.FLOAT -> FloatValue((this.value as Number).toFloat())
|
||||
PrimitiveType.LONG -> LongValue((this.value as Number).toLong())
|
||||
PrimitiveType.DOUBLE -> DoubleValue((this.value as Number).toDouble())
|
||||
null -> when (constType.getUnsignedType()) {
|
||||
UnsignedType.UBYTE -> UByteValue((this.value as Number).toByte())
|
||||
UnsignedType.USHORT -> UShortValue((this.value as Number).toShort())
|
||||
UnsignedType.UINT -> UIntValue((this.value as Number).toInt())
|
||||
UnsignedType.ULONG -> ULongValue((this.value as Number).toLong())
|
||||
null -> when {
|
||||
constType.isString() -> StringValue(this.value as String)
|
||||
else -> error("Cannot convert IrConst ${this.render()} to ConstantValue")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+10
-7
@@ -5,20 +5,17 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.interpreter.checker
|
||||
|
||||
import org.jetbrains.kotlin.constant.ErrorValue
|
||||
import org.jetbrains.kotlin.constant.EvaluatedConstTracker
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrAnnotationContainer
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationBase
|
||||
import org.jetbrains.kotlin.ir.declarations.IrField
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrStringConcatenationImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl
|
||||
import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
|
||||
import org.jetbrains.kotlin.ir.interpreter.IrInterpreterConfiguration
|
||||
import org.jetbrains.kotlin.ir.interpreter.*
|
||||
import org.jetbrains.kotlin.ir.interpreter.isPrimitiveArray
|
||||
import org.jetbrains.kotlin.ir.interpreter.toIrConst
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.dump
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
@@ -29,6 +26,7 @@ class IrConstTransformer(
|
||||
private val interpreter: IrInterpreter,
|
||||
private val irFile: IrFile,
|
||||
private val mode: EvaluationMode,
|
||||
private val evaluatedConstTracker: EvaluatedConstTracker? = null,
|
||||
private val onWarning: (IrFile, IrElement, IrErrorExpression) -> Unit = { _, _, _ -> },
|
||||
private val onError: (IrFile, IrElement, IrErrorExpression) -> Unit = { _, _, _ -> },
|
||||
private val suppressExceptions: Boolean = false,
|
||||
@@ -77,6 +75,11 @@ class IrConstTransformer(
|
||||
throw AssertionError("Error occurred while optimizing an expression:\n${this.dump()}", e)
|
||||
}
|
||||
|
||||
evaluatedConstTracker?.save(
|
||||
this.startOffset, this.endOffset,
|
||||
constant = if (result is IrErrorExpression) ErrorValue.create(result.description)
|
||||
else (result as IrConst<*>).toConstantValue()
|
||||
)
|
||||
return if (failAsError) result.reportIfError(this) else result.warningIfError(this)
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2010-2023 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.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.constant
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
abstract class EvaluatedConstTracker {
|
||||
abstract fun save(start: Int, end: Int, constant: ConstantValue<*>)
|
||||
abstract fun load(start: Int, end: Int): ConstantValue<*>?
|
||||
}
|
||||
|
||||
class DefaultEvaluatedConstTracker : EvaluatedConstTracker() {
|
||||
private val storage = ConcurrentHashMap<Pair<Int, Int>, ConstantValue<*>>()
|
||||
|
||||
override fun save(start: Int, end: Int, constant: ConstantValue<*>) {
|
||||
storage[start to end] = constant
|
||||
}
|
||||
|
||||
override fun load(start: Int, end: Int): ConstantValue<*>? {
|
||||
return storage[start to end]
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user