Support interpretation for inner class
This commit is contained in:
+15
-7
@@ -281,6 +281,10 @@ class IrInterpreter(irModule: IrModuleFragment) {
|
||||
val isLocal = (dispatchReceiver as? Complex)?.getOriginal()?.irClass?.isLocal ?: irFunction.isLocal
|
||||
if (isLocal) valueArguments.addAll(dispatchReceiver.extractNonLocalDeclarations())
|
||||
|
||||
if (functionReceiver is Complex && irFunction.parentClassOrNull?.isInner == true) {
|
||||
generateSequence(functionReceiver.outerClass) { (it.state as? Complex)?.outerClass }.forEach { valueArguments.add(it) }
|
||||
}
|
||||
|
||||
return stack.newFrame(asSubFrame = irFunction.isInline || irFunction.isLocal, initPool = valueArguments) {
|
||||
// inline only methods are not presented in lookup table, so must be interpreted instead of execution
|
||||
val isInlineOnly = irFunction.hasAnnotation(FqName("kotlin.internal.InlineOnly"))
|
||||
@@ -321,20 +325,24 @@ class IrInterpreter(irModule: IrModuleFragment) {
|
||||
|
||||
interpretValueParameters(constructorCall, owner, valueArguments).check { return it }
|
||||
|
||||
val parent = owner.parent as IrClass
|
||||
val typeArguments = getTypeArguments(parent, constructorCall) { stack.getVariableState(it) } + stack.getAllTypeArguments()
|
||||
if (parent.hasAnnotation(evaluateIntrinsicAnnotation)) {
|
||||
val irClass = owner.parent as IrClass
|
||||
val typeArguments = getTypeArguments(irClass, constructorCall) { stack.getVariableState(it) } + stack.getAllTypeArguments()
|
||||
if (irClass.hasAnnotation(evaluateIntrinsicAnnotation)) {
|
||||
return stack.newFrame(initPool = valueArguments) { Wrapper.getConstructorMethod(owner).invokeMethod(owner) }
|
||||
.apply { (stack.peekReturnValue() as? Wrapper)?.typeArguments?.addAll(typeArguments) } // can be exception
|
||||
.apply { (stack.peekReturnValue() as? Wrapper)?.typeArguments?.addAll(typeArguments) } // 'as?' because can be exception
|
||||
}
|
||||
|
||||
if (parent.defaultType.isArray() || parent.defaultType.isPrimitiveArray()) {
|
||||
if (irClass.defaultType.isArray() || irClass.defaultType.isPrimitiveArray()) {
|
||||
// array constructor doesn't have body so must be treated separately
|
||||
return stack.newFrame(initPool = valueArguments) { handleIntrinsicMethods(owner) }
|
||||
}
|
||||
|
||||
val state = Common(parent).apply { this.typeArguments.addAll(typeArguments) }
|
||||
if (parent.isLocal) state.fields.addAll(stack.getAll()) // TODO save only necessary declarations
|
||||
val state = Common(irClass).apply { this.typeArguments.addAll(typeArguments) }
|
||||
if (irClass.isLocal) state.fields.addAll(stack.getAll()) // TODO save only necessary declarations
|
||||
if (irClass.isInner) {
|
||||
constructorCall.dispatchReceiver!!.interpret().check { return it }
|
||||
state.outerClass = Variable(constructorCall.symbol.owner.dispatchReceiverParameter!!.descriptor, stack.popReturnValue())
|
||||
}
|
||||
valueArguments.add(Variable(constructorCall.getThisAsReceiver(), state)) //used to set up fields in body
|
||||
return stack.newFrame(initPool = valueArguments + state.typeArguments) {
|
||||
val statements = constructorCall.getBody()!!.statements
|
||||
|
||||
+4
-9
@@ -5,22 +5,19 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.common.interpreter.state
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.interpreter.getLastOverridden
|
||||
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.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.ir.types.classOrNull
|
||||
import org.jetbrains.kotlin.ir.util.fqNameForIrSerialization
|
||||
import org.jetbrains.kotlin.ir.util.isFakeOverride
|
||||
import org.jetbrains.kotlin.ir.util.isInterface
|
||||
|
||||
class Common private constructor(
|
||||
override val irClass: IrClass, override val fields: MutableList<Variable>, override val typeArguments: MutableList<Variable>,
|
||||
superClass: Complex?, subClass: Complex?
|
||||
) : Complex(irClass, fields, superClass, subClass) {
|
||||
override val irClass: IrClass, override val fields: MutableList<Variable>
|
||||
) : Complex(irClass, fields) {
|
||||
|
||||
constructor(irClass: IrClass) : this(irClass, mutableListOf(), mutableListOf(), null, null)
|
||||
constructor(irClass: IrClass) : this(irClass, mutableListOf())
|
||||
|
||||
fun setSuperClassRecursive() {
|
||||
var thisClass: Common? = this
|
||||
@@ -51,9 +48,7 @@ class Common private constructor(
|
||||
.let { getOverridden(it as IrSimpleFunction, this) }
|
||||
}
|
||||
|
||||
override fun copy(): State {
|
||||
return Common(irClass, fields, typeArguments, superClass, subClass ?: this)
|
||||
}
|
||||
override fun copy() = Common(irClass, fields).copyFrom(this)
|
||||
|
||||
override fun toString(): String {
|
||||
return "Common(obj='${irClass.fqNameForIrSerialization}', super=$superClass, values=$fields)"
|
||||
|
||||
+13
-4
@@ -18,10 +18,11 @@ import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.util.fqNameForIrSerialization
|
||||
import org.jetbrains.kotlin.ir.util.isInterface
|
||||
|
||||
abstract class Complex(
|
||||
override val irClass: IrClass, override val fields: MutableList<Variable>, var superClass: Complex?, var subClass: Complex?
|
||||
) : State {
|
||||
abstract val typeArguments: MutableList<Variable>
|
||||
abstract class Complex(override val irClass: IrClass, override val fields: MutableList<Variable>) : State {
|
||||
var superClass: Complex? = null
|
||||
var subClass: Complex? = null
|
||||
val typeArguments: MutableList<Variable> = mutableListOf()
|
||||
var outerClass: Variable? = null
|
||||
|
||||
fun setSuperClassInstance(superClass: Complex) {
|
||||
if (this.irClass == superClass.irClass) {
|
||||
@@ -52,6 +53,14 @@ abstract class Complex(
|
||||
}
|
||||
}
|
||||
|
||||
protected fun copyFrom(other: Complex): State {
|
||||
this.superClass = other.superClass
|
||||
this.subClass = other.subClass ?: other
|
||||
this.typeArguments.addAll(other.typeArguments)
|
||||
this.outerClass = other.outerClass
|
||||
return this
|
||||
}
|
||||
|
||||
private fun getIrFunction(descriptor: FunctionDescriptor): IrFunction? {
|
||||
val propertyGetters = irClass.declarations.filterIsInstance<IrProperty>().mapNotNull { it.getter }
|
||||
val functions = irClass.declarations.filterIsInstance<IrFunction>()
|
||||
|
||||
+3
-6
@@ -16,9 +16,8 @@ import org.jetbrains.kotlin.ir.util.nameForIrSerialization
|
||||
import kotlin.math.min
|
||||
|
||||
class ExceptionState private constructor(
|
||||
override val irClass: IrClass, override val fields: MutableList<Variable>, stackTrace: List<String>, subClass: Complex? = null
|
||||
) : Complex(irClass, fields, null, subClass) {
|
||||
override val typeArguments: MutableList<Variable> = mutableListOf()
|
||||
override val irClass: IrClass, override val fields: MutableList<Variable>, stackTrace: List<String>
|
||||
) : Complex(irClass, fields) {
|
||||
|
||||
private lateinit var exceptionFqName: String
|
||||
private val exceptionHierarchy = mutableListOf<String>()
|
||||
@@ -106,9 +105,7 @@ class ExceptionState private constructor(
|
||||
|
||||
fun getThisAsCauseForException() = ExceptionData(this)
|
||||
|
||||
override fun copy(): State {
|
||||
return ExceptionState(irClass, fields, stackTrace, subClass ?: this)
|
||||
}
|
||||
override fun copy() = ExceptionState(irClass, fields, stackTrace).copyFrom(this)
|
||||
|
||||
companion object {
|
||||
private fun IrClass.getPropertyByName(name: String): IrProperty {
|
||||
|
||||
+2
-8
@@ -34,15 +34,11 @@ import java.lang.invoke.MethodHandle
|
||||
import java.lang.invoke.MethodHandles
|
||||
import java.lang.invoke.MethodType
|
||||
|
||||
class Wrapper private constructor(
|
||||
val value: Any, override val irClass: IrClass, subClass: Complex?, override val typeArguments: MutableList<Variable>
|
||||
) : Complex(irClass, mutableListOf(), null, subClass) {
|
||||
class Wrapper(val value: Any, override val irClass: IrClass) : Complex(irClass, mutableListOf()) {
|
||||
|
||||
private val typeFqName = irClass.fqNameForIrSerialization.toUnsafe()
|
||||
private val receiverClass = irClass.defaultType.getClass(true)
|
||||
|
||||
constructor(value: Any, irClass: IrClass) : this(value, irClass, null, mutableListOf())
|
||||
|
||||
fun getMethod(irFunction: IrFunction): MethodHandle? {
|
||||
if (irFunction.getEvaluateIntrinsicValue()?.isEmpty() == true) return null // this method will handle IntrinsicEvaluator
|
||||
// if function is actually a getter, then use "get${property.name.capitalize()}" as method name
|
||||
@@ -198,9 +194,7 @@ class Wrapper private constructor(
|
||||
}
|
||||
}
|
||||
|
||||
override fun copy(): State {
|
||||
return Wrapper(value, irClass, subClass ?: this, typeArguments)
|
||||
}
|
||||
override fun copy() = Wrapper(value, irClass).copyFrom(this)
|
||||
|
||||
override fun toString(): String {
|
||||
return "Wrapper(obj='$typeFqName', value=$value)"
|
||||
|
||||
Reference in New Issue
Block a user