[IR] Simplify access to IrProperty from IrCall and IrField in interpreter

This commit is contained in:
Ivan Kylchik
2023-10-25 11:18:37 +02:00
committed by Space Team
parent 604c8edd1c
commit a97c0bab0b
7 changed files with 28 additions and 14 deletions
@@ -378,11 +378,11 @@ class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal
else -> callInterceptor.interceptJavaStaticField(expression) else -> callInterceptor.interceptJavaStaticField(expression)
} }
} }
field.origin == IrDeclarationOrigin.PROPERTY_BACKING_FIELD && field.correspondingPropertySymbol?.owner?.isConst == true -> { field.origin == IrDeclarationOrigin.PROPERTY_BACKING_FIELD && field.property?.isConst == true -> {
callStack.pushCompoundInstruction(field.initializer?.expression) callStack.pushCompoundInstruction(field.initializer?.expression)
} }
expression.accessesTopLevelOrObjectField() -> { expression.accessesTopLevelOrObjectField() -> {
val propertyOwner = field.correspondingPropertySymbol?.owner val propertyOwner = field.property
val isConst = propertyOwner?.isConst == true || val isConst = propertyOwner?.isConst == true ||
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
@@ -17,7 +17,10 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
import org.jetbrains.kotlin.ir.interpreter.exceptions.handleUserException import org.jetbrains.kotlin.ir.interpreter.exceptions.handleUserException
import org.jetbrains.kotlin.ir.interpreter.proxy.wrap import org.jetbrains.kotlin.ir.interpreter.proxy.wrap
import org.jetbrains.kotlin.ir.interpreter.stack.CallStack import org.jetbrains.kotlin.ir.interpreter.stack.CallStack
import org.jetbrains.kotlin.ir.interpreter.state.* import org.jetbrains.kotlin.ir.interpreter.state.Common
import org.jetbrains.kotlin.ir.interpreter.state.Primitive
import org.jetbrains.kotlin.ir.interpreter.state.State
import org.jetbrains.kotlin.ir.interpreter.state.isSubtypeOf
import org.jetbrains.kotlin.ir.interpreter.state.reflection.KTypeState import org.jetbrains.kotlin.ir.interpreter.state.reflection.KTypeState
import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.types.*
@@ -318,7 +321,7 @@ internal fun IrExpression?.isAccessToNotNullableObject(): Boolean {
} }
internal fun IrFunction.isAccessorOfPropertyWithBackingField(): Boolean { internal fun IrFunction.isAccessorOfPropertyWithBackingField(): Boolean {
return this is IrSimpleFunction && this.correspondingPropertySymbol?.owner?.backingField?.initializer != null return property?.backingField?.initializer != null
} }
internal fun State.unsignedToString(): String { internal fun State.unsignedToString(): String {
@@ -359,3 +362,8 @@ internal fun IrEnumEntry.toState(irBuiltIns: IrBuiltIns): Common {
internal val IrFunction.property: IrProperty? internal val IrFunction.property: IrProperty?
get() = (this as? IrSimpleFunction)?.correspondingPropertySymbol?.owner get() = (this as? IrSimpleFunction)?.correspondingPropertySymbol?.owner
internal val IrField.property: IrProperty?
get() = this.correspondingPropertySymbol?.owner
internal val IrCall.correspondingProperty: IrProperty?
get() = this.symbol.owner.correspondingPropertySymbol?.owner
@@ -9,7 +9,9 @@ import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.interpreter.*
import org.jetbrains.kotlin.ir.interpreter.accessesTopLevelOrObjectField import org.jetbrains.kotlin.ir.interpreter.accessesTopLevelOrObjectField
import org.jetbrains.kotlin.ir.interpreter.correspondingProperty
import org.jetbrains.kotlin.ir.interpreter.fqName import org.jetbrains.kotlin.ir.interpreter.fqName
import org.jetbrains.kotlin.ir.interpreter.isAccessToNotNullableObject 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.isEnumName
@@ -57,7 +59,7 @@ class IrInterpreterCommonChecker : IrInterpreterChecker {
} }
private fun IrCall.isGetterToConstVal(): Boolean { private fun IrCall.isGetterToConstVal(): Boolean {
return symbol.owner.correspondingPropertySymbol?.owner?.isConst == true return correspondingProperty?.isConst == true
} }
override fun visitCall(expression: IrCall, data: IrInterpreterCheckerData): Boolean { override fun visitCall(expression: IrCall, data: IrInterpreterCheckerData): Boolean {
@@ -171,7 +173,7 @@ class IrInterpreterCommonChecker : IrInterpreterChecker {
override fun visitGetField(expression: IrGetField, data: IrInterpreterCheckerData): Boolean { override fun visitGetField(expression: IrGetField, data: IrInterpreterCheckerData): Boolean {
val owner = expression.symbol.owner val owner = expression.symbol.owner
val property = owner.correspondingPropertySymbol?.owner val property = owner.property
val fqName = owner.fqName val fqName = owner.fqName
fun isJavaStaticWithPrimitiveOrString(): Boolean { fun isJavaStaticWithPrimitiveOrString(): Boolean {
return owner.origin == IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB && owner.isStatic && owner.isFinal && return owner.origin == IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB && owner.isStatic && owner.isFinal &&
@@ -206,7 +208,7 @@ class IrInterpreterCommonChecker : IrInterpreterChecker {
override fun visitSetField(expression: IrSetField, data: IrInterpreterCheckerData): Boolean { override fun visitSetField(expression: IrSetField, data: IrInterpreterCheckerData): Boolean {
if (expression.accessesTopLevelOrObjectField()) return false if (expression.accessesTopLevelOrObjectField()) return false
//todo check receiver? //todo check receiver?
val property = expression.symbol.owner.correspondingPropertySymbol?.owner val property = expression.symbol.owner.property
val declarations = expression.symbol.owner.parent.getInnerDeclarations() val declarations = expression.symbol.owner.parent.getInnerDeclarations()
val setter = declarations.filterIsInstance<IrProperty>().single { it == property }.setter ?: return false val setter = declarations.filterIsInstance<IrProperty>().single { it == property }.setter ?: return false
return visitedStack.contains(setter) && expression.value.accept(this, data) return visitedStack.contains(setter) && expression.value.accept(this, data)
@@ -14,6 +14,8 @@ import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.expressions.* 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.property
import org.jetbrains.kotlin.ir.types.classOrFail import org.jetbrains.kotlin.ir.types.classOrFail
class IrInterpreterConstGetterPreprocessor : IrInterpreterPreprocessor { class IrInterpreterConstGetterPreprocessor : IrInterpreterPreprocessor {
@@ -24,7 +26,7 @@ class IrInterpreterConstGetterPreprocessor : IrInterpreterPreprocessor {
} }
override fun visitCall(expression: IrCall, data: IrInterpreterPreprocessorData): IrElement { override fun visitCall(expression: IrCall, data: IrInterpreterPreprocessorData): IrElement {
val field = expression.symbol.owner.correspondingPropertySymbol?.owner?.backingField ?: return super.visitCall(expression, data) val field = expression.correspondingProperty?.backingField ?: return super.visitCall(expression, data)
return expression.lowerConstRead(field, data) ?: super.visitCall(expression, data) return expression.lowerConstRead(field, data) ?: super.visitCall(expression, data)
} }
@@ -62,6 +64,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 || correspondingPropertySymbol?.owner?.isConst == true return implicitConst || property?.isConst == true
} }
} }
@@ -139,7 +139,7 @@ internal class Wrapper(val value: Any, override val irClass: IrClass, environmen
val methodType = irFunction.getMethodType() val methodType = irFunction.getMethodType()
val methodName = when (irFunction) { val methodName = when (irFunction) {
is IrSimpleFunction -> { is IrSimpleFunction -> {
val property = irFunction.correspondingPropertySymbol?.owner val property = irFunction.property
when { when {
property?.getter == irFunction -> "get${property.name.asString().capitalizeAsciiOnly()}" property?.getter == irFunction -> "get${property.name.asString().capitalizeAsciiOnly()}"
property?.setter == irFunction -> "set${property.name.asString().capitalizeAsciiOnly()}" property?.setter == irFunction -> "set${property.name.asString().capitalizeAsciiOnly()}"
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.ir.interpreter.state.reflection
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.interpreter.CallInterceptor import org.jetbrains.kotlin.ir.interpreter.CallInterceptor
import org.jetbrains.kotlin.ir.interpreter.property
import org.jetbrains.kotlin.ir.interpreter.proxy.reflection.KTypeProxy import org.jetbrains.kotlin.ir.interpreter.proxy.reflection.KTypeProxy
import kotlin.reflect.KParameter import kotlin.reflect.KParameter
import kotlin.reflect.KType import kotlin.reflect.KType
@@ -48,7 +49,7 @@ internal class KParameterState(
append(" of ") append(" of ")
when (val parent = irParameter.parent) { when (val parent = irParameter.parent) {
is IrSimpleFunction -> parent.correspondingPropertySymbol?.owner?.let { append(renderProperty(it)) } is IrSimpleFunction -> parent.property?.let { append(renderProperty(it)) }
?: append(renderFunction(parent)) ?: append(renderFunction(parent))
is IrFunction -> append(renderFunction(parent)) is IrFunction -> append(renderFunction(parent))
is IrProperty -> append(renderProperty(parent)) is IrProperty -> append(renderProperty(parent))
@@ -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.property
/** /**
* This transformer will visit all expressions and will evaluate only those that are necessary. By "necessary" we mean expressions * This transformer will visit all expressions and will evaluate only those that are necessary. By "necessary" we mean expressions
@@ -34,7 +35,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.correspondingPropertySymbol?.owner?.isConst == true val isConstGetter = expression.symbol.owner.property?.isConst == true
if (!data.inAnnotation && !isConstGetter) { if (!data.inAnnotation && !isConstGetter) {
expression.transformChildren(this, data) expression.transformChildren(this, data)
return expression return expression
@@ -43,7 +44,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.correspondingPropertySymbol?.owner?.isConst == true val isConst = expression.symbol.owner.property?.isConst == true
if (!data.inAnnotation && !isConst) return expression if (!data.inAnnotation && !isConst) return expression
return super.visitGetField(expression, data) return super.visitGetField(expression, data)
} }
@@ -57,7 +58,7 @@ internal class IrConstOnlyNecessaryTransformer(
} }
override fun visitField(declaration: IrField, data: Data): IrStatement { override fun visitField(declaration: IrField, data: Data): IrStatement {
val isConst = declaration.correspondingPropertySymbol?.owner?.isConst == true val isConst = declaration.property?.isConst == true
if (!isConst) { if (!isConst) {
declaration.transformChildren(this, data) declaration.transformChildren(this, data)
return declaration return declaration