From 06a8156376be80bf5f299cd1c819ab7d9c2445f0 Mon Sep 17 00:00:00 2001 From: Ivan Kylchik Date: Wed, 2 Jun 2021 19:25:45 +0300 Subject: [PATCH] Change logic of returning object from constructor in interpreter For now there is no need to place object on stack before evaluation. The result will be taken from memory and all unnecessary values on stack will be removed --- .../jetbrains/kotlin/ir/interpreter/CallInterceptor.kt | 5 ++++- .../kotlin/ir/interpreter/InstructionsUnfolder.kt | 8 +++++++- .../org/jetbrains/kotlin/ir/interpreter/IrInterpreter.kt | 4 ++-- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/CallInterceptor.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/CallInterceptor.kt index fc90de101a9..4842782f57a 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/CallInterceptor.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/CallInterceptor.kt @@ -137,7 +137,10 @@ internal class DefaultCallInterceptor(override val interpreter: IrInterpreter) : when { Wrapper.mustBeHandledWithWrapper(irClass) || irClass.fqNameWhenAvailable!!.startsWith(Name.identifier("java")) -> { Wrapper.getConstructorMethod(irConstructor).invokeMethod(irConstructor, args) - if (constructorCall !is IrConstructorCall) (receiver as Common).superWrapperClass = callStack.popState() as Wrapper + when (constructorCall) { + is IrConstructorCall -> callStack.setState(constructorCall.getThisReceiver(), callStack.popState()) + else -> (receiver as Common).superWrapperClass = callStack.popState() as Wrapper + } } irClass.defaultType.isArray() || irClass.defaultType.isPrimitiveArray() -> { // array constructor doesn't have body so must be treated separately diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/InstructionsUnfolder.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/InstructionsUnfolder.kt index d04e4764f6b..5fae48cc6d1 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/InstructionsUnfolder.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/InstructionsUnfolder.kt @@ -200,11 +200,17 @@ private fun unfoldBlock(block: IrBlock, callStack: CallStack) { } private fun unfoldStatements(statements: List, callStack: CallStack) { + fun Int.isLastIndex(): Boolean = statements.size - 1 == this + for (i in statements.indices.reversed()) { when (val statement = statements[i]) { is IrClass -> if (!statement.isLocal) TODO("Only local classes are supported") is IrFunction -> if (!statement.isLocal) TODO("Only local functions are supported") - is IrExpression -> statement.handleAndDropResult(callStack, dropOnlyUnit = true) + is IrExpression -> + when { + i.isLastIndex() -> callStack.addInstruction(CompoundInstruction(statement)) + else -> statement.handleAndDropResult(callStack, dropOnlyUnit = true) + } else -> callStack.addInstruction(CompoundInstruction(statement)) } } diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/IrInterpreter.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/IrInterpreter.kt index 4bf6f9d31ae..d4a0373d19e 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/IrInterpreter.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/IrInterpreter.kt @@ -205,7 +205,7 @@ class IrInterpreter private constructor( .forEach { callStack.addVariable(Variable(it.symbol, KTypeState(call.getTypeArgument(it.index)!!, irBuiltIns.anyClass.owner))) } // 5. load up values onto stack - if (dispatchReceiver == null && extensionReceiver == null && irFunction.isLocal) callStack.copyUpValuesFromPreviousFrame() + if (irFunction.isLocal) callStack.copyUpValuesFromPreviousFrame() if (dispatchReceiver is StateWithClosure) callStack.loadUpValues(dispatchReceiver) if (extensionReceiver is StateWithClosure) callStack.loadUpValues(extensionReceiver) @@ -254,6 +254,7 @@ class IrInterpreter private constructor( @Suppress("UNUSED_PARAMETER") private fun interpretConstructor(constructor: IrConstructor) { + callStack.pushState(callStack.getState(constructor.parentAsClass.thisReceiver!!.symbol)) callStack.dropFrameAndCopyResult() } @@ -291,7 +292,6 @@ class IrInterpreter private constructor( superReceiver?.let { callStack.addVariable(Variable(it, objectState)) } callInterceptor.interceptConstructor(constructorCall, valueArguments) { - callStack.pushState(objectState) callStack.addInstruction(CompoundInstruction(constructor)) } }