Add reference to sub class in Complex class
This is replacement for instance field
This commit is contained in:
+12
-17
@@ -268,7 +268,7 @@ class IrInterpreter(irModule: IrModuleFragment) {
|
|||||||
private suspend fun calculateAbstract(irFunction: IrFunction, data: Frame): Code {
|
private suspend fun calculateAbstract(irFunction: IrFunction, data: Frame): Code {
|
||||||
if (irFunction.body == null) {
|
if (irFunction.body == null) {
|
||||||
val receiver = data.getVariableState(irFunction.symbol.getReceiver()!!) as Complex
|
val receiver = data.getVariableState(irFunction.symbol.getReceiver()!!) as Complex
|
||||||
val instance = receiver.instance!!
|
val instance = receiver.getOriginal()
|
||||||
|
|
||||||
val functionImplementation = instance.getIrFunction(irFunction.descriptor)
|
val functionImplementation = instance.getIrFunction(irFunction.descriptor)
|
||||||
if (functionImplementation?.body == null) throw NoSuchMethodException("Method \"${irFunction.name}\" wasn't implemented")
|
if (functionImplementation?.body == null) throw NoSuchMethodException("Method \"${irFunction.name}\" wasn't implemented")
|
||||||
@@ -283,7 +283,7 @@ class IrInterpreter(irModule: IrModuleFragment) {
|
|||||||
|
|
||||||
private suspend fun calculateOverridden(owner: IrSimpleFunction, data: Frame): Code {
|
private suspend fun calculateOverridden(owner: IrSimpleFunction, data: Frame): Code {
|
||||||
val variableDescriptor = owner.symbol.getReceiver()!!
|
val variableDescriptor = owner.symbol.getReceiver()!!
|
||||||
val superQualifier = (data.getVariableState(variableDescriptor) as? Complex)?.superType
|
val superQualifier = (data.getVariableState(variableDescriptor) as? Complex)?.superClass
|
||||||
if (superQualifier == null) {
|
if (superQualifier == null) {
|
||||||
// superQualifier is null for exception state => find method in builtins
|
// superQualifier is null for exception state => find method in builtins
|
||||||
return calculateBuiltIns(owner.getLastOverridden() as IrSimpleFunction, data)
|
return calculateBuiltIns(owner.getLastOverridden() as IrSimpleFunction, data)
|
||||||
@@ -298,7 +298,7 @@ class IrInterpreter(irModule: IrModuleFragment) {
|
|||||||
val overriddenOwner = overridden.owner
|
val overriddenOwner = overridden.owner
|
||||||
return when {
|
return when {
|
||||||
overriddenOwner.body != null -> overriddenOwner.interpret(newStates)
|
overriddenOwner.body != null -> overriddenOwner.interpret(newStates)
|
||||||
superQualifier.superType == null -> calculateBuiltIns(overriddenOwner, newStates)
|
superQualifier.superClass == null -> calculateBuiltIns(overriddenOwner, newStates)
|
||||||
else -> calculateOverridden(overriddenOwner, newStates)
|
else -> calculateOverridden(overriddenOwner, newStates)
|
||||||
}.apply { data.pushReturnValue(newStates) }
|
}.apply { data.pushReturnValue(newStates) }
|
||||||
}
|
}
|
||||||
@@ -313,7 +313,7 @@ class IrInterpreter(irModule: IrModuleFragment) {
|
|||||||
|
|
||||||
val receiverType = descriptor.dispatchReceiverParameter?.type ?: descriptor.extensionReceiverParameter?.type
|
val receiverType = descriptor.dispatchReceiverParameter?.type ?: descriptor.extensionReceiverParameter?.type
|
||||||
val argsType = listOfNotNull(receiverType) + descriptor.valueParameters.map { it.original.type }
|
val argsType = listOfNotNull(receiverType) + descriptor.valueParameters.map { it.original.type }
|
||||||
val argsValues = args.map { (it as? Complex)?.instance ?: (it as Primitive<*>).value }
|
val argsValues = args.map { (it as? Complex)?.getOriginal() ?: (it as Primitive<*>).value }
|
||||||
val signature = CompileTimeFunction(methodName, argsType.map { it.toString() })
|
val signature = CompileTimeFunction(methodName, argsType.map { it.toString() })
|
||||||
|
|
||||||
val result = when (argsType.size) {
|
val result = when (argsType.size) {
|
||||||
@@ -376,7 +376,7 @@ class IrInterpreter(irModule: IrModuleFragment) {
|
|||||||
val dispatchReceiver = rawDispatchReceiver?.let { data.popReturnValue() }
|
val dispatchReceiver = rawDispatchReceiver?.let { data.popReturnValue() }
|
||||||
val irFunctionReceiver = when (expression.superQualifierSymbol) {
|
val irFunctionReceiver = when (expression.superQualifierSymbol) {
|
||||||
null -> dispatchReceiver
|
null -> dispatchReceiver
|
||||||
else -> (dispatchReceiver as Complex).superType?.takeIf { it.irClass.isSubclassOf(expression.superQualifierSymbol!!.owner) }
|
else -> (dispatchReceiver as Complex).superClass?.takeIf { it.irClass.isSubclassOf(expression.superQualifierSymbol!!.owner) }
|
||||||
}
|
}
|
||||||
// it is important firstly to add receiver, then arguments; this order is used in builtin method call
|
// it is important firstly to add receiver, then arguments; this order is used in builtin method call
|
||||||
val irFunction = irFunctionReceiver?.getIrFunction(expression.symbol.descriptor) ?: expression.symbol.owner
|
val irFunction = irFunctionReceiver?.getIrFunction(expression.symbol.descriptor) ?: expression.symbol.owner
|
||||||
@@ -400,7 +400,7 @@ class IrInterpreter(irModule: IrModuleFragment) {
|
|||||||
|
|
||||||
irFunction.takeIf { it.isInline }?.typeParameters?.forEachIndexed { index, typeParameter ->
|
irFunction.takeIf { it.isInline }?.typeParameters?.forEachIndexed { index, typeParameter ->
|
||||||
if (typeParameter.isReified) {
|
if (typeParameter.isReified) {
|
||||||
val typeArgumentState = Common(expression.getTypeArgument(index)?.classOrNull!!.owner, mutableListOf())
|
val typeArgumentState = Common(expression.getTypeArgument(index)?.classOrNull!!.owner)
|
||||||
newFrame.addVar(Variable(typeParameter.descriptor, typeArgumentState))
|
newFrame.addVar(Variable(typeParameter.descriptor, typeArgumentState))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -497,30 +497,25 @@ class IrInterpreter(irModule: IrModuleFragment) {
|
|||||||
return Code.NEXT
|
return Code.NEXT
|
||||||
}
|
}
|
||||||
|
|
||||||
val state = Common(parent, mutableListOf())
|
val state = Common(parent)
|
||||||
newFrame.addVar(Variable(constructorCall.getThisAsReceiver(), state)) //used to set up fields in body
|
newFrame.addVar(Variable(constructorCall.getThisAsReceiver(), state)) //used to set up fields in body
|
||||||
constructorCall.getBody()?.interpret(newFrame)?.checkForReturn(newFrame, data) { return it }
|
constructorCall.getBody()?.interpret(newFrame)?.checkForReturn(newFrame, data) { return it }
|
||||||
val returnedState = newFrame.popReturnValue() as Complex
|
val returnedState = newFrame.popReturnValue() as Complex
|
||||||
data.pushReturnValue(if (isPrimary) state.apply { superType = returnedState } else returnedState.apply { setStatesFrom(state) })
|
data.pushReturnValue(if (isPrimary) state.apply { this.setSuperClassInstance(returnedState) } else returnedState.apply { setStatesFrom(state) })
|
||||||
return Code.NEXT
|
return Code.NEXT
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun interpretConstructorCall(constructorCall: IrConstructorCall, data: Frame): Code {
|
private suspend fun interpretConstructorCall(constructorCall: IrConstructorCall, data: Frame): Code {
|
||||||
return interpretConstructor(constructorCall, data).apply {
|
return interpretConstructor(constructorCall, data)
|
||||||
// constructor can return primitive object; fot example, when create array by constructor
|
|
||||||
(data.peekReturnValue() as? Complex)?.let { it.setInstanceRecursive(it) }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun interpretEnumConstructorCall(enumConstructorCall: IrEnumConstructorCall, data: Frame): Code {
|
private suspend fun interpretEnumConstructorCall(enumConstructorCall: IrEnumConstructorCall, data: Frame): Code {
|
||||||
return interpretConstructor(enumConstructorCall, data).apply {
|
return interpretConstructor(enumConstructorCall, data)
|
||||||
(data.peekReturnValue() as Complex).let { it.setInstanceRecursive(it) }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun interpretDelegatedConstructorCall(delegatingConstructorCall: IrDelegatingConstructorCall, data: Frame): Code {
|
private suspend fun interpretDelegatedConstructorCall(delegatingConstructorCall: IrDelegatingConstructorCall, data: Frame): Code {
|
||||||
if (delegatingConstructorCall.symbol.descriptor.containingDeclaration.defaultType == DefaultBuiltIns.Instance.anyType) {
|
if (delegatingConstructorCall.symbol.descriptor.containingDeclaration.defaultType == DefaultBuiltIns.Instance.anyType) {
|
||||||
val anyAsStateObject = Common(irBuiltIns.anyClass.owner, mutableListOf())
|
val anyAsStateObject = Common(irBuiltIns.anyClass.owner)
|
||||||
data.pushReturnValue(anyAsStateObject)
|
data.pushReturnValue(anyAsStateObject)
|
||||||
return Code.NEXT
|
return Code.NEXT
|
||||||
}
|
}
|
||||||
@@ -665,7 +660,7 @@ class IrInterpreter(irModule: IrModuleFragment) {
|
|||||||
data.pushReturnValue(Wrapper.getCompanionObject(owner))
|
data.pushReturnValue(Wrapper.getCompanionObject(owner))
|
||||||
return Code.NEXT
|
return Code.NEXT
|
||||||
}
|
}
|
||||||
val objectState = Common(owner, mutableListOf()).apply { this.instance = this }
|
val objectState = Common(owner)
|
||||||
data.pushReturnValue(objectState)
|
data.pushReturnValue(objectState)
|
||||||
return Code.NEXT
|
return Code.NEXT
|
||||||
}
|
}
|
||||||
|
|||||||
+40
-39
@@ -96,17 +96,16 @@ class Primitive<T>(var value: T, val type: IrType) : State {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class Complex(override val irClass: IrClass, override val fields: MutableList<Variable>) : State {
|
abstract class Complex(
|
||||||
var superType: Complex? = null
|
override val irClass: IrClass, override val fields: MutableList<Variable>, var superClass: Complex?, var subClass: Complex?
|
||||||
var instance: Complex? = null
|
) : State {
|
||||||
|
fun setSuperClassInstance(superClass: Complex) {
|
||||||
fun setInstanceRecursive(instance: Complex) {
|
this.superClass = superClass
|
||||||
this.instance = instance
|
superClass.subClass = this
|
||||||
superType?.setInstanceRecursive(instance)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getReceiver(): DeclarationDescriptor {
|
fun getOriginal(): Complex {
|
||||||
return irClass.thisReceiver!!.descriptor
|
return subClass?.getOriginal() ?: this
|
||||||
}
|
}
|
||||||
|
|
||||||
fun irClassFqName(): String {
|
fun irClassFqName(): String {
|
||||||
@@ -130,7 +129,12 @@ abstract class Complex(override val irClass: IrClass, override val fields: Mutab
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Common(override val irClass: IrClass, override val fields: MutableList<Variable>) : Complex(irClass, fields) {
|
class Common private constructor(
|
||||||
|
override val irClass: IrClass, override val fields: MutableList<Variable>, superClass: Complex?, subClass: Complex?
|
||||||
|
) : Complex(irClass, fields, superClass, subClass) {
|
||||||
|
|
||||||
|
constructor(irClass: IrClass) : this(irClass, mutableListOf(), null, null)
|
||||||
|
|
||||||
fun getToStringFunction(): IrFunctionImpl {
|
fun getToStringFunction(): IrFunctionImpl {
|
||||||
return irClass.declarations.filterIsInstance<IrFunction>()
|
return irClass.declarations.filterIsInstance<IrFunction>()
|
||||||
.filter { it.descriptor.name.asString() == "toString" }
|
.filter { it.descriptor.name.asString() == "toString" }
|
||||||
@@ -138,24 +142,22 @@ class Common(override val irClass: IrClass, override val fields: MutableList<Var
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun copy(): State {
|
override fun copy(): State {
|
||||||
return Common(irClass, fields).apply {
|
return Common(irClass, fields, superClass, subClass ?: this)
|
||||||
this@apply.superType = this@Common.superType
|
|
||||||
this@apply.instance = this@Common.instance
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
return "Common(obj='${irClass.fqNameForIrSerialization}', super=$superType, values=$fields)"
|
return "Common(obj='${irClass.fqNameForIrSerialization}', super=$superClass, values=$fields)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Wrapper(val value: Any, override val irClass: IrClass) : Complex(irClass, mutableListOf()) {
|
class Wrapper private constructor(
|
||||||
|
val value: Any, override val irClass: IrClass, subClass: Complex?
|
||||||
|
) : Complex(irClass, mutableListOf(), null, subClass) {
|
||||||
|
|
||||||
private val typeFqName = irClass.fqNameForIrSerialization.toUnsafe()
|
private val typeFqName = irClass.fqNameForIrSerialization.toUnsafe()
|
||||||
private val receiverClass = irClass.defaultType.getClass(true)
|
private val receiverClass = irClass.defaultType.getClass(true)
|
||||||
|
|
||||||
init {
|
constructor(value: Any, irClass: IrClass) : this(value, irClass, null)
|
||||||
instance = this
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getMethod(irFunction: IrFunction): MethodHandle? {
|
fun getMethod(irFunction: IrFunction): MethodHandle? {
|
||||||
// if function is actually a getter, then use "get${property.name.capitalize()}" as method name
|
// if function is actually a getter, then use "get${property.name.capitalize()}" as method name
|
||||||
@@ -280,7 +282,7 @@ class Wrapper(val value: Any, override val irClass: IrClass) : Complex(irClass,
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun copy(): State {
|
override fun copy(): State {
|
||||||
return Wrapper(value, irClass).apply { this@apply.instance = this@Wrapper.instance }
|
return Wrapper(value, irClass, subClass ?: this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
@@ -288,7 +290,9 @@ class Wrapper(val value: Any, override val irClass: IrClass) : Complex(irClass,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Lambda(val irFunction: IrFunction, override val irClass: IrClass) : Complex(irClass, mutableListOf()) {
|
class Lambda(val irFunction: IrFunction, override val irClass: IrClass) : State {
|
||||||
|
override val fields: MutableList<Variable> = mutableListOf()
|
||||||
|
|
||||||
// irFunction is anonymous declaration, but irCall will contain descriptor of invoke method from Function interface
|
// irFunction is anonymous declaration, but irCall will contain descriptor of invoke method from Function interface
|
||||||
private val invokeDescriptor = irClass.declarations.single { it.nameForIrSerialization.asString() == "invoke" }.descriptor
|
private val invokeDescriptor = irClass.declarations.single { it.nameForIrSerialization.asString() == "invoke" }.descriptor
|
||||||
|
|
||||||
@@ -301,7 +305,7 @@ class Lambda(val irFunction: IrFunction, override val irClass: IrClass) : Comple
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun copy(): State {
|
override fun copy(): State {
|
||||||
return Lambda(irFunction, irClass).apply { this@apply.instance = this@Lambda.instance }
|
return Lambda(irFunction, irClass)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
@@ -310,18 +314,17 @@ class Lambda(val irFunction: IrFunction, override val irClass: IrClass) : Comple
|
|||||||
}
|
}
|
||||||
|
|
||||||
class ExceptionState private constructor(
|
class ExceptionState private constructor(
|
||||||
override val irClass: IrClass, override val fields: MutableList<Variable>, stackTrace: List<String>
|
override val irClass: IrClass, override val fields: MutableList<Variable>, stackTrace: List<String>, subClass: Complex? = null
|
||||||
) : Complex(irClass, fields) {
|
) : Complex(irClass, fields, null, subClass) {
|
||||||
|
|
||||||
private lateinit var exceptionFqName: String
|
private lateinit var exceptionFqName: String
|
||||||
private val exceptionHierarchy = mutableListOf<String>()
|
private val exceptionHierarchy = mutableListOf<String>()
|
||||||
private val messageProperty = irClass.getPropertyByName("message")
|
private val messageProperty = irClass.getPropertyByName("message")
|
||||||
private val causeProperty = irClass.getPropertyByName("cause")
|
private val causeProperty = irClass.getPropertyByName("cause")
|
||||||
|
|
||||||
private val stackTrace: List<String>
|
private val stackTrace: List<String> = stackTrace.reversed()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
instance = this
|
|
||||||
this.stackTrace = stackTrace.reversed()
|
|
||||||
if (!this::exceptionFqName.isInitialized) this.exceptionFqName = irClassFqName()
|
if (!this::exceptionFqName.isInitialized) this.exceptionFqName = irClassFqName()
|
||||||
|
|
||||||
if (fields.none { it.descriptor.equalTo(messageProperty.descriptor) }) {
|
if (fields.none { it.descriptor.equalTo(messageProperty.descriptor) }) {
|
||||||
@@ -331,7 +334,7 @@ class ExceptionState private constructor(
|
|||||||
|
|
||||||
constructor(common: Common, stackTrace: List<String>) : this(common.irClass, common.fields, stackTrace) {
|
constructor(common: Common, stackTrace: List<String>) : this(common.irClass, common.fields, stackTrace) {
|
||||||
var wrapperSuperType: Complex? = common
|
var wrapperSuperType: Complex? = common
|
||||||
while (wrapperSuperType != null && wrapperSuperType !is Wrapper) wrapperSuperType = (wrapperSuperType as Common).superType
|
while (wrapperSuperType != null && wrapperSuperType !is Wrapper) wrapperSuperType = (wrapperSuperType as Common).superClass
|
||||||
setUpCauseIfNeeded(wrapperSuperType as? Wrapper)
|
setUpCauseIfNeeded(wrapperSuperType as? Wrapper)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -351,6 +354,13 @@ class ExceptionState private constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data class ExceptionData(val state: ExceptionState) : Throwable() {
|
||||||
|
override val message: String? = state.getMessage().value
|
||||||
|
override fun fillInStackTrace() = this
|
||||||
|
|
||||||
|
override fun toString(): String = state.getMessageWithName()
|
||||||
|
}
|
||||||
|
|
||||||
private fun setUpCauseIfNeeded(wrapper: Wrapper?) {
|
private fun setUpCauseIfNeeded(wrapper: Wrapper?) {
|
||||||
val cause = (wrapper?.value as? Throwable)?.cause as? ExceptionData
|
val cause = (wrapper?.value as? Throwable)?.cause as? ExceptionData
|
||||||
setCause(cause?.state)
|
setCause(cause?.state)
|
||||||
@@ -376,7 +386,7 @@ class ExceptionState private constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun getMessage(): Primitive<String?> = getState(messageProperty.descriptor) as Primitive<String?>
|
fun getMessage(): Primitive<String?> = getState(messageProperty.descriptor) as Primitive<String?>
|
||||||
fun getMessageWithName(): String = getMessage().value?.let { "$exceptionFqName: $it" } ?: exceptionFqName
|
private fun getMessageWithName(): String = getMessage().value?.let { "$exceptionFqName: $it" } ?: exceptionFqName
|
||||||
|
|
||||||
fun getCause(): ExceptionState? = getState(causeProperty.descriptor)?.let { if (it is ExceptionState) it else null }
|
fun getCause(): ExceptionState? = getState(causeProperty.descriptor)?.let { if (it is ExceptionState) it else null }
|
||||||
|
|
||||||
@@ -394,7 +404,7 @@ class ExceptionState private constructor(
|
|||||||
fun getThisAsCauseForException() = ExceptionData(this)
|
fun getThisAsCauseForException() = ExceptionData(this)
|
||||||
|
|
||||||
override fun copy(): State {
|
override fun copy(): State {
|
||||||
return ExceptionState(irClass, fields, stackTrace).apply { this@apply.instance = this@ExceptionState.instance }
|
return ExceptionState(irClass, fields, stackTrace, subClass ?: this)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@@ -443,12 +453,3 @@ class ExceptionState private constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO remove this data class and make ExceptionState a child of Throwable
|
|
||||||
// this is possible by converting Complex to an interface
|
|
||||||
data class ExceptionData(val state: ExceptionState) : Throwable() {
|
|
||||||
override val message: String? = state.getMessage().value
|
|
||||||
override fun fillInStackTrace() = this
|
|
||||||
|
|
||||||
override fun toString(): String = state.getMessageWithName()
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user