Change the way of receiving fields
Before that, interpreted values for fields were taken by backing field's symbol. For now, they will be taken by property's symbol. It was done because not all properties contain backing field. For example, Throwable class in FIR2IR.
This commit is contained in:
+6
-6
@@ -337,7 +337,7 @@ class IrInterpreter(irModule: IrModuleFragment, private val bodyMap: Map<IdSigna
|
|||||||
val receiver = irClass.thisReceiver!!.symbol
|
val receiver = irClass.thisReceiver!!.symbol
|
||||||
if (property.backingField?.initializer != null) {
|
if (property.backingField?.initializer != null) {
|
||||||
val receiverState = stack.getVariable(receiver).state
|
val receiverState = stack.getVariable(receiver).state
|
||||||
val propertyVar = Variable(property.backingField!!.symbol, stack.popReturnValue())
|
val propertyVar = Variable(property.symbol, stack.popReturnValue())
|
||||||
receiverState.setField(propertyVar)
|
receiverState.setField(propertyVar)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -508,7 +508,8 @@ class IrInterpreter(irModule: IrModuleFragment, private val bodyMap: Map<IdSigna
|
|||||||
|
|
||||||
// receiver is null only for top level var, but it cannot be used in constexpr; corresponding check is on frontend
|
// receiver is null only for top level var, but it cannot be used in constexpr; corresponding check is on frontend
|
||||||
val receiver = (expression.receiver as IrDeclarationReference).symbol
|
val receiver = (expression.receiver as IrDeclarationReference).symbol
|
||||||
stack.getVariable(receiver).apply { this.state.setField(Variable(expression.symbol, stack.popReturnValue())) }
|
val propertySymbol = expression.symbol.owner.correspondingPropertySymbol!!
|
||||||
|
stack.getVariable(receiver).apply { this.state.setField(Variable(propertySymbol, stack.popReturnValue())) }
|
||||||
return Next
|
return Next
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -521,7 +522,7 @@ class IrInterpreter(irModule: IrModuleFragment, private val bodyMap: Map<IdSigna
|
|||||||
return Next
|
return Next
|
||||||
}
|
}
|
||||||
// receiver is null, for example, for top level fields
|
// receiver is null, for example, for top level fields
|
||||||
val result = receiver?.let { stack.getVariable(receiver).state.getState(expression.symbol) }
|
val result = receiver?.let { stack.getVariable(receiver).state.getState(field.correspondingPropertySymbol!!) }
|
||||||
?: return (expression.symbol.owner.initializer?.expression?.interpret() ?: Next)
|
?: return (expression.symbol.owner.initializer?.expression?.interpret() ?: Next)
|
||||||
stack.pushReturnValue(result)
|
stack.pushReturnValue(result)
|
||||||
return Next
|
return Next
|
||||||
@@ -672,12 +673,11 @@ class IrInterpreter(irModule: IrModuleFragment, private val bodyMap: Map<IdSigna
|
|||||||
"UByteArray", "UShortArray", "UIntArray", "ULongArray" -> {
|
"UByteArray", "UShortArray", "UIntArray", "ULongArray" -> {
|
||||||
val owner = expression.type.classOrNull!!.owner
|
val owner = expression.type.classOrNull!!.owner
|
||||||
val storageProperty = owner.declarations.filterIsInstance<IrProperty>().first { it.name.asString() == "storage" }
|
val storageProperty = owner.declarations.filterIsInstance<IrProperty>().first { it.name.asString() == "storage" }
|
||||||
val storageField = storageProperty.backingField!!
|
|
||||||
val primitiveArray = args.map { ((it as Common).fields.single().state as Primitive<*>).value }
|
val primitiveArray = args.map { ((it as Common).fields.single().state as Primitive<*>).value }
|
||||||
val unsignedArray = primitiveArray.toPrimitiveStateArray(storageField.type)
|
val unsignedArray = primitiveArray.toPrimitiveStateArray(storageProperty.backingField!!.type)
|
||||||
Common(owner).apply {
|
Common(owner).apply {
|
||||||
setSuperClassRecursive()
|
setSuperClassRecursive()
|
||||||
fields.add(Variable(storageField.symbol, unsignedArray))
|
fields.add(Variable(storageProperty.symbol, unsignedArray))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> args.toPrimitiveStateArray(expression.type)
|
else -> args.toPrimitiveStateArray(expression.type)
|
||||||
|
|||||||
+13
-14
@@ -9,7 +9,6 @@ import org.jetbrains.kotlin.backend.common.interpreter.getLastOverridden
|
|||||||
import org.jetbrains.kotlin.backend.common.interpreter.stack.Variable
|
import org.jetbrains.kotlin.backend.common.interpreter.stack.Variable
|
||||||
import org.jetbrains.kotlin.backend.common.interpreter.toState
|
import org.jetbrains.kotlin.backend.common.interpreter.toState
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrField
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrProperty
|
import org.jetbrains.kotlin.ir.declarations.IrProperty
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||||
import org.jetbrains.kotlin.ir.util.isSubclassOf
|
import org.jetbrains.kotlin.ir.util.isSubclassOf
|
||||||
@@ -22,15 +21,15 @@ class ExceptionState private constructor(
|
|||||||
|
|
||||||
private lateinit var exceptionFqName: String
|
private lateinit var exceptionFqName: String
|
||||||
private val exceptionHierarchy = mutableListOf<String>()
|
private val exceptionHierarchy = mutableListOf<String>()
|
||||||
private val messageField = irClass.getFieldByName("message")
|
private val messageProperty = irClass.getPropertyByName("message")
|
||||||
private val causeField = irClass.getFieldByName("cause")
|
private val causeProperty = irClass.getPropertyByName("cause")
|
||||||
|
|
||||||
private val stackTrace: List<String> = stackTrace.reversed()
|
private val stackTrace: List<String> = stackTrace.reversed()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
if (!this::exceptionFqName.isInitialized) this.exceptionFqName = irClassFqName()
|
if (!this::exceptionFqName.isInitialized) this.exceptionFqName = irClassFqName()
|
||||||
|
|
||||||
if (fields.none { it.symbol == messageField.symbol }) {
|
if (fields.none { it.symbol == messageProperty.symbol }) {
|
||||||
setMessage()
|
setMessage()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -81,17 +80,17 @@ class ExceptionState private constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun setMessage(messageValue: String? = null) {
|
private fun setMessage(messageValue: String? = null) {
|
||||||
setField(Variable(messageField.symbol, Primitive(messageValue, messageField.type)))
|
setField(Variable(messageProperty.symbol, Primitive(messageValue, messageProperty.getter!!.returnType)))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setCause(causeValue: State?) {
|
private fun setCause(causeValue: State?) {
|
||||||
setField(Variable(causeField.symbol, causeValue ?: Primitive<Throwable?>(null, causeField.type)))
|
setField(Variable(causeProperty.symbol, causeValue ?: Primitive<Throwable?>(null, causeProperty.getter!!.returnType)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getMessage(): String? = (getState(messageField.symbol) as Primitive<*>).value as String?
|
fun getMessage(): String? = (getState(messageProperty.symbol) as Primitive<*>).value as String?
|
||||||
private fun getMessageWithName(): String = getMessage()?.let { "$exceptionFqName: $it" } ?: exceptionFqName
|
private fun getMessageWithName(): String = getMessage()?.let { "$exceptionFqName: $it" } ?: exceptionFqName
|
||||||
|
|
||||||
fun getCause(): ExceptionState? = getState(causeField.symbol)?.let { if (it is ExceptionState) it else null }
|
fun getCause(): ExceptionState? = getState(causeProperty.symbol)?.let { if (it is ExceptionState) it else null }
|
||||||
|
|
||||||
fun getFullDescription(): String {
|
fun getFullDescription(): String {
|
||||||
// TODO remainder of the stack trace with "..."
|
// TODO remainder of the stack trace with "..."
|
||||||
@@ -107,18 +106,18 @@ class ExceptionState private constructor(
|
|||||||
fun getThisAsCauseForException() = ExceptionData(this)
|
fun getThisAsCauseForException() = ExceptionData(this)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private fun IrClass.getFieldByName(name: String): IrField {
|
private fun IrClass.getPropertyByName(name: String): IrProperty {
|
||||||
val property = this.declarations.single { it.nameForIrSerialization.asString() == name } as IrProperty
|
val property = this.declarations.single { it.nameForIrSerialization.asString() == name } as IrProperty
|
||||||
return (property.getter!!.getLastOverridden() as IrSimpleFunction).correspondingPropertySymbol!!.owner.backingField!!
|
return (property.getter!!.getLastOverridden() as IrSimpleFunction).correspondingPropertySymbol!!.owner
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun evaluateFields(exception: Throwable, irClass: IrClass, stackTrace: List<String>): MutableList<Variable> {
|
private fun evaluateFields(exception: Throwable, irClass: IrClass, stackTrace: List<String>): MutableList<Variable> {
|
||||||
val messageField = irClass.getFieldByName("message")
|
val messageProperty = irClass.getPropertyByName("message")
|
||||||
val causeField = irClass.getFieldByName("cause")
|
val causeProperty = irClass.getPropertyByName("cause")
|
||||||
|
|
||||||
val messageVar = Variable(messageField.symbol, exception.message.toState(messageField.type))
|
val messageVar = Variable(messageProperty.symbol, exception.message.toState(messageProperty.getter!!.returnType))
|
||||||
val causeVar = exception.cause?.let {
|
val causeVar = exception.cause?.let {
|
||||||
Variable(causeField.symbol, ExceptionState(it, irClass, stackTrace + it.stackTrace.reversed().map { "at $it" }))
|
Variable(causeProperty.symbol, ExceptionState(it, irClass, stackTrace + it.stackTrace.reversed().map { "at $it" }))
|
||||||
}
|
}
|
||||||
return listOfNotNull(messageVar, causeVar).toMutableList()
|
return listOfNotNull(messageVar, causeVar).toMutableList()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user