[IR] Simplify IrProperty?.isConst check in interpreter

This commit is contained in:
Ivan Kylchik
2023-10-25 11:21:41 +02:00
committed by Space Team
parent a97c0bab0b
commit e827f260e7
6 changed files with 16 additions and 10 deletions
@@ -378,12 +378,12 @@ class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal
else -> callInterceptor.interceptJavaStaticField(expression) else -> callInterceptor.interceptJavaStaticField(expression)
} }
} }
field.origin == IrDeclarationOrigin.PROPERTY_BACKING_FIELD && field.property?.isConst == true -> { field.origin == IrDeclarationOrigin.PROPERTY_BACKING_FIELD && field.property.isConst -> {
callStack.pushCompoundInstruction(field.initializer?.expression) callStack.pushCompoundInstruction(field.initializer?.expression)
} }
expression.accessesTopLevelOrObjectField() -> { expression.accessesTopLevelOrObjectField() -> {
val propertyOwner = field.property val propertyOwner = field.property
val isConst = propertyOwner?.isConst == true || val isConst = propertyOwner.isConst ||
propertyOwner?.backingField?.initializer?.expression is IrConst<*> || propertyOwner?.backingField?.initializer?.expression is IrConst<*> ||
propertyOwner?.parentClassOrNull?.hasAnnotation(compileTimeAnnotation) == true // check if object is marked as compile time propertyOwner?.parentClassOrNull?.hasAnnotation(compileTimeAnnotation) == true // check if object is marked as compile time
verify(isConst) { "Cannot interpret get method on top level non const properties" } verify(isConst) { "Cannot interpret get method on top level non const properties" }
@@ -367,3 +367,6 @@ internal val IrField.property: IrProperty?
internal val IrCall.correspondingProperty: IrProperty? internal val IrCall.correspondingProperty: IrProperty?
get() = this.symbol.owner.correspondingPropertySymbol?.owner get() = this.symbol.owner.correspondingPropertySymbol?.owner
internal val IrProperty?.isConst: Boolean
get() = this?.isConst == true
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.interpreter.hasAnnotation import org.jetbrains.kotlin.ir.interpreter.hasAnnotation
import org.jetbrains.kotlin.ir.interpreter.intrinsicConstEvaluationAnnotation import org.jetbrains.kotlin.ir.interpreter.intrinsicConstEvaluationAnnotation
import org.jetbrains.kotlin.ir.interpreter.isConst
import org.jetbrains.kotlin.ir.interpreter.property import org.jetbrains.kotlin.ir.interpreter.property
import org.jetbrains.kotlin.ir.types.isPrimitiveType import org.jetbrains.kotlin.ir.types.isPrimitiveType
import org.jetbrains.kotlin.ir.types.isString import org.jetbrains.kotlin.ir.types.isString
@@ -59,7 +60,7 @@ enum class EvaluationMode {
).map { IrBuiltIns.KOTLIN_INTERNAL_IR_FQN.child(Name.identifier(it)).asString() }.toSet() ).map { IrBuiltIns.KOTLIN_INTERNAL_IR_FQN.child(Name.identifier(it)).asString() }.toSet()
override fun canEvaluateFunction(function: IrFunction): Boolean { override fun canEvaluateFunction(function: IrFunction): Boolean {
if (function.property?.isConst == true) return true if (function.property.isConst) return true
val returnType = function.returnType val returnType = function.returnType
if (!returnType.isPrimitiveType() && !returnType.isString() && !returnType.isUnsignedType()) return false if (!returnType.isPrimitiveType() && !returnType.isString() && !returnType.isUnsignedType()) return false
@@ -59,7 +59,7 @@ class IrInterpreterCommonChecker : IrInterpreterChecker {
} }
private fun IrCall.isGetterToConstVal(): Boolean { private fun IrCall.isGetterToConstVal(): Boolean {
return correspondingProperty?.isConst == true return correspondingProperty.isConst
} }
override fun visitCall(expression: IrCall, data: IrInterpreterCheckerData): Boolean { override fun visitCall(expression: IrCall, data: IrInterpreterCheckerData): Boolean {
@@ -189,8 +189,8 @@ class IrInterpreterCommonChecker : IrInterpreterChecker {
// its type is flexible (so its not primitive) and there is no initializer at backing field // its type is flexible (so its not primitive) and there is no initializer at backing field
fqName == "java.lang.Boolean.FALSE" || fqName == "java.lang.Boolean.TRUE" -> true fqName == "java.lang.Boolean.FALSE" || fqName == "java.lang.Boolean.TRUE" -> true
isJavaStaticWithPrimitiveOrString() -> owner.initializer?.accept(this, data) == true isJavaStaticWithPrimitiveOrString() -> owner.initializer?.accept(this, data) == true
expression.receiver == null -> property?.isConst == true && owner.initializer?.accept(this, data) == true expression.receiver == null -> property.isConst && owner.initializer?.accept(this, data) == true
owner.origin == IrDeclarationOrigin.PROPERTY_BACKING_FIELD && property?.isConst == true -> { owner.origin == IrDeclarationOrigin.PROPERTY_BACKING_FIELD && property.isConst -> {
val receiverComputable = (expression.receiver?.accept(this, data) ?: true) val receiverComputable = (expression.receiver?.accept(this, data) ?: true)
|| expression.receiver.isAccessToNotNullableObject() || expression.receiver.isAccessToNotNullableObject()
val initializerComputable = owner.initializer?.accept(this, data) ?: false val initializerComputable = owner.initializer?.accept(this, data) ?: false
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrGetObjectValueImpl import org.jetbrains.kotlin.ir.expressions.impl.IrGetObjectValueImpl
import org.jetbrains.kotlin.ir.interpreter.correspondingProperty import org.jetbrains.kotlin.ir.interpreter.correspondingProperty
import org.jetbrains.kotlin.ir.interpreter.isConst
import org.jetbrains.kotlin.ir.interpreter.property import org.jetbrains.kotlin.ir.interpreter.property
import org.jetbrains.kotlin.ir.types.classOrFail import org.jetbrains.kotlin.ir.types.classOrFail
@@ -64,6 +65,6 @@ class IrInterpreterConstGetterPreprocessor : IrInterpreterPreprocessor {
fun IrField.hasConstantValue(): Boolean { fun IrField.hasConstantValue(): Boolean {
val implicitConst = isFinal && isStatic && origin == IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB && initializer != null val implicitConst = isFinal && isStatic && origin == IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB && initializer != null
return implicitConst || property?.isConst == true return implicitConst || property.isConst
} }
} }
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.interpreter.IrInterpreter import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
import org.jetbrains.kotlin.ir.interpreter.checker.EvaluationMode import org.jetbrains.kotlin.ir.interpreter.checker.EvaluationMode
import org.jetbrains.kotlin.ir.interpreter.checker.IrInterpreterChecker import org.jetbrains.kotlin.ir.interpreter.checker.IrInterpreterChecker
import org.jetbrains.kotlin.ir.interpreter.isConst
import org.jetbrains.kotlin.ir.interpreter.property import org.jetbrains.kotlin.ir.interpreter.property
/** /**
@@ -35,7 +36,7 @@ internal class IrConstOnlyNecessaryTransformer(
interpreter, irFile, mode, checker, evaluatedConstTracker, inlineConstTracker, onWarning, onError, suppressExceptions interpreter, irFile, mode, checker, evaluatedConstTracker, inlineConstTracker, onWarning, onError, suppressExceptions
) { ) {
override fun visitCall(expression: IrCall, data: Data): IrElement { override fun visitCall(expression: IrCall, data: Data): IrElement {
val isConstGetter = expression.symbol.owner.property?.isConst == true val isConstGetter = expression.symbol.owner.property.isConst
if (!data.inAnnotation && !isConstGetter) { if (!data.inAnnotation && !isConstGetter) {
expression.transformChildren(this, data) expression.transformChildren(this, data)
return expression return expression
@@ -44,7 +45,7 @@ internal class IrConstOnlyNecessaryTransformer(
} }
override fun visitGetField(expression: IrGetField, data: Data): IrExpression { override fun visitGetField(expression: IrGetField, data: Data): IrExpression {
val isConst = expression.symbol.owner.property?.isConst == true val isConst = expression.symbol.owner.property.isConst
if (!data.inAnnotation && !isConst) return expression if (!data.inAnnotation && !isConst) return expression
return super.visitGetField(expression, data) return super.visitGetField(expression, data)
} }
@@ -58,7 +59,7 @@ internal class IrConstOnlyNecessaryTransformer(
} }
override fun visitField(declaration: IrField, data: Data): IrStatement { override fun visitField(declaration: IrField, data: Data): IrStatement {
val isConst = declaration.property?.isConst == true val isConst = declaration.property.isConst
if (!isConst) { if (!isConst) {
declaration.transformChildren(this, data) declaration.transformChildren(this, data)
return declaration return declaration