From ae9914afe04ebb952dc312a92272cb6fcaa963f4 Mon Sep 17 00:00:00 2001 From: Ivan Kylchik Date: Wed, 11 Aug 2021 16:42:40 +0300 Subject: [PATCH] Move `Instruction` interface to separate file --- .../kotlin/ir/interpreter/CallInterceptor.kt | 8 +- .../kotlin/ir/interpreter/Instruction.kt | 27 ++++ .../ir/interpreter/InstructionsUnfolder.kt | 134 +++++++++--------- .../kotlin/ir/interpreter/IrInterpreter.kt | 47 +++--- .../kotlin/ir/interpreter/stack/CallStack.kt | 26 ++-- 5 files changed, 129 insertions(+), 113 deletions(-) create mode 100644 compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/Instruction.kt 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 f95ff34e421..25f65a40541 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 @@ -50,7 +50,7 @@ internal class DefaultCallInterceptor(override val interpreter: IrInterpreter) : override fun interceptProxy(irFunction: IrFunction, valueArguments: List, expectedResultClass: Class<*>): Any? { val irCall = irFunction.createCall() return interpreter.withNewCallStack(irCall) { - this@withNewCallStack.environment.callStack.pushInstruction(SimpleInstruction(irCall)) + this@withNewCallStack.environment.callStack.pushSimpleInstruction(irCall) valueArguments.forEach { this@withNewCallStack.environment.callStack.pushState(it) } }.wrap(this@DefaultCallInterceptor, remainArraysAsIs = false, extendFrom = expectedResultClass) } @@ -67,7 +67,7 @@ internal class DefaultCallInterceptor(override val interpreter: IrInterpreter) : receiver is Primitive<*> -> calculateBuiltIns(irFunction, args) // check for js char, js long and get field for primitives // TODO try to save fields in Primitive -> then it is possible to move up next branch // TODO try to create backing field if it is missing - irFunction.body == null && irFunction.isAccessorOfPropertyWithBackingField() -> callStack.pushInstruction(CompoundInstruction(irFunction.createGetField())) + irFunction.body == null && irFunction.isAccessorOfPropertyWithBackingField() -> callStack.pushCompoundInstruction(irFunction.createGetField()) irFunction.body == null -> irFunction.trySubstituteFunctionBody() ?: calculateBuiltIns(irFunction, args) else -> defaultAction() } @@ -186,7 +186,7 @@ internal class DefaultCallInterceptor(override val interpreter: IrInterpreter) : constructorCall.putValueArgument(index, primitive.value.toIrConst(constructorValueParameters[index].owner.type)) } - callStack.pushInstruction(CompoundInstruction(constructorCall)) + callStack.pushCompoundInstruction(constructorCall) } private fun Any?.getType(defaultType: IrType): IrType { @@ -208,7 +208,7 @@ internal class DefaultCallInterceptor(override val interpreter: IrInterpreter) : private fun IrFunction.trySubstituteFunctionBody(): IrElement? { val signature = this.symbol.signature ?: return null this.body = bodyMap[signature] ?: return null - callStack.pushInstruction(CompoundInstruction(this)) + callStack.pushCompoundInstruction(this) return body } } diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/Instruction.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/Instruction.kt new file mode 100644 index 00000000000..3c0fde32815 --- /dev/null +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/Instruction.kt @@ -0,0 +1,27 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.ir.interpreter + +import org.jetbrains.kotlin.ir.IrElement +import org.jetbrains.kotlin.ir.interpreter.stack.CallStack + +internal interface Instruction { + val element: IrElement? +} + +internal class CompoundInstruction(override val element: IrElement?) : Instruction // must unwind first +internal class SimpleInstruction(override val element: IrElement) : Instruction // must interpret as is +internal class CustomInstruction(val evaluate: () -> Unit) : Instruction { + override val element: IrElement? = null +} + +internal fun CallStack.pushSimpleInstruction(element: IrElement) { + pushInstruction(SimpleInstruction(element)) +} + +internal fun CallStack.pushCompoundInstruction(element: IrElement?) { + pushInstruction(CompoundInstruction(element)) +} 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 703991cdb62..8d0f4bb8dfb 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 @@ -26,7 +26,7 @@ internal fun IrExpression.handleAndDropResult(callStack: CallStack, dropOnlyUnit if (!dropOnlyUnit && !this.type.isUnit() || callStack.peekState().isUnit()) callStack.popState() } callStack.pushInstruction(CustomInstruction(dropResult)) - callStack.pushInstruction(CompoundInstruction(this)) + callStack.pushCompoundInstruction(this) } internal fun unfoldInstruction(element: IrElement?, environment: IrInterpreterEnvironment) { @@ -45,11 +45,11 @@ internal fun unfoldInstruction(element: IrElement?, environment: IrInterpreterEn is IrBlock -> unfoldBlock(element, callStack) is IrReturn -> unfoldReturn(element, callStack) is IrSetField -> unfoldSetField(element, callStack) - is IrGetField -> callStack.pushInstruction(SimpleInstruction(element)) + is IrGetField -> callStack.pushSimpleInstruction(element) is IrGetValue -> unfoldGetValue(element, environment) is IrGetObjectValue -> unfoldGetObjectValue(element, environment) is IrGetEnumValue -> unfoldGetEnumValue(element, environment) - is IrConst<*> -> callStack.pushInstruction(SimpleInstruction(element)) + is IrConst<*> -> callStack.pushSimpleInstruction(element) is IrVariable -> unfoldVariable(element, callStack) is IrSetValue -> unfoldSetValue(element, callStack) is IrTypeOperatorCall -> unfoldTypeOperatorCall(element, callStack) @@ -60,12 +60,12 @@ internal fun unfoldInstruction(element: IrElement?, environment: IrInterpreterEn is IrBreak -> unfoldBreak(element, callStack) is IrContinue -> unfoldContinue(element, callStack) is IrVararg -> unfoldVararg(element, callStack) - is IrSpreadElement -> callStack.pushInstruction(CompoundInstruction(element.expression)) + is IrSpreadElement -> callStack.pushCompoundInstruction(element.expression) is IrTry -> unfoldTry(element, callStack) is IrCatch -> unfoldCatch(element, callStack) is IrThrow -> unfoldThrow(element, callStack) is IrStringConcatenation -> unfoldStringConcatenation(element, environment) - is IrFunctionExpression -> callStack.pushInstruction(SimpleInstruction(element)) + is IrFunctionExpression -> callStack.pushSimpleInstruction(element) is IrFunctionReference -> unfoldFunctionReference(element, callStack) is IrPropertyReference -> unfoldPropertyReference(element, callStack) is IrClassReference -> unfoldClassReference(element, callStack) @@ -83,7 +83,7 @@ private fun unfoldFunction(function: IrSimpleFunction, environment: IrInterprete } // SimpleInstruction with function is added in IrCall // It will serve as endpoint for all possible calls, there we drop frame and copy result to new one - function.body?.let { environment.callStack.pushInstruction(CompoundInstruction(it)) } + function.body?.let { environment.callStack.pushCompoundInstruction(it) } ?: throw InterpreterError("Ir function must be with body") } @@ -103,7 +103,7 @@ private fun unfoldConstructor(constructor: IrConstructor, callStack: CallStack) else -> { // SimpleInstruction with function is added in constructor call // It will serve as endpoint for all possible constructor calls, there we drop frame and return object - callStack.pushInstruction(CompoundInstruction(constructor.body!!)) + callStack.pushCompoundInstruction(constructor.body!!) } } } @@ -114,7 +114,7 @@ private fun unfoldValueParameters(expression: IrFunctionAccessExpression, enviro if (hasDefaults) { environment.getCachedFunction(expression.symbol, fromDelegatingCall = expression is IrDelegatingConstructorCall)?.let { val callToDefault = it.owner.createCall().apply { environment.irBuiltIns.copyArgs(expression, this) } - callStack.pushInstruction(CompoundInstruction(callToDefault)) + callStack.pushCompoundInstruction(callToDefault) return } @@ -162,14 +162,14 @@ private fun unfoldValueParameters(expression: IrFunctionAccessExpression, enviro val callToDefault = environment.setCachedFunction( expression.symbol, fromDelegatingCall = expression is IrDelegatingConstructorCall, newFunction = defaultFun.symbol ).owner.createCall().apply { environment.irBuiltIns.copyArgs(expression, this) } - callStack.pushInstruction(CompoundInstruction(callToDefault)) + callStack.pushCompoundInstruction(callToDefault) } else { val irFunction = expression.symbol.owner - callStack.pushInstruction(SimpleInstruction(expression)) + callStack.pushSimpleInstruction(expression) fun IrValueParameter.schedule(arg: IrExpression?) { - callStack.pushInstruction(SimpleInstruction(this)) - callStack.pushInstruction(CompoundInstruction(arg)) + callStack.pushSimpleInstruction(this) + callStack.pushCompoundInstruction(arg) } (expression.valueArgumentsCount - 1 downTo 0).forEach { irFunction.valueParameters[it].schedule(expression.getValueArgument(it)) } expression.extensionReceiver?.let { irFunction.extensionReceiverParameter!!.schedule(it) } @@ -183,25 +183,25 @@ private fun unfoldInstanceInitializerCall(instanceInitializerCall: IrInstanceIni toInitialize.reversed().forEach { when { - it is IrAnonymousInitializer -> callStack.pushInstruction(CompoundInstruction(it.body)) - it is IrProperty && it.backingField?.initializer?.expression != null -> callStack.pushInstruction(CompoundInstruction(it.backingField)) + it is IrAnonymousInitializer -> callStack.pushCompoundInstruction(it.body) + it is IrProperty && it.backingField?.initializer?.expression != null -> callStack.pushCompoundInstruction(it.backingField) } } } private fun unfoldField(field: IrField, callStack: CallStack) { - callStack.pushInstruction(SimpleInstruction(field)) - callStack.pushInstruction(CompoundInstruction(field.initializer?.expression)) + callStack.pushSimpleInstruction(field) + callStack.pushCompoundInstruction(field.initializer?.expression) } private fun unfoldBody(body: IrBody, callStack: CallStack) { - callStack.pushInstruction(SimpleInstruction(body)) + callStack.pushSimpleInstruction(body) unfoldStatements(body.statements, callStack) } private fun unfoldBlock(block: IrBlock, callStack: CallStack) { callStack.newSubFrame(block) - callStack.pushInstruction(SimpleInstruction(block)) + callStack.pushSimpleInstruction(block) unfoldStatements(block.statements, callStack) } @@ -214,24 +214,24 @@ private fun unfoldStatements(statements: List, callStack: CallStack is IrFunction -> if (!statement.isLocal) TODO("Only local functions are supported") is IrExpression -> when { - i.isLastIndex() -> callStack.pushInstruction(CompoundInstruction(statement)) + i.isLastIndex() -> callStack.pushCompoundInstruction(statement) else -> statement.handleAndDropResult(callStack, dropOnlyUnit = true) } - else -> callStack.pushInstruction(CompoundInstruction(statement)) + else -> callStack.pushCompoundInstruction(statement) } } } private fun unfoldReturn(expression: IrReturn, callStack: CallStack) { - callStack.pushInstruction(SimpleInstruction(expression)) - callStack.pushInstruction(CompoundInstruction(expression.value)) + callStack.pushSimpleInstruction(expression) + callStack.pushCompoundInstruction(expression.value) } private fun unfoldSetField(expression: IrSetField, callStack: CallStack) { verify(!expression.accessesTopLevelOrObjectField()) { "Cannot interpret set method on top level properties" } - callStack.pushInstruction(SimpleInstruction(expression)) - callStack.pushInstruction(CompoundInstruction(expression.value)) + callStack.pushSimpleInstruction(expression) + callStack.pushCompoundInstruction(expression.value) } private fun unfoldGetValue(expression: IrGetValue, environment: IrInterpreterEnvironment) { @@ -249,18 +249,18 @@ private fun unfoldGetObjectValue(expression: IrGetObjectValue, environment: IrIn val objectClass = expression.symbol.owner environment.mapOfObjects[objectClass.symbol]?.let { return callStack.pushState(it) } - callStack.pushInstruction(SimpleInstruction(expression)) + callStack.pushSimpleInstruction(expression) } private fun unfoldGetEnumValue(expression: IrGetEnumValue, environment: IrInterpreterEnvironment) { val callStack = environment.callStack environment.mapOfEnums[expression.symbol]?.let { return callStack.pushState(it) } - callStack.pushInstruction(SimpleInstruction(expression)) + callStack.pushSimpleInstruction(expression) val enumEntry = expression.symbol.owner val enumClass = enumEntry.symbol.owner.parentAsClass enumClass.declarations.filterIsInstance().forEach { - callStack.pushInstruction(SimpleInstruction(it)) + callStack.pushSimpleInstruction(it) } } @@ -268,45 +268,45 @@ private fun unfoldVariable(variable: IrVariable, callStack: CallStack) { when (variable.initializer) { null -> callStack.storeState(variable.symbol, null) else -> { - callStack.pushInstruction(SimpleInstruction(variable)) - callStack.pushInstruction(CompoundInstruction(variable.initializer!!)) + callStack.pushSimpleInstruction(variable) + callStack.pushCompoundInstruction(variable.initializer!!) } } } private fun unfoldSetValue(expression: IrSetValue, callStack: CallStack) { - callStack.pushInstruction(SimpleInstruction(expression)) - callStack.pushInstruction(CompoundInstruction(expression.value)) + callStack.pushSimpleInstruction(expression) + callStack.pushCompoundInstruction(expression.value) } private fun unfoldTypeOperatorCall(element: IrTypeOperatorCall, callStack: CallStack) { - callStack.pushInstruction(SimpleInstruction(element)) - callStack.pushInstruction(CompoundInstruction(element.argument)) + callStack.pushSimpleInstruction(element) + callStack.pushCompoundInstruction(element.argument) } private fun unfoldBranch(branch: IrBranch, callStack: CallStack) { - callStack.pushInstruction(SimpleInstruction(branch)) - callStack.pushInstruction(CompoundInstruction(branch.condition)) + callStack.pushSimpleInstruction(branch) + callStack.pushCompoundInstruction(branch.condition) } private fun unfoldWhileLoop(loop: IrWhileLoop, callStack: CallStack) { callStack.newSubFrame(loop) - callStack.pushInstruction(SimpleInstruction(loop)) - callStack.pushInstruction(CompoundInstruction(loop.condition)) + callStack.pushSimpleInstruction(loop) + callStack.pushCompoundInstruction(loop.condition) } private fun unfoldDoWhileLoop(loop: IrDoWhileLoop, callStack: CallStack) { callStack.newSubFrame(loop) - callStack.pushInstruction(SimpleInstruction(loop)) - callStack.pushInstruction(CompoundInstruction(loop.condition)) - callStack.pushInstruction(CompoundInstruction(loop.body)) + callStack.pushSimpleInstruction(loop) + callStack.pushCompoundInstruction(loop.condition) + callStack.pushCompoundInstruction(loop.body) } private fun unfoldWhen(element: IrWhen, callStack: CallStack) { // new sub frame to drop it after callStack.newSubFrame(element) - callStack.pushInstruction(SimpleInstruction(element)) - element.branches.reversed().forEach { callStack.pushInstruction(CompoundInstruction(it)) } + callStack.pushSimpleInstruction(element) + element.branches.reversed().forEach { callStack.pushCompoundInstruction(it) } } private fun unfoldContinue(element: IrContinue, callStack: CallStack) { @@ -318,14 +318,14 @@ private fun unfoldBreak(element: IrBreak, callStack: CallStack) { } private fun unfoldVararg(element: IrVararg, callStack: CallStack) { - callStack.pushInstruction(SimpleInstruction(element)) - element.elements.reversed().forEach { callStack.pushInstruction(CompoundInstruction(it)) } + callStack.pushSimpleInstruction(element) + element.elements.reversed().forEach { callStack.pushCompoundInstruction(it) } } private fun unfoldTry(element: IrTry, callStack: CallStack) { callStack.newSubFrame(element) - callStack.pushInstruction(SimpleInstruction(element)) - callStack.pushInstruction(CompoundInstruction(element.tryResult)) + callStack.pushSimpleInstruction(element) + callStack.pushCompoundInstruction(element.tryResult) } private fun unfoldCatch(element: IrCatch, callStack: CallStack) { @@ -336,19 +336,19 @@ private fun unfoldCatch(element: IrCatch, callStack: CallStack) { callStack.dropSubFrame() // drop other catch blocks callStack.newSubFrame(element) // new frame with IrTry instruction to interpret finally block at the end callStack.storeState(element.catchParameter.symbol, exceptionState) - callStack.pushInstruction(SimpleInstruction(frameOwner)) - callStack.pushInstruction(CompoundInstruction(element.result)) + callStack.pushSimpleInstruction(frameOwner) + callStack.pushCompoundInstruction(element.result) } } private fun unfoldThrow(expression: IrThrow, callStack: CallStack) { - callStack.pushInstruction(SimpleInstruction(expression)) - callStack.pushInstruction(CompoundInstruction(expression.value)) + callStack.pushSimpleInstruction(expression) + callStack.pushCompoundInstruction(expression.value) } private fun unfoldStringConcatenation(expression: IrStringConcatenation, environment: IrInterpreterEnvironment) { val callStack = environment.callStack - callStack.pushInstruction(SimpleInstruction(expression)) + callStack.pushSimpleInstruction(expression) // this callback is used to check the need for an explicit toString call val explicitToStringCheck = fun() { @@ -367,52 +367,52 @@ private fun unfoldStringConcatenation(expression: IrStringConcatenation, environ return callStack.pushState(environment.convertToState(result, environment.irBuiltIns.stringType)) } val toStringCall = state.createToStringIrCall() - callStack.pushInstruction(SimpleInstruction(toStringCall)) + callStack.pushSimpleInstruction(toStringCall) callStack.pushState(state) } } } expression.arguments.reversed().forEach { callStack.pushInstruction(CustomInstruction(explicitToStringCheck)) - callStack.pushInstruction(CompoundInstruction(it)) + callStack.pushCompoundInstruction(it) } } private fun unfoldComposite(element: IrComposite, callStack: CallStack) { when (element.origin) { IrStatementOrigin.DESTRUCTURING_DECLARATION, IrStatementOrigin.DO_WHILE_LOOP, null -> // is null for body of do while loop - element.statements.reversed().forEach { callStack.pushInstruction(CompoundInstruction(it)) } + element.statements.reversed().forEach { callStack.pushCompoundInstruction(it) } else -> TODO("${element.origin} not implemented") } } private fun unfoldFunctionReference(reference: IrFunctionReference, callStack: CallStack) { val function = reference.symbol.owner - callStack.pushInstruction(SimpleInstruction(reference)) + callStack.pushSimpleInstruction(reference) - reference.dispatchReceiver?.let { callStack.pushInstruction(SimpleInstruction(function.dispatchReceiverParameter!!)) } - reference.extensionReceiver?.let { callStack.pushInstruction(SimpleInstruction(function.extensionReceiverParameter!!)) } + reference.dispatchReceiver?.let { callStack.pushSimpleInstruction(function.dispatchReceiverParameter!!) } + reference.extensionReceiver?.let { callStack.pushSimpleInstruction(function.extensionReceiverParameter!!) } - reference.extensionReceiver?.let { callStack.pushInstruction(CompoundInstruction(it)) } - reference.dispatchReceiver?.let { callStack.pushInstruction(CompoundInstruction(it)) } + reference.extensionReceiver?.let { callStack.pushCompoundInstruction(it) } + reference.dispatchReceiver?.let { callStack.pushCompoundInstruction(it) } } private fun unfoldPropertyReference(propertyReference: IrPropertyReference, callStack: CallStack) { val getter = propertyReference.getter!!.owner - callStack.pushInstruction(SimpleInstruction(propertyReference)) + callStack.pushSimpleInstruction(propertyReference) - propertyReference.dispatchReceiver?.let { callStack.pushInstruction(SimpleInstruction(getter.dispatchReceiverParameter!!)) } - propertyReference.extensionReceiver?.let { callStack.pushInstruction(SimpleInstruction(getter.extensionReceiverParameter!!)) } + propertyReference.dispatchReceiver?.let { callStack.pushSimpleInstruction(getter.dispatchReceiverParameter!!) } + propertyReference.extensionReceiver?.let { callStack.pushSimpleInstruction(getter.extensionReceiverParameter!!) } - propertyReference.extensionReceiver?.let { callStack.pushInstruction(CompoundInstruction(it)) } - propertyReference.dispatchReceiver?.let { callStack.pushInstruction(CompoundInstruction(it)) } + propertyReference.extensionReceiver?.let { callStack.pushCompoundInstruction(it) } + propertyReference.dispatchReceiver?.let { callStack.pushCompoundInstruction(it) } } private fun unfoldClassReference(classReference: IrClassReference, callStack: CallStack) { - callStack.pushInstruction(SimpleInstruction(classReference)) + callStack.pushSimpleInstruction(classReference) } private fun unfoldGetClass(element: IrGetClass, callStack: CallStack) { - callStack.pushInstruction(SimpleInstruction(element)) - callStack.pushInstruction(CompoundInstruction(element.argument)) + callStack.pushSimpleInstruction(element) + callStack.pushCompoundInstruction(element.argument) } \ No newline at end of file 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 5041e496dc3..2083eea5ae6 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 @@ -23,17 +23,6 @@ import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.util.OperatorNameConventions -internal interface Instruction { - val element: IrElement? -} - -internal class CompoundInstruction(override val element: IrElement?) : Instruction // must unwind first -internal class SimpleInstruction(override val element: IrElement) : Instruction // must interpret as is -internal class CustomInstruction(val evaluate: () -> Unit) : Instruction { - override val element: IrElement? - get() = null -} - class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal val bodyMap: Map) { val irBuiltIns: IrBuiltIns get() = environment.irBuiltIns @@ -65,7 +54,7 @@ class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal fun interpret(expression: IrExpression, file: IrFile? = null): IrExpression { commandCount = 0 callStack.newFrame(expression, file) - callStack.pushInstruction(CompoundInstruction(expression)) + callStack.pushCompoundInstruction(expression) while (!callStack.hasNoInstructions()) { callStack.popInstruction().handle() @@ -174,7 +163,7 @@ class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal val reifiedTypeArguments = environment.loadReifiedTypeArguments(call) callStack.newFrame(irFunction) - callStack.pushInstruction(SimpleInstruction(irFunction)) + callStack.pushSimpleInstruction(irFunction) // 4. load up values onto stack; do it at first to set low priority of these variables if (dispatchReceiver is StateWithClosure) callStack.loadUpValues(dispatchReceiver) @@ -195,7 +184,7 @@ class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal if (dispatchReceiver is Complex && irFunction.parentClassOrNull?.isInner == true) dispatchReceiver.loadOuterClassesInto(callStack) callInterceptor.interceptCall(call, irFunction, args) { - callStack.pushInstruction(CompoundInstruction(irFunction)) + callStack.pushCompoundInstruction(irFunction) } } @@ -244,7 +233,7 @@ class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal val returnType = constructorCall.type.getTypeIfReified(callStack) callStack.newFrame(constructor) - callStack.pushInstruction(SimpleInstruction(constructor)) + callStack.pushSimpleInstruction(constructor) if (irClass.isLocal) callStack.loadUpValues(objectState as StateWithClosure) callStack.storeState(constructorCall.getThisReceiver(), objectState) @@ -274,7 +263,7 @@ class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal } callInterceptor.interceptConstructor(constructorCall, valueArguments) { - callStack.pushInstruction(CompoundInstruction(constructor)) + callStack.pushCompoundInstruction(constructor) } } @@ -303,7 +292,7 @@ class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal val constructorCall = IrConstructorCallImpl.fromSymbolOwner(constructor.returnType, constructor.symbol) constructorCall.putValueArgument(0, expression.value.toIrConst(signedType)) - return callStack.pushInstruction(CompoundInstruction(constructorCall)) + return callStack.pushCompoundInstruction(constructorCall) } callStack.pushState(expression.toPrimitive()) } @@ -317,9 +306,9 @@ class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal callStack.dropSubFrame() if (result) { callStack.newSubFrame(loop) - callStack.pushInstruction(SimpleInstruction(loop)) - callStack.pushInstruction(CompoundInstruction(loop.condition)) - callStack.pushInstruction(CompoundInstruction(loop.body)) + callStack.pushSimpleInstruction(loop) + callStack.pushCompoundInstruction(loop.condition) + callStack.pushCompoundInstruction(loop.body) } } @@ -328,9 +317,9 @@ class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal callStack.dropSubFrame() if (result) { callStack.newSubFrame(loop) - callStack.pushInstruction(SimpleInstruction(loop)) - callStack.pushInstruction(CompoundInstruction(loop.condition)) - callStack.pushInstruction(CompoundInstruction(loop.body)) + callStack.pushSimpleInstruction(loop) + callStack.pushCompoundInstruction(loop.condition) + callStack.pushCompoundInstruction(loop.body) } } @@ -338,7 +327,7 @@ class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal val result = callStack.popState().asBoolean() if (result) { callStack.dropSubFrame() - callStack.pushInstruction(CompoundInstruction(branch.result)) + callStack.pushCompoundInstruction(branch.result) } } @@ -355,12 +344,12 @@ class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal field.origin == IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB && field.isStatic -> { // for java static variables when (val initializerExpression = field.initializer?.expression) { - is IrConst<*> -> callStack.pushInstruction(SimpleInstruction(initializerExpression)) + is IrConst<*> -> callStack.pushSimpleInstruction(initializerExpression) else -> callInterceptor.interceptJavaStaticField(expression) } } field.origin == IrDeclarationOrigin.PROPERTY_BACKING_FIELD && field.correspondingPropertySymbol?.owner?.isConst == true -> { - callStack.pushInstruction(CompoundInstruction(field.initializer?.expression)) + callStack.pushCompoundInstruction(field.initializer?.expression) } expression.accessesTopLevelOrObjectField() -> { val propertyOwner = field.correspondingPropertySymbol?.owner @@ -368,7 +357,7 @@ class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal propertyOwner?.backingField?.initializer?.expression is IrConst<*> || propertyOwner?.parentClassOrNull?.hasAnnotation(compileTimeAnnotation) == true // check if object is marked as compile time verify(isConst) { "Cannot interpret get method on top level non const properties" } - callStack.pushInstruction(CompoundInstruction(field.initializer?.expression)) + callStack.pushCompoundInstruction(field.initializer?.expression) } else -> { val result = callStack.loadState(receiver!!).getField(field.correspondingPropertySymbol!!) @@ -391,7 +380,7 @@ class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal val constructor = objectClass.constructors.first() val constructorCall = IrConstructorCallImpl.fromSymbolOwner(constructor.returnType, constructor.symbol) - callStack.pushInstruction(CompoundInstruction(constructorCall)) + callStack.pushCompoundInstruction(constructorCall) } } @@ -428,7 +417,7 @@ class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal callStack.newSubFrame(enumEntry) callStack.pushInstruction(CustomInstruction(cleanEnumSuperCall)) - callStack.pushInstruction(CompoundInstruction(enumInitializer)) + callStack.pushCompoundInstruction(enumInitializer) callStack.storeState(enumConstructorCall.getThisReceiver(), enumClassObject) } } diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/stack/CallStack.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/stack/CallStack.kt index 870cdb1cda7..c171aa4ce26 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/stack/CallStack.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/stack/CallStack.kt @@ -10,10 +10,10 @@ import org.jetbrains.kotlin.ir.declarations.IrConstructor import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.expressions.* -import org.jetbrains.kotlin.ir.interpreter.CompoundInstruction import org.jetbrains.kotlin.ir.interpreter.Instruction -import org.jetbrains.kotlin.ir.interpreter.SimpleInstruction import org.jetbrains.kotlin.ir.interpreter.handleAndDropResult +import org.jetbrains.kotlin.ir.interpreter.pushCompoundInstruction +import org.jetbrains.kotlin.ir.interpreter.pushSimpleInstruction import org.jetbrains.kotlin.ir.interpreter.state.State import org.jetbrains.kotlin.ir.interpreter.state.StateWithClosure import org.jetbrains.kotlin.ir.symbols.IrSymbol @@ -60,7 +60,7 @@ internal class CallStack { is IrTry -> { dropSubFrame() pushState(result) - pushInstruction(SimpleInstruction(irReturn)) + pushSimpleInstruction(irReturn) frameOwner.finallyExpression?.handleAndDropResult(this) return } @@ -68,7 +68,7 @@ internal class CallStack { val tryBlock = currentFrame.dropInstructions()!!.element as IrTry// last instruction in `catch` block is `try` dropSubFrame() pushState(result) - pushInstruction(SimpleInstruction(irReturn)) + pushSimpleInstruction(irReturn) tryBlock.finallyExpression?.handleAndDropResult(this) return } @@ -81,7 +81,7 @@ internal class CallStack { } currentFrame.dropInstructions() - pushInstruction(SimpleInstruction(returnTarget)) + pushSimpleInstruction(returnTarget) if (returnTarget !is IrConstructor) pushState(result) } @@ -91,15 +91,15 @@ internal class CallStack { when (frameOwner) { is IrTry -> { currentFrame.removeSubFrameWithoutDataPropagation() - pushInstruction(CompoundInstruction(breakOrContinue)) + pushCompoundInstruction(breakOrContinue) newSubFrame(frameOwner) // will be deleted when interpret 'try' - pushInstruction(SimpleInstruction(frameOwner)) + pushSimpleInstruction(frameOwner) return } is IrCatch -> { val tryInstruction = currentFrame.dropInstructions()!! // last instruction in `catch` block is `try` currentFrame.removeSubFrameWithoutDataPropagation() - pushInstruction(CompoundInstruction(breakOrContinue)) + pushCompoundInstruction(breakOrContinue) newSubFrame(tryInstruction.element!!) // will be deleted when interpret 'try' pushInstruction(tryInstruction) return @@ -114,10 +114,10 @@ internal class CallStack { when (breakOrContinue) { is IrBreak -> currentFrame.removeSubFrameWithoutDataPropagation() // drop loop else -> if (breakOrContinue.loop is IrDoWhileLoop) { - pushInstruction(SimpleInstruction(breakOrContinue.loop)) - pushInstruction(CompoundInstruction(breakOrContinue.loop.condition)) + pushSimpleInstruction(breakOrContinue.loop) + pushCompoundInstruction(breakOrContinue.loop.condition) } else { - pushInstruction(CompoundInstruction(breakOrContinue.loop)) + pushCompoundInstruction(breakOrContinue.loop) } } } @@ -133,8 +133,8 @@ internal class CallStack { is IrTry -> { dropSubFrame() // drop all instructions that left newSubFrame(frameOwner) - pushInstruction(SimpleInstruction(frameOwner)) // to evaluate finally at the end - frameOwner.catches.reversed().forEach { pushInstruction(CompoundInstruction(it)) } + pushSimpleInstruction(frameOwner) // to evaluate finally at the end + frameOwner.catches.reversed().forEach { pushCompoundInstruction(it) } pushState(exception) return }