[JS_IR] Forbid to inline constants during const lowering

This commit is contained in:
Ivan Kylchik
2023-06-16 20:44:44 +02:00
committed by Space Team
parent d3d28783c5
commit 31e75cc603
5 changed files with 30 additions and 21 deletions
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.platform.TargetPlatform
* @param createNonCompileTimeObjects
* 'true' - interpreter will construct object and initialize its properties despite the fact it is not marked as compile time;
* 'false' - interpreter will create a representation of empty object, that can be used to get const properties
* @param inlineConstVal tell the interpreter that value of const property can be inlined instead of getter call
*/
// TODO maybe create some sort of builder
data class IrInterpreterConfiguration(
@@ -23,4 +24,5 @@ data class IrInterpreterConfiguration(
val createNonCompileTimeObjects: Boolean = false,
val printOnlyExceptionMessage: Boolean = false,
val collapseStackTraceFromJDK: Boolean = true,
val inlineConstVal: Boolean = true,
)
@@ -6,12 +6,14 @@
package org.jetbrains.kotlin.ir.interpreter.checker
import org.jetbrains.kotlin.ir.IrBuiltIns
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.interpreter.IrInterpreterConfiguration
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
interface IrInterpreterChecker : IrElementVisitor<Boolean, IrInterpreterCheckerData>
class IrInterpreterCheckerData(
val irFile: IrFile,
val mode: EvaluationMode,
val irBuiltIns: IrBuiltIns,
val interpreterConfiguration: IrInterpreterConfiguration,
@@ -15,7 +15,7 @@ import org.jetbrains.kotlin.ir.interpreter.isAccessToNotNullableObject
import org.jetbrains.kotlin.ir.interpreter.preprocessor.IrInterpreterKCallableNamePreprocessor.Companion.isEnumName
import org.jetbrains.kotlin.ir.interpreter.preprocessor.IrInterpreterKCallableNamePreprocessor.Companion.isKCallableNameCall
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.constructors
import org.jetbrains.kotlin.ir.util.fileOrNull
import org.jetbrains.kotlin.ir.util.parentAsClass
import org.jetbrains.kotlin.ir.util.statements
@@ -59,22 +59,20 @@ class IrInterpreterCommonChecker : IrInterpreterChecker {
override fun visitCall(expression: IrCall, data: IrInterpreterCheckerData): Boolean {
val owner = expression.symbol.owner
if (expression.dispatchReceiver.isAccessToNotNullableObject() && expression.isGetterToConstVal()) {
return visitBodyIfNeeded(owner, data)
return when {
!data.interpreterConfiguration.inlineConstVal && expression.isGetterToConstVal() && data.irFile != owner.fileOrNull -> false
expression.dispatchReceiver.isAccessToNotNullableObject() && expression.isGetterToConstVal() -> visitBodyIfNeeded(owner, data)
!data.mode.canEvaluateExpression(expression) || !data.mode.canEvaluateFunction(owner) -> false
expression.isKCallableNameCall(data.irBuiltIns) || expression.isEnumName() -> true
else -> {
val dispatchReceiverComputable = expression.dispatchReceiver?.accept(this, data) ?: true
val extensionReceiverComputable = expression.extensionReceiver?.accept(this, data) ?: true
dispatchReceiverComputable &&
extensionReceiverComputable &&
visitValueArguments(expression, data) &&
visitBodyIfNeeded(owner, data)
}
}
if (!data.mode.canEvaluateExpression(expression)) return false
if (!data.mode.canEvaluateFunction(owner)) return false
if (expression.isKCallableNameCall(data.irBuiltIns) || expression.isEnumName()) return true
val dispatchReceiverComputable = expression.dispatchReceiver?.accept(this, data) ?: true
val extensionReceiverComputable = expression.extensionReceiver?.accept(this, data) ?: true
if (!visitValueArguments(expression, data)) return false
val bodyComputable = visitBodyIfNeeded(owner, data)
return dispatchReceiverComputable && extensionReceiverComputable && bodyComputable
}
override fun visitVariable(declaration: IrVariable, data: IrInterpreterCheckerData): Boolean {
@@ -176,6 +174,7 @@ class IrInterpreterCommonChecker : IrInterpreterChecker {
return owner.origin == IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB && owner.isStatic && owner.isFinal &&
(owner.type.isPrimitiveType() || owner.type.isStringClassType())
}
return owner.asVisited {
when {
// TODO fix later; used it here because java boolean resolves very strange,
@@ -119,7 +119,7 @@ internal abstract class IrConstTransformer(
configuration: IrInterpreterConfiguration = interpreter.environment.configuration
): Boolean {
return try {
this.accept(checker, IrInterpreterCheckerData(mode, interpreter.irBuiltIns, configuration))
this.accept(checker, IrInterpreterCheckerData(irFile, mode, interpreter.irBuiltIns, configuration))
} catch (e: Throwable) {
if (suppressExceptions) {
return false