Allow local declaration interpretation
By local declaration is meant local functions and local objects
This commit is contained in:
+15
-3
@@ -121,6 +121,7 @@ class IrInterpreter(irModule: IrModuleFragment) {
|
|||||||
is IrFunctionReference -> interpretFunctionReference(this)
|
is IrFunctionReference -> interpretFunctionReference(this)
|
||||||
is IrComposite -> interpretComposite(this)
|
is IrComposite -> interpretComposite(this)
|
||||||
|
|
||||||
|
is IrClass -> if (this.isLocal) Next else TODO("Only local classes are supported")
|
||||||
else -> TODO("${this.javaClass} not supported")
|
else -> TODO("${this.javaClass} not supported")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -274,9 +275,11 @@ class IrInterpreter(irModule: IrModuleFragment) {
|
|||||||
|
|
||||||
return stack.newFrame(asSubFrame = true, initPool = pool) {
|
return stack.newFrame(asSubFrame = true, initPool = pool) {
|
||||||
for (i in valueArguments.indices) {
|
for (i in valueArguments.indices) {
|
||||||
(valueArguments[i] ?: defaultValues[i])!!.interpret().check { return@newFrame it }
|
(valueArguments[i] ?: defaultValues[i])?.interpret()?.check { return@newFrame it }
|
||||||
|
?: stack.pushReturnValue(listOf<Any?>().toPrimitiveStateArray(expression.getVarargType(i)!!))
|
||||||
|
|
||||||
with(Variable(valueParametersDescriptors[i], stack.popReturnValue())) {
|
with(Variable(valueParametersDescriptors[i], stack.popReturnValue())) {
|
||||||
stack.addVar(this)
|
stack.addVar(this) //must add value argument in current stack because it can be used later as default argument
|
||||||
pool.add(this)
|
pool.add(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -314,6 +317,12 @@ class IrInterpreter(irModule: IrModuleFragment) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// load data from declaration if it is local
|
||||||
|
if (dispatchReceiver != null && (irFunction.isLocal || dispatchReceiver.irClass.isLocal)) {
|
||||||
|
with(dispatchReceiver) { this.fields.filterNot { it.descriptor.containingDeclaration == this.irClass.descriptor } }
|
||||||
|
.apply { valueArguments.addAll(this) }
|
||||||
|
}
|
||||||
|
|
||||||
return stack.newFrame(asSubFrame = irFunction.isInline || irFunction.isLocal, initPool = valueArguments) {
|
return stack.newFrame(asSubFrame = irFunction.isInline || irFunction.isLocal, initPool = valueArguments) {
|
||||||
val isWrapper = dispatchReceiver is Wrapper && rawExtensionReceiver == null
|
val isWrapper = dispatchReceiver is Wrapper && rawExtensionReceiver == null
|
||||||
val isInterfaceDefaultMethod = irFunction.body != null && (irFunction.parent as? IrClass)?.isInterface == true
|
val isInterfaceDefaultMethod = irFunction.body != null && (irFunction.parent as? IrClass)?.isInterface == true
|
||||||
@@ -367,6 +376,7 @@ class IrInterpreter(irModule: IrModuleFragment) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val state = Common(parent)
|
val state = Common(parent)
|
||||||
|
if (parent.isLocal) state.fields.addAll(stack.getAll()) // TODO save only necessary declarations
|
||||||
valueArguments.add(Variable(constructorCall.getThisAsReceiver(), state)) //used to set up fields in body
|
valueArguments.add(Variable(constructorCall.getThisAsReceiver(), state)) //used to set up fields in body
|
||||||
return stack.newFrame(initPool = valueArguments) {
|
return stack.newFrame(initPool = valueArguments) {
|
||||||
val statements = constructorCall.getBody()!!.statements
|
val statements = constructorCall.getBody()!!.statements
|
||||||
@@ -709,7 +719,9 @@ class IrInterpreter(irModule: IrModuleFragment) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun interpretFunctionExpression(expression: IrFunctionExpression): ExecutionResult {
|
private fun interpretFunctionExpression(expression: IrFunctionExpression): ExecutionResult {
|
||||||
stack.pushReturnValue(Lambda(expression.function, expression.type.classOrNull!!.owner))
|
val lambda = Lambda(expression.function, expression.type.classOrNull!!.owner)
|
||||||
|
if (expression.function.isLocal) lambda.fields.addAll(stack.getAll()) // TODO save only necessary declarations
|
||||||
|
stack.pushReturnValue(lambda)
|
||||||
return Next
|
return Next
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
@@ -234,3 +234,9 @@ fun State?.getFunctionReceiver(superIrClass: IrClass?): State? {
|
|||||||
else -> (this as Complex).superClass
|
else -> (this as Complex).superClass
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun IrFunctionAccessExpression.getVarargType(index: Int): IrType? {
|
||||||
|
val varargType = this.symbol.owner.valueParameters[index].varargElementType ?: return null
|
||||||
|
val typeParameter = varargType.classifierOrFail.owner as IrTypeParameter
|
||||||
|
return this.getTypeArgument(typeParameter.index)
|
||||||
|
}
|
||||||
+1
-1
@@ -28,7 +28,7 @@ class Lambda(val irFunction: IrFunction, override val irClass: IrClass) : State
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun copy(): State {
|
override fun copy(): State {
|
||||||
return Lambda(irFunction, irClass)
|
return Lambda(irFunction, irClass).apply { this.fields.addAll(this@Lambda.fields) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
|
|||||||
Reference in New Issue
Block a user