diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/interpreter/IrInterpreter.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/interpreter/IrInterpreter.kt index 77289637e97..4aa8c862714 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/interpreter/IrInterpreter.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/interpreter/IrInterpreter.kt @@ -121,6 +121,7 @@ class IrInterpreter(irModule: IrModuleFragment) { is IrFunctionReference -> interpretFunctionReference(this) is IrComposite -> interpretComposite(this) + is IrClass -> if (this.isLocal) Next else TODO("Only local classes are supported") else -> TODO("${this.javaClass} not supported") } @@ -274,9 +275,11 @@ class IrInterpreter(irModule: IrModuleFragment) { return stack.newFrame(asSubFrame = true, initPool = pool) { 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().toPrimitiveStateArray(expression.getVarargType(i)!!)) + 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) } } @@ -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) { val isWrapper = dispatchReceiver is Wrapper && rawExtensionReceiver == null val isInterfaceDefaultMethod = irFunction.body != null && (irFunction.parent as? IrClass)?.isInterface == true @@ -367,6 +376,7 @@ class IrInterpreter(irModule: IrModuleFragment) { } 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 return stack.newFrame(initPool = valueArguments) { val statements = constructorCall.getBody()!!.statements @@ -709,7 +719,9 @@ class IrInterpreter(irModule: IrModuleFragment) { } 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 } diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/interpreter/Utils.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/interpreter/Utils.kt index fe2197f5b69..7069ddf77c6 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/interpreter/Utils.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/interpreter/Utils.kt @@ -233,4 +233,10 @@ fun State?.getFunctionReceiver(superIrClass: IrClass?): State? { } 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) } \ No newline at end of file diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/interpreter/state/Lambda.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/interpreter/state/Lambda.kt index b9bd9100d3d..7e206623b1e 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/interpreter/state/Lambda.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/interpreter/state/Lambda.kt @@ -28,7 +28,7 @@ class Lambda(val irFunction: IrFunction, override val irClass: IrClass) : State } override fun copy(): State { - return Lambda(irFunction, irClass) + return Lambda(irFunction, irClass).apply { this.fields.addAll(this@Lambda.fields) } } override fun toString(): String {