From 7fe776fe1023b5f66f96bc75a1e1bf82f6c67a3c Mon Sep 17 00:00:00 2001 From: Ivan Kylchik Date: Thu, 22 Oct 2020 15:03:53 +0300 Subject: [PATCH] Simplify work with stack by adding additional newFrame method --- .../kotlin/ir/interpreter/IrInterpreter.kt | 13 ++-- .../kotlin/ir/interpreter/stack/Stack.kt | 65 +++++++++---------- 2 files changed, 38 insertions(+), 40 deletions(-) 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 396595ff499..63256f159c0 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 @@ -73,10 +73,9 @@ class IrInterpreter(val irBuiltIns: IrBuiltIns, private val bodyMap: Map= MAX_COMMANDS) InterpreterTimeOutError().throwAsUserException() } - fun interpret(expression: IrExpression, parentFile: IrFile? = null): IrExpression { - stack.clean() - val result = stack.withEntryPoint(irFile = parentFile) { expression.interpret() } - return when (val returnLabel = result.returnLabel) { + fun interpret(expression: IrExpression, rootFile: IrFile? = null): IrExpression { + stack.clean(rootFile) + return when (val returnLabel = expression.interpret().returnLabel) { ReturnLabel.REGULAR -> stack.popReturnValue().toIrExpression(expression) ReturnLabel.EXCEPTION -> { val message = (stack.popReturnValue() as ExceptionState).getFullDescription() @@ -377,12 +376,12 @@ class IrInterpreter(val irBuiltIns: IrBuiltIns, private val bodyMap: Map stack.pushReturnValue(Primitive(array.value, constructorCall.type)) @@ -413,7 +412,7 @@ class IrInterpreter(val irBuiltIns: IrBuiltIns, private val bodyMap: Map { diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/stack/Stack.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/stack/Stack.kt index b30271d93e2..68de5f3acf6 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/stack/Stack.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/stack/Stack.kt @@ -21,13 +21,13 @@ import org.jetbrains.kotlin.ir.util.isLocal internal interface Stack { fun newFrame(asSubFrame: Boolean = false, initPool: List = listOf(), block: () -> ExecutionResult): ExecutionResult fun newFrame(irFunction: IrFunction, initPool: List = listOf(), block: () -> ExecutionResult): ExecutionResult + fun newFrame(irFile: IrFile?, initPool: List = listOf(), block: () -> ExecutionResult): ExecutionResult fun fixCallEntryPoint(irExpression: IrExpression) - fun withEntryPoint(irFunction: IrFunction? = null, irFile: IrFile? = null, block: () -> ExecutionResult): ExecutionResult fun getStackTrace(): List fun getStackCount(): Int - fun clean() + fun clean(rootFile: IrFile?) fun addVar(variable: Variable) fun addAll(variables: List) fun getVariable(symbol: IrSymbol): Variable @@ -41,16 +41,21 @@ internal interface Stack { } internal class StackImpl : Stack { - private val frameList = mutableListOf(FrameContainer()) // first frame is default, it is easier to work when last() is not null + private val frameList = mutableListOf() private fun getCurrentFrame() = frameList.last() private var stackCount = 0 - override fun newFrame(asSubFrame: Boolean, initPool: List, block: () -> ExecutionResult): ExecutionResult { + private fun addNewFrame(asSubFrame: Boolean, initPool: List, irFunction: IrFunction? = null, irFile: IrFile? = null) { val typeArgumentsPool = initPool.filter { it.symbol is IrTypeParameterSymbol } val valueArguments = initPool.filter { it.symbol !is IrTypeParameterSymbol } val newFrame = InterpreterFrame(valueArguments.toMutableList(), typeArgumentsPool) - if (asSubFrame) getCurrentFrame().addSubFrame(newFrame) else frameList.add(FrameContainer(newFrame)) + when { + asSubFrame -> getCurrentFrame().addSubFrame(newFrame) + else -> frameList.add(FrameContainer(irFile, irFunction, newFrame)) + } + } + private fun withStackIncrement(asSubFrame: Boolean, block: () -> ExecutionResult): ExecutionResult { return try { stackCount++ block() @@ -60,13 +65,20 @@ internal class StackImpl : Stack { } } + override fun newFrame(asSubFrame: Boolean, initPool: List, block: () -> ExecutionResult): ExecutionResult { + addNewFrame(asSubFrame, initPool, null, null) + return withStackIncrement(asSubFrame, block) + } + override fun newFrame(irFunction: IrFunction, initPool: List, block: () -> ExecutionResult): ExecutionResult { val asSubFrame = irFunction.isInline || irFunction.isLocal - return newFrame(asSubFrame, initPool) { - withEntryPoint(irFunction, irFunction.fileOrNull) { - block() - } - } + addNewFrame(asSubFrame, initPool, irFunction, irFunction.fileOrNull) + return withStackIncrement(asSubFrame, block) + } + + override fun newFrame(irFile: IrFile?, initPool: List, block: () -> ExecutionResult): ExecutionResult { + addNewFrame(false, initPool, null, irFile) + return withStackIncrement(false, block) } private fun removeLastFrame() { @@ -75,16 +87,9 @@ internal class StackImpl : Stack { } override fun fixCallEntryPoint(irExpression: IrExpression) { - val fileEntry = getCurrentFrame().entryPoint?.irFile?.fileEntry ?: return + val fileEntry = getCurrentFrame().irFile?.fileEntry ?: return val lineNum = fileEntry.getLineNumber(irExpression.startOffset) + 1 - getCurrentFrame().entryPoint?.lineNumber = lineNum - } - - // TODO remove method and create EntryPoint in frame constructor - override fun withEntryPoint(irFunction: IrFunction?, irFile: IrFile?, block: () -> ExecutionResult): ExecutionResult { - val frame = getCurrentFrame() - if (frame.entryPoint == null && irFile != null) frame.entryPoint = FrameContainer.Companion.EntryPoint(irFunction, irFile) - return block() + getCurrentFrame().lineNumber = lineNum } override fun getStackTrace(): List { @@ -94,10 +99,10 @@ internal class StackImpl : Stack { override fun getStackCount(): Int = stackCount - override fun clean() { + override fun clean(rootFile: IrFile?) { stackCount = 0 frameList.clear() - frameList.add(FrameContainer()) + rootFile?.let { frameList.add(FrameContainer(rootFile)) } } override fun addVar(variable: Variable) { @@ -137,17 +142,11 @@ internal class StackImpl : Stack { } } -private class FrameContainer(current: Frame = InterpreterFrame()) { - var entryPoint: EntryPoint? = null +private class FrameContainer(val irFile: IrFile? = null, private val entryPoint: IrFunction? = null, current: Frame = InterpreterFrame()) { + var lineNumber: Int = -1 private val innerStack = mutableListOf(current) private fun getTopFrame() = innerStack.first() - companion object { - class EntryPoint(val irFunction: IrFunction?, val irFile: IrFile) { - var lineNumber: Int = -1 - } - } - fun addSubFrame(frame: Frame) { innerStack.add(0, frame) } @@ -173,9 +172,9 @@ private class FrameContainer(current: Frame = InterpreterFrame()) { fun peekReturnValue() = getTopFrame().peekReturnValue() override fun toString(): String { - entryPoint?.irFile ?: return "Not defined" - val fileNameCapitalized = entryPoint!!.irFile.name.replace(".kt", "Kt").capitalize() - val lineNum = if (entryPoint?.lineNumber != -1) ":${entryPoint?.lineNumber}" else "" - return "at $fileNameCapitalized.${entryPoint?.irFunction?.fqNameWhenAvailable ?: ""}(${entryPoint!!.irFile.name}$lineNum)" + irFile ?: return "Not defined" + val fileNameCapitalized = irFile.name.replace(".kt", "Kt").capitalize() + val lineNum = if (lineNumber != -1) ":$lineNumber" else "" + return "at $fileNameCapitalized.${entryPoint?.fqNameWhenAvailable ?: ""}(${irFile.name}$lineNum)" } }