Implement interpretation for object with overridden methods

This commit is contained in:
Ivan Kylchik
2020-06-10 22:37:35 +03:00
parent fe7abb7132
commit 06e6c7cdf5
2 changed files with 25 additions and 2 deletions
@@ -627,8 +627,7 @@ class IrInterpreter(irModule: IrModuleFragment) {
data.pushReturnValue(Wrapper.getCompanionObject(owner))
return Next
}
val objectState = Common(owner)
data.pushReturnValue(objectState)
data.pushReturnValue(Common(owner).apply { setSuperClassRecursive() })
return Next
}
@@ -9,7 +9,9 @@ import org.jetbrains.kotlin.backend.common.interpreter.stack.Variable
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
import org.jetbrains.kotlin.ir.types.classOrNull
import org.jetbrains.kotlin.ir.util.fqNameForIrSerialization
import org.jetbrains.kotlin.ir.util.isInterface
class Common private constructor(
override val irClass: IrClass, override val fields: MutableList<Variable>, superClass: Complex?, subClass: Complex?
@@ -17,6 +19,28 @@ class Common private constructor(
constructor(irClass: IrClass) : this(irClass, mutableListOf(), null, null)
fun setSuperClassRecursive() {
var thisClass: Common? = this
while (thisClass != null) {
val superClass = thisClass.irClass.superTypes.filterNot { it.isInterface() }.singleOrNull()
val superClassOwner = superClass?.classOrNull?.owner
val superClassState = superClassOwner?.let { Common(it) }
superClassState?.let { thisClass!!.setSuperClassInstance(it) }
if (superClass == null && thisClass.irClass.superTypes.isNotEmpty()) {
// cover the case when super type implement an interface and so doesn't have explicit any as super class
thisClass.setSuperClassInstance(Common(getAnyClassRecursive()))
}
thisClass = superClassState
}
}
private fun getAnyClassRecursive(): IrClass {
var owner = irClass.superTypes.first().classOrNull!!.owner
while (owner.superTypes.isNotEmpty()) owner = owner.superTypes.first().classOrNull!!.owner
return owner
}
fun getToStringFunction(): IrFunctionImpl {
return irClass.declarations.filterIsInstance<IrFunction>()
.filter { it.descriptor.name.asString() == "toString" }