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
|
||||
if (property.backingField?.initializer != null) {
|
||||
val receiverState = stack.getVariable(receiver).state
|
||||
val propertyVar = Variable(property.backingField!!.symbol, stack.popReturnValue())
|
||||
val propertyVar = Variable(property.symbol, stack.popReturnValue())
|
||||
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
|
||||
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
|
||||
}
|
||||
|
||||
@@ -521,7 +522,7 @@ class IrInterpreter(irModule: IrModuleFragment, private val bodyMap: Map<IdSigna
|
||||
return Next
|
||||
}
|
||||
// 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)
|
||||
stack.pushReturnValue(result)
|
||||
return Next
|
||||
@@ -672,12 +673,11 @@ class IrInterpreter(irModule: IrModuleFragment, private val bodyMap: Map<IdSigna
|
||||
"UByteArray", "UShortArray", "UIntArray", "ULongArray" -> {
|
||||
val owner = expression.type.classOrNull!!.owner
|
||||
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 unsignedArray = primitiveArray.toPrimitiveStateArray(storageField.type)
|
||||
val unsignedArray = primitiveArray.toPrimitiveStateArray(storageProperty.backingField!!.type)
|
||||
Common(owner).apply {
|
||||
setSuperClassRecursive()
|
||||
fields.add(Variable(storageField.symbol, unsignedArray))
|
||||
fields.add(Variable(storageProperty.symbol, unsignedArray))
|
||||
}
|
||||
}
|
||||
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.toState
|
||||
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.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.ir.util.isSubclassOf
|
||||
@@ -22,15 +21,15 @@ class ExceptionState private constructor(
|
||||
|
||||
private lateinit var exceptionFqName: String
|
||||
private val exceptionHierarchy = mutableListOf<String>()
|
||||
private val messageField = irClass.getFieldByName("message")
|
||||
private val causeField = irClass.getFieldByName("cause")
|
||||
private val messageProperty = irClass.getPropertyByName("message")
|
||||
private val causeProperty = irClass.getPropertyByName("cause")
|
||||
|
||||
private val stackTrace: List<String> = stackTrace.reversed()
|
||||
|
||||
init {
|
||||
if (!this::exceptionFqName.isInitialized) this.exceptionFqName = irClassFqName()
|
||||
|
||||
if (fields.none { it.symbol == messageField.symbol }) {
|
||||
if (fields.none { it.symbol == messageProperty.symbol }) {
|
||||
setMessage()
|
||||
}
|
||||
}
|
||||
@@ -81,17 +80,17 @@ class ExceptionState private constructor(
|
||||
}
|
||||
|
||||
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?) {
|
||||
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
|
||||
|
||||
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 {
|
||||
// TODO remainder of the stack trace with "..."
|
||||
@@ -107,18 +106,18 @@ class ExceptionState private constructor(
|
||||
fun getThisAsCauseForException() = ExceptionData(this)
|
||||
|
||||
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
|
||||
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> {
|
||||
val messageField = irClass.getFieldByName("message")
|
||||
val causeField = irClass.getFieldByName("cause")
|
||||
val messageProperty = irClass.getPropertyByName("message")
|
||||
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 {
|
||||
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()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user