Move Instruction interface to separate file
This commit is contained in:
+4
-4
@@ -50,7 +50,7 @@ internal class DefaultCallInterceptor(override val interpreter: IrInterpreter) :
|
|||||||
override fun interceptProxy(irFunction: IrFunction, valueArguments: List<State>, expectedResultClass: Class<*>): Any? {
|
override fun interceptProxy(irFunction: IrFunction, valueArguments: List<State>, expectedResultClass: Class<*>): Any? {
|
||||||
val irCall = irFunction.createCall()
|
val irCall = irFunction.createCall()
|
||||||
return interpreter.withNewCallStack(irCall) {
|
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) }
|
valueArguments.forEach { this@withNewCallStack.environment.callStack.pushState(it) }
|
||||||
}.wrap(this@DefaultCallInterceptor, remainArraysAsIs = false, extendFrom = expectedResultClass)
|
}.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
|
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 save fields in Primitive -> then it is possible to move up next branch
|
||||||
// TODO try to create backing field if it is missing
|
// 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)
|
irFunction.body == null -> irFunction.trySubstituteFunctionBody() ?: calculateBuiltIns(irFunction, args)
|
||||||
else -> defaultAction()
|
else -> defaultAction()
|
||||||
}
|
}
|
||||||
@@ -186,7 +186,7 @@ internal class DefaultCallInterceptor(override val interpreter: IrInterpreter) :
|
|||||||
constructorCall.putValueArgument(index, primitive.value.toIrConst(constructorValueParameters[index].owner.type))
|
constructorCall.putValueArgument(index, primitive.value.toIrConst(constructorValueParameters[index].owner.type))
|
||||||
}
|
}
|
||||||
|
|
||||||
callStack.pushInstruction(CompoundInstruction(constructorCall))
|
callStack.pushCompoundInstruction(constructorCall)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Any?.getType(defaultType: IrType): IrType {
|
private fun Any?.getType(defaultType: IrType): IrType {
|
||||||
@@ -208,7 +208,7 @@ internal class DefaultCallInterceptor(override val interpreter: IrInterpreter) :
|
|||||||
private fun IrFunction.trySubstituteFunctionBody(): IrElement? {
|
private fun IrFunction.trySubstituteFunctionBody(): IrElement? {
|
||||||
val signature = this.symbol.signature ?: return null
|
val signature = this.symbol.signature ?: return null
|
||||||
this.body = bodyMap[signature] ?: return null
|
this.body = bodyMap[signature] ?: return null
|
||||||
callStack.pushInstruction(CompoundInstruction(this))
|
callStack.pushCompoundInstruction(this)
|
||||||
return body
|
return body
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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))
|
||||||
|
}
|
||||||
+67
-67
@@ -26,7 +26,7 @@ internal fun IrExpression.handleAndDropResult(callStack: CallStack, dropOnlyUnit
|
|||||||
if (!dropOnlyUnit && !this.type.isUnit() || callStack.peekState().isUnit()) callStack.popState()
|
if (!dropOnlyUnit && !this.type.isUnit() || callStack.peekState().isUnit()) callStack.popState()
|
||||||
}
|
}
|
||||||
callStack.pushInstruction(CustomInstruction(dropResult))
|
callStack.pushInstruction(CustomInstruction(dropResult))
|
||||||
callStack.pushInstruction(CompoundInstruction(this))
|
callStack.pushCompoundInstruction(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun unfoldInstruction(element: IrElement?, environment: IrInterpreterEnvironment) {
|
internal fun unfoldInstruction(element: IrElement?, environment: IrInterpreterEnvironment) {
|
||||||
@@ -45,11 +45,11 @@ internal fun unfoldInstruction(element: IrElement?, environment: IrInterpreterEn
|
|||||||
is IrBlock -> unfoldBlock(element, callStack)
|
is IrBlock -> unfoldBlock(element, callStack)
|
||||||
is IrReturn -> unfoldReturn(element, callStack)
|
is IrReturn -> unfoldReturn(element, callStack)
|
||||||
is IrSetField -> unfoldSetField(element, callStack)
|
is IrSetField -> unfoldSetField(element, callStack)
|
||||||
is IrGetField -> callStack.pushInstruction(SimpleInstruction(element))
|
is IrGetField -> callStack.pushSimpleInstruction(element)
|
||||||
is IrGetValue -> unfoldGetValue(element, environment)
|
is IrGetValue -> unfoldGetValue(element, environment)
|
||||||
is IrGetObjectValue -> unfoldGetObjectValue(element, environment)
|
is IrGetObjectValue -> unfoldGetObjectValue(element, environment)
|
||||||
is IrGetEnumValue -> unfoldGetEnumValue(element, environment)
|
is IrGetEnumValue -> unfoldGetEnumValue(element, environment)
|
||||||
is IrConst<*> -> callStack.pushInstruction(SimpleInstruction(element))
|
is IrConst<*> -> callStack.pushSimpleInstruction(element)
|
||||||
is IrVariable -> unfoldVariable(element, callStack)
|
is IrVariable -> unfoldVariable(element, callStack)
|
||||||
is IrSetValue -> unfoldSetValue(element, callStack)
|
is IrSetValue -> unfoldSetValue(element, callStack)
|
||||||
is IrTypeOperatorCall -> unfoldTypeOperatorCall(element, callStack)
|
is IrTypeOperatorCall -> unfoldTypeOperatorCall(element, callStack)
|
||||||
@@ -60,12 +60,12 @@ internal fun unfoldInstruction(element: IrElement?, environment: IrInterpreterEn
|
|||||||
is IrBreak -> unfoldBreak(element, callStack)
|
is IrBreak -> unfoldBreak(element, callStack)
|
||||||
is IrContinue -> unfoldContinue(element, callStack)
|
is IrContinue -> unfoldContinue(element, callStack)
|
||||||
is IrVararg -> unfoldVararg(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 IrTry -> unfoldTry(element, callStack)
|
||||||
is IrCatch -> unfoldCatch(element, callStack)
|
is IrCatch -> unfoldCatch(element, callStack)
|
||||||
is IrThrow -> unfoldThrow(element, callStack)
|
is IrThrow -> unfoldThrow(element, callStack)
|
||||||
is IrStringConcatenation -> unfoldStringConcatenation(element, environment)
|
is IrStringConcatenation -> unfoldStringConcatenation(element, environment)
|
||||||
is IrFunctionExpression -> callStack.pushInstruction(SimpleInstruction(element))
|
is IrFunctionExpression -> callStack.pushSimpleInstruction(element)
|
||||||
is IrFunctionReference -> unfoldFunctionReference(element, callStack)
|
is IrFunctionReference -> unfoldFunctionReference(element, callStack)
|
||||||
is IrPropertyReference -> unfoldPropertyReference(element, callStack)
|
is IrPropertyReference -> unfoldPropertyReference(element, callStack)
|
||||||
is IrClassReference -> unfoldClassReference(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
|
// 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
|
// 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")
|
?: throw InterpreterError("Ir function must be with body")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,7 +103,7 @@ private fun unfoldConstructor(constructor: IrConstructor, callStack: CallStack)
|
|||||||
else -> {
|
else -> {
|
||||||
// SimpleInstruction with function is added in constructor call
|
// 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
|
// 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) {
|
if (hasDefaults) {
|
||||||
environment.getCachedFunction(expression.symbol, fromDelegatingCall = expression is IrDelegatingConstructorCall)?.let {
|
environment.getCachedFunction(expression.symbol, fromDelegatingCall = expression is IrDelegatingConstructorCall)?.let {
|
||||||
val callToDefault = it.owner.createCall().apply { environment.irBuiltIns.copyArgs(expression, this) }
|
val callToDefault = it.owner.createCall().apply { environment.irBuiltIns.copyArgs(expression, this) }
|
||||||
callStack.pushInstruction(CompoundInstruction(callToDefault))
|
callStack.pushCompoundInstruction(callToDefault)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,14 +162,14 @@ private fun unfoldValueParameters(expression: IrFunctionAccessExpression, enviro
|
|||||||
val callToDefault = environment.setCachedFunction(
|
val callToDefault = environment.setCachedFunction(
|
||||||
expression.symbol, fromDelegatingCall = expression is IrDelegatingConstructorCall, newFunction = defaultFun.symbol
|
expression.symbol, fromDelegatingCall = expression is IrDelegatingConstructorCall, newFunction = defaultFun.symbol
|
||||||
).owner.createCall().apply { environment.irBuiltIns.copyArgs(expression, this) }
|
).owner.createCall().apply { environment.irBuiltIns.copyArgs(expression, this) }
|
||||||
callStack.pushInstruction(CompoundInstruction(callToDefault))
|
callStack.pushCompoundInstruction(callToDefault)
|
||||||
} else {
|
} else {
|
||||||
val irFunction = expression.symbol.owner
|
val irFunction = expression.symbol.owner
|
||||||
callStack.pushInstruction(SimpleInstruction(expression))
|
callStack.pushSimpleInstruction(expression)
|
||||||
|
|
||||||
fun IrValueParameter.schedule(arg: IrExpression?) {
|
fun IrValueParameter.schedule(arg: IrExpression?) {
|
||||||
callStack.pushInstruction(SimpleInstruction(this))
|
callStack.pushSimpleInstruction(this)
|
||||||
callStack.pushInstruction(CompoundInstruction(arg))
|
callStack.pushCompoundInstruction(arg)
|
||||||
}
|
}
|
||||||
(expression.valueArgumentsCount - 1 downTo 0).forEach { irFunction.valueParameters[it].schedule(expression.getValueArgument(it)) }
|
(expression.valueArgumentsCount - 1 downTo 0).forEach { irFunction.valueParameters[it].schedule(expression.getValueArgument(it)) }
|
||||||
expression.extensionReceiver?.let { irFunction.extensionReceiverParameter!!.schedule(it) }
|
expression.extensionReceiver?.let { irFunction.extensionReceiverParameter!!.schedule(it) }
|
||||||
@@ -183,25 +183,25 @@ private fun unfoldInstanceInitializerCall(instanceInitializerCall: IrInstanceIni
|
|||||||
|
|
||||||
toInitialize.reversed().forEach {
|
toInitialize.reversed().forEach {
|
||||||
when {
|
when {
|
||||||
it is IrAnonymousInitializer -> callStack.pushInstruction(CompoundInstruction(it.body))
|
it is IrAnonymousInitializer -> callStack.pushCompoundInstruction(it.body)
|
||||||
it is IrProperty && it.backingField?.initializer?.expression != null -> callStack.pushInstruction(CompoundInstruction(it.backingField))
|
it is IrProperty && it.backingField?.initializer?.expression != null -> callStack.pushCompoundInstruction(it.backingField)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun unfoldField(field: IrField, callStack: CallStack) {
|
private fun unfoldField(field: IrField, callStack: CallStack) {
|
||||||
callStack.pushInstruction(SimpleInstruction(field))
|
callStack.pushSimpleInstruction(field)
|
||||||
callStack.pushInstruction(CompoundInstruction(field.initializer?.expression))
|
callStack.pushCompoundInstruction(field.initializer?.expression)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun unfoldBody(body: IrBody, callStack: CallStack) {
|
private fun unfoldBody(body: IrBody, callStack: CallStack) {
|
||||||
callStack.pushInstruction(SimpleInstruction(body))
|
callStack.pushSimpleInstruction(body)
|
||||||
unfoldStatements(body.statements, callStack)
|
unfoldStatements(body.statements, callStack)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun unfoldBlock(block: IrBlock, callStack: CallStack) {
|
private fun unfoldBlock(block: IrBlock, callStack: CallStack) {
|
||||||
callStack.newSubFrame(block)
|
callStack.newSubFrame(block)
|
||||||
callStack.pushInstruction(SimpleInstruction(block))
|
callStack.pushSimpleInstruction(block)
|
||||||
unfoldStatements(block.statements, callStack)
|
unfoldStatements(block.statements, callStack)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,24 +214,24 @@ private fun unfoldStatements(statements: List<IrStatement>, callStack: CallStack
|
|||||||
is IrFunction -> if (!statement.isLocal) TODO("Only local functions are supported")
|
is IrFunction -> if (!statement.isLocal) TODO("Only local functions are supported")
|
||||||
is IrExpression ->
|
is IrExpression ->
|
||||||
when {
|
when {
|
||||||
i.isLastIndex() -> callStack.pushInstruction(CompoundInstruction(statement))
|
i.isLastIndex() -> callStack.pushCompoundInstruction(statement)
|
||||||
else -> statement.handleAndDropResult(callStack, dropOnlyUnit = true)
|
else -> statement.handleAndDropResult(callStack, dropOnlyUnit = true)
|
||||||
}
|
}
|
||||||
else -> callStack.pushInstruction(CompoundInstruction(statement))
|
else -> callStack.pushCompoundInstruction(statement)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun unfoldReturn(expression: IrReturn, callStack: CallStack) {
|
private fun unfoldReturn(expression: IrReturn, callStack: CallStack) {
|
||||||
callStack.pushInstruction(SimpleInstruction(expression))
|
callStack.pushSimpleInstruction(expression)
|
||||||
callStack.pushInstruction(CompoundInstruction(expression.value))
|
callStack.pushCompoundInstruction(expression.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun unfoldSetField(expression: IrSetField, callStack: CallStack) {
|
private fun unfoldSetField(expression: IrSetField, callStack: CallStack) {
|
||||||
verify(!expression.accessesTopLevelOrObjectField()) { "Cannot interpret set method on top level properties" }
|
verify(!expression.accessesTopLevelOrObjectField()) { "Cannot interpret set method on top level properties" }
|
||||||
|
|
||||||
callStack.pushInstruction(SimpleInstruction(expression))
|
callStack.pushSimpleInstruction(expression)
|
||||||
callStack.pushInstruction(CompoundInstruction(expression.value))
|
callStack.pushCompoundInstruction(expression.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun unfoldGetValue(expression: IrGetValue, environment: IrInterpreterEnvironment) {
|
private fun unfoldGetValue(expression: IrGetValue, environment: IrInterpreterEnvironment) {
|
||||||
@@ -249,18 +249,18 @@ private fun unfoldGetObjectValue(expression: IrGetObjectValue, environment: IrIn
|
|||||||
val objectClass = expression.symbol.owner
|
val objectClass = expression.symbol.owner
|
||||||
environment.mapOfObjects[objectClass.symbol]?.let { return callStack.pushState(it) }
|
environment.mapOfObjects[objectClass.symbol]?.let { return callStack.pushState(it) }
|
||||||
|
|
||||||
callStack.pushInstruction(SimpleInstruction(expression))
|
callStack.pushSimpleInstruction(expression)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun unfoldGetEnumValue(expression: IrGetEnumValue, environment: IrInterpreterEnvironment) {
|
private fun unfoldGetEnumValue(expression: IrGetEnumValue, environment: IrInterpreterEnvironment) {
|
||||||
val callStack = environment.callStack
|
val callStack = environment.callStack
|
||||||
environment.mapOfEnums[expression.symbol]?.let { return callStack.pushState(it) }
|
environment.mapOfEnums[expression.symbol]?.let { return callStack.pushState(it) }
|
||||||
|
|
||||||
callStack.pushInstruction(SimpleInstruction(expression))
|
callStack.pushSimpleInstruction(expression)
|
||||||
val enumEntry = expression.symbol.owner
|
val enumEntry = expression.symbol.owner
|
||||||
val enumClass = enumEntry.symbol.owner.parentAsClass
|
val enumClass = enumEntry.symbol.owner.parentAsClass
|
||||||
enumClass.declarations.filterIsInstance<IrEnumEntry>().forEach {
|
enumClass.declarations.filterIsInstance<IrEnumEntry>().forEach {
|
||||||
callStack.pushInstruction(SimpleInstruction(it))
|
callStack.pushSimpleInstruction(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -268,45 +268,45 @@ private fun unfoldVariable(variable: IrVariable, callStack: CallStack) {
|
|||||||
when (variable.initializer) {
|
when (variable.initializer) {
|
||||||
null -> callStack.storeState(variable.symbol, null)
|
null -> callStack.storeState(variable.symbol, null)
|
||||||
else -> {
|
else -> {
|
||||||
callStack.pushInstruction(SimpleInstruction(variable))
|
callStack.pushSimpleInstruction(variable)
|
||||||
callStack.pushInstruction(CompoundInstruction(variable.initializer!!))
|
callStack.pushCompoundInstruction(variable.initializer!!)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun unfoldSetValue(expression: IrSetValue, callStack: CallStack) {
|
private fun unfoldSetValue(expression: IrSetValue, callStack: CallStack) {
|
||||||
callStack.pushInstruction(SimpleInstruction(expression))
|
callStack.pushSimpleInstruction(expression)
|
||||||
callStack.pushInstruction(CompoundInstruction(expression.value))
|
callStack.pushCompoundInstruction(expression.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun unfoldTypeOperatorCall(element: IrTypeOperatorCall, callStack: CallStack) {
|
private fun unfoldTypeOperatorCall(element: IrTypeOperatorCall, callStack: CallStack) {
|
||||||
callStack.pushInstruction(SimpleInstruction(element))
|
callStack.pushSimpleInstruction(element)
|
||||||
callStack.pushInstruction(CompoundInstruction(element.argument))
|
callStack.pushCompoundInstruction(element.argument)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun unfoldBranch(branch: IrBranch, callStack: CallStack) {
|
private fun unfoldBranch(branch: IrBranch, callStack: CallStack) {
|
||||||
callStack.pushInstruction(SimpleInstruction(branch))
|
callStack.pushSimpleInstruction(branch)
|
||||||
callStack.pushInstruction(CompoundInstruction(branch.condition))
|
callStack.pushCompoundInstruction(branch.condition)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun unfoldWhileLoop(loop: IrWhileLoop, callStack: CallStack) {
|
private fun unfoldWhileLoop(loop: IrWhileLoop, callStack: CallStack) {
|
||||||
callStack.newSubFrame(loop)
|
callStack.newSubFrame(loop)
|
||||||
callStack.pushInstruction(SimpleInstruction(loop))
|
callStack.pushSimpleInstruction(loop)
|
||||||
callStack.pushInstruction(CompoundInstruction(loop.condition))
|
callStack.pushCompoundInstruction(loop.condition)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun unfoldDoWhileLoop(loop: IrDoWhileLoop, callStack: CallStack) {
|
private fun unfoldDoWhileLoop(loop: IrDoWhileLoop, callStack: CallStack) {
|
||||||
callStack.newSubFrame(loop)
|
callStack.newSubFrame(loop)
|
||||||
callStack.pushInstruction(SimpleInstruction(loop))
|
callStack.pushSimpleInstruction(loop)
|
||||||
callStack.pushInstruction(CompoundInstruction(loop.condition))
|
callStack.pushCompoundInstruction(loop.condition)
|
||||||
callStack.pushInstruction(CompoundInstruction(loop.body))
|
callStack.pushCompoundInstruction(loop.body)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun unfoldWhen(element: IrWhen, callStack: CallStack) {
|
private fun unfoldWhen(element: IrWhen, callStack: CallStack) {
|
||||||
// new sub frame to drop it after
|
// new sub frame to drop it after
|
||||||
callStack.newSubFrame(element)
|
callStack.newSubFrame(element)
|
||||||
callStack.pushInstruction(SimpleInstruction(element))
|
callStack.pushSimpleInstruction(element)
|
||||||
element.branches.reversed().forEach { callStack.pushInstruction(CompoundInstruction(it)) }
|
element.branches.reversed().forEach { callStack.pushCompoundInstruction(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun unfoldContinue(element: IrContinue, callStack: CallStack) {
|
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) {
|
private fun unfoldVararg(element: IrVararg, callStack: CallStack) {
|
||||||
callStack.pushInstruction(SimpleInstruction(element))
|
callStack.pushSimpleInstruction(element)
|
||||||
element.elements.reversed().forEach { callStack.pushInstruction(CompoundInstruction(it)) }
|
element.elements.reversed().forEach { callStack.pushCompoundInstruction(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun unfoldTry(element: IrTry, callStack: CallStack) {
|
private fun unfoldTry(element: IrTry, callStack: CallStack) {
|
||||||
callStack.newSubFrame(element)
|
callStack.newSubFrame(element)
|
||||||
callStack.pushInstruction(SimpleInstruction(element))
|
callStack.pushSimpleInstruction(element)
|
||||||
callStack.pushInstruction(CompoundInstruction(element.tryResult))
|
callStack.pushCompoundInstruction(element.tryResult)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun unfoldCatch(element: IrCatch, callStack: CallStack) {
|
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.dropSubFrame() // drop other catch blocks
|
||||||
callStack.newSubFrame(element) // new frame with IrTry instruction to interpret finally block at the end
|
callStack.newSubFrame(element) // new frame with IrTry instruction to interpret finally block at the end
|
||||||
callStack.storeState(element.catchParameter.symbol, exceptionState)
|
callStack.storeState(element.catchParameter.symbol, exceptionState)
|
||||||
callStack.pushInstruction(SimpleInstruction(frameOwner))
|
callStack.pushSimpleInstruction(frameOwner)
|
||||||
callStack.pushInstruction(CompoundInstruction(element.result))
|
callStack.pushCompoundInstruction(element.result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun unfoldThrow(expression: IrThrow, callStack: CallStack) {
|
private fun unfoldThrow(expression: IrThrow, callStack: CallStack) {
|
||||||
callStack.pushInstruction(SimpleInstruction(expression))
|
callStack.pushSimpleInstruction(expression)
|
||||||
callStack.pushInstruction(CompoundInstruction(expression.value))
|
callStack.pushCompoundInstruction(expression.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun unfoldStringConcatenation(expression: IrStringConcatenation, environment: IrInterpreterEnvironment) {
|
private fun unfoldStringConcatenation(expression: IrStringConcatenation, environment: IrInterpreterEnvironment) {
|
||||||
val callStack = environment.callStack
|
val callStack = environment.callStack
|
||||||
callStack.pushInstruction(SimpleInstruction(expression))
|
callStack.pushSimpleInstruction(expression)
|
||||||
|
|
||||||
// this callback is used to check the need for an explicit toString call
|
// this callback is used to check the need for an explicit toString call
|
||||||
val explicitToStringCheck = fun() {
|
val explicitToStringCheck = fun() {
|
||||||
@@ -367,52 +367,52 @@ private fun unfoldStringConcatenation(expression: IrStringConcatenation, environ
|
|||||||
return callStack.pushState(environment.convertToState(result, environment.irBuiltIns.stringType))
|
return callStack.pushState(environment.convertToState(result, environment.irBuiltIns.stringType))
|
||||||
}
|
}
|
||||||
val toStringCall = state.createToStringIrCall()
|
val toStringCall = state.createToStringIrCall()
|
||||||
callStack.pushInstruction(SimpleInstruction(toStringCall))
|
callStack.pushSimpleInstruction(toStringCall)
|
||||||
callStack.pushState(state)
|
callStack.pushState(state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expression.arguments.reversed().forEach {
|
expression.arguments.reversed().forEach {
|
||||||
callStack.pushInstruction(CustomInstruction(explicitToStringCheck))
|
callStack.pushInstruction(CustomInstruction(explicitToStringCheck))
|
||||||
callStack.pushInstruction(CompoundInstruction(it))
|
callStack.pushCompoundInstruction(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun unfoldComposite(element: IrComposite, callStack: CallStack) {
|
private fun unfoldComposite(element: IrComposite, callStack: CallStack) {
|
||||||
when (element.origin) {
|
when (element.origin) {
|
||||||
IrStatementOrigin.DESTRUCTURING_DECLARATION, IrStatementOrigin.DO_WHILE_LOOP, null -> // is null for body of do while loop
|
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")
|
else -> TODO("${element.origin} not implemented")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun unfoldFunctionReference(reference: IrFunctionReference, callStack: CallStack) {
|
private fun unfoldFunctionReference(reference: IrFunctionReference, callStack: CallStack) {
|
||||||
val function = reference.symbol.owner
|
val function = reference.symbol.owner
|
||||||
callStack.pushInstruction(SimpleInstruction(reference))
|
callStack.pushSimpleInstruction(reference)
|
||||||
|
|
||||||
reference.dispatchReceiver?.let { callStack.pushInstruction(SimpleInstruction(function.dispatchReceiverParameter!!)) }
|
reference.dispatchReceiver?.let { callStack.pushSimpleInstruction(function.dispatchReceiverParameter!!) }
|
||||||
reference.extensionReceiver?.let { callStack.pushInstruction(SimpleInstruction(function.extensionReceiverParameter!!)) }
|
reference.extensionReceiver?.let { callStack.pushSimpleInstruction(function.extensionReceiverParameter!!) }
|
||||||
|
|
||||||
reference.extensionReceiver?.let { callStack.pushInstruction(CompoundInstruction(it)) }
|
reference.extensionReceiver?.let { callStack.pushCompoundInstruction(it) }
|
||||||
reference.dispatchReceiver?.let { callStack.pushInstruction(CompoundInstruction(it)) }
|
reference.dispatchReceiver?.let { callStack.pushCompoundInstruction(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun unfoldPropertyReference(propertyReference: IrPropertyReference, callStack: CallStack) {
|
private fun unfoldPropertyReference(propertyReference: IrPropertyReference, callStack: CallStack) {
|
||||||
val getter = propertyReference.getter!!.owner
|
val getter = propertyReference.getter!!.owner
|
||||||
callStack.pushInstruction(SimpleInstruction(propertyReference))
|
callStack.pushSimpleInstruction(propertyReference)
|
||||||
|
|
||||||
propertyReference.dispatchReceiver?.let { callStack.pushInstruction(SimpleInstruction(getter.dispatchReceiverParameter!!)) }
|
propertyReference.dispatchReceiver?.let { callStack.pushSimpleInstruction(getter.dispatchReceiverParameter!!) }
|
||||||
propertyReference.extensionReceiver?.let { callStack.pushInstruction(SimpleInstruction(getter.extensionReceiverParameter!!)) }
|
propertyReference.extensionReceiver?.let { callStack.pushSimpleInstruction(getter.extensionReceiverParameter!!) }
|
||||||
|
|
||||||
propertyReference.extensionReceiver?.let { callStack.pushInstruction(CompoundInstruction(it)) }
|
propertyReference.extensionReceiver?.let { callStack.pushCompoundInstruction(it) }
|
||||||
propertyReference.dispatchReceiver?.let { callStack.pushInstruction(CompoundInstruction(it)) }
|
propertyReference.dispatchReceiver?.let { callStack.pushCompoundInstruction(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun unfoldClassReference(classReference: IrClassReference, callStack: CallStack) {
|
private fun unfoldClassReference(classReference: IrClassReference, callStack: CallStack) {
|
||||||
callStack.pushInstruction(SimpleInstruction(classReference))
|
callStack.pushSimpleInstruction(classReference)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun unfoldGetClass(element: IrGetClass, callStack: CallStack) {
|
private fun unfoldGetClass(element: IrGetClass, callStack: CallStack) {
|
||||||
callStack.pushInstruction(SimpleInstruction(element))
|
callStack.pushSimpleInstruction(element)
|
||||||
callStack.pushInstruction(CompoundInstruction(element.argument))
|
callStack.pushCompoundInstruction(element.argument)
|
||||||
}
|
}
|
||||||
+18
-29
@@ -23,17 +23,6 @@ import org.jetbrains.kotlin.ir.types.*
|
|||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
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<IdSignature, IrBody>) {
|
class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal val bodyMap: Map<IdSignature, IrBody>) {
|
||||||
val irBuiltIns: IrBuiltIns
|
val irBuiltIns: IrBuiltIns
|
||||||
get() = environment.irBuiltIns
|
get() = environment.irBuiltIns
|
||||||
@@ -65,7 +54,7 @@ class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal
|
|||||||
fun interpret(expression: IrExpression, file: IrFile? = null): IrExpression {
|
fun interpret(expression: IrExpression, file: IrFile? = null): IrExpression {
|
||||||
commandCount = 0
|
commandCount = 0
|
||||||
callStack.newFrame(expression, file)
|
callStack.newFrame(expression, file)
|
||||||
callStack.pushInstruction(CompoundInstruction(expression))
|
callStack.pushCompoundInstruction(expression)
|
||||||
|
|
||||||
while (!callStack.hasNoInstructions()) {
|
while (!callStack.hasNoInstructions()) {
|
||||||
callStack.popInstruction().handle()
|
callStack.popInstruction().handle()
|
||||||
@@ -174,7 +163,7 @@ class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal
|
|||||||
val reifiedTypeArguments = environment.loadReifiedTypeArguments(call)
|
val reifiedTypeArguments = environment.loadReifiedTypeArguments(call)
|
||||||
|
|
||||||
callStack.newFrame(irFunction)
|
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
|
// 4. load up values onto stack; do it at first to set low priority of these variables
|
||||||
if (dispatchReceiver is StateWithClosure) callStack.loadUpValues(dispatchReceiver)
|
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)
|
if (dispatchReceiver is Complex && irFunction.parentClassOrNull?.isInner == true) dispatchReceiver.loadOuterClassesInto(callStack)
|
||||||
|
|
||||||
callInterceptor.interceptCall(call, irFunction, args) {
|
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)
|
val returnType = constructorCall.type.getTypeIfReified(callStack)
|
||||||
|
|
||||||
callStack.newFrame(constructor)
|
callStack.newFrame(constructor)
|
||||||
callStack.pushInstruction(SimpleInstruction(constructor))
|
callStack.pushSimpleInstruction(constructor)
|
||||||
if (irClass.isLocal) callStack.loadUpValues(objectState as StateWithClosure)
|
if (irClass.isLocal) callStack.loadUpValues(objectState as StateWithClosure)
|
||||||
|
|
||||||
callStack.storeState(constructorCall.getThisReceiver(), objectState)
|
callStack.storeState(constructorCall.getThisReceiver(), objectState)
|
||||||
@@ -274,7 +263,7 @@ class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal
|
|||||||
}
|
}
|
||||||
|
|
||||||
callInterceptor.interceptConstructor(constructorCall, valueArguments) {
|
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)
|
val constructorCall = IrConstructorCallImpl.fromSymbolOwner(constructor.returnType, constructor.symbol)
|
||||||
constructorCall.putValueArgument(0, expression.value.toIrConst(signedType))
|
constructorCall.putValueArgument(0, expression.value.toIrConst(signedType))
|
||||||
|
|
||||||
return callStack.pushInstruction(CompoundInstruction(constructorCall))
|
return callStack.pushCompoundInstruction(constructorCall)
|
||||||
}
|
}
|
||||||
callStack.pushState(expression.toPrimitive())
|
callStack.pushState(expression.toPrimitive())
|
||||||
}
|
}
|
||||||
@@ -317,9 +306,9 @@ class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal
|
|||||||
callStack.dropSubFrame()
|
callStack.dropSubFrame()
|
||||||
if (result) {
|
if (result) {
|
||||||
callStack.newSubFrame(loop)
|
callStack.newSubFrame(loop)
|
||||||
callStack.pushInstruction(SimpleInstruction(loop))
|
callStack.pushSimpleInstruction(loop)
|
||||||
callStack.pushInstruction(CompoundInstruction(loop.condition))
|
callStack.pushCompoundInstruction(loop.condition)
|
||||||
callStack.pushInstruction(CompoundInstruction(loop.body))
|
callStack.pushCompoundInstruction(loop.body)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -328,9 +317,9 @@ class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal
|
|||||||
callStack.dropSubFrame()
|
callStack.dropSubFrame()
|
||||||
if (result) {
|
if (result) {
|
||||||
callStack.newSubFrame(loop)
|
callStack.newSubFrame(loop)
|
||||||
callStack.pushInstruction(SimpleInstruction(loop))
|
callStack.pushSimpleInstruction(loop)
|
||||||
callStack.pushInstruction(CompoundInstruction(loop.condition))
|
callStack.pushCompoundInstruction(loop.condition)
|
||||||
callStack.pushInstruction(CompoundInstruction(loop.body))
|
callStack.pushCompoundInstruction(loop.body)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -338,7 +327,7 @@ class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal
|
|||||||
val result = callStack.popState().asBoolean()
|
val result = callStack.popState().asBoolean()
|
||||||
if (result) {
|
if (result) {
|
||||||
callStack.dropSubFrame()
|
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 -> {
|
field.origin == IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB && field.isStatic -> {
|
||||||
// for java static variables
|
// for java static variables
|
||||||
when (val initializerExpression = field.initializer?.expression) {
|
when (val initializerExpression = field.initializer?.expression) {
|
||||||
is IrConst<*> -> callStack.pushInstruction(SimpleInstruction(initializerExpression))
|
is IrConst<*> -> callStack.pushSimpleInstruction(initializerExpression)
|
||||||
else -> callInterceptor.interceptJavaStaticField(expression)
|
else -> callInterceptor.interceptJavaStaticField(expression)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
field.origin == IrDeclarationOrigin.PROPERTY_BACKING_FIELD && field.correspondingPropertySymbol?.owner?.isConst == true -> {
|
field.origin == IrDeclarationOrigin.PROPERTY_BACKING_FIELD && field.correspondingPropertySymbol?.owner?.isConst == true -> {
|
||||||
callStack.pushInstruction(CompoundInstruction(field.initializer?.expression))
|
callStack.pushCompoundInstruction(field.initializer?.expression)
|
||||||
}
|
}
|
||||||
expression.accessesTopLevelOrObjectField() -> {
|
expression.accessesTopLevelOrObjectField() -> {
|
||||||
val propertyOwner = field.correspondingPropertySymbol?.owner
|
val propertyOwner = field.correspondingPropertySymbol?.owner
|
||||||
@@ -368,7 +357,7 @@ class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal
|
|||||||
propertyOwner?.backingField?.initializer?.expression is IrConst<*> ||
|
propertyOwner?.backingField?.initializer?.expression is IrConst<*> ||
|
||||||
propertyOwner?.parentClassOrNull?.hasAnnotation(compileTimeAnnotation) == true // check if object is marked as compile time
|
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" }
|
verify(isConst) { "Cannot interpret get method on top level non const properties" }
|
||||||
callStack.pushInstruction(CompoundInstruction(field.initializer?.expression))
|
callStack.pushCompoundInstruction(field.initializer?.expression)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
val result = callStack.loadState(receiver!!).getField(field.correspondingPropertySymbol!!)
|
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 constructor = objectClass.constructors.first()
|
||||||
val constructorCall = IrConstructorCallImpl.fromSymbolOwner(constructor.returnType, constructor.symbol)
|
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.newSubFrame(enumEntry)
|
||||||
callStack.pushInstruction(CustomInstruction(cleanEnumSuperCall))
|
callStack.pushInstruction(CustomInstruction(cleanEnumSuperCall))
|
||||||
callStack.pushInstruction(CompoundInstruction(enumInitializer))
|
callStack.pushCompoundInstruction(enumInitializer)
|
||||||
callStack.storeState(enumConstructorCall.getThisReceiver(), enumClassObject)
|
callStack.storeState(enumConstructorCall.getThisReceiver(), enumClassObject)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-13
@@ -10,10 +10,10 @@ import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
|||||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
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.Instruction
|
||||||
import org.jetbrains.kotlin.ir.interpreter.SimpleInstruction
|
|
||||||
import org.jetbrains.kotlin.ir.interpreter.handleAndDropResult
|
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.State
|
||||||
import org.jetbrains.kotlin.ir.interpreter.state.StateWithClosure
|
import org.jetbrains.kotlin.ir.interpreter.state.StateWithClosure
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||||
@@ -60,7 +60,7 @@ internal class CallStack {
|
|||||||
is IrTry -> {
|
is IrTry -> {
|
||||||
dropSubFrame()
|
dropSubFrame()
|
||||||
pushState(result)
|
pushState(result)
|
||||||
pushInstruction(SimpleInstruction(irReturn))
|
pushSimpleInstruction(irReturn)
|
||||||
frameOwner.finallyExpression?.handleAndDropResult(this)
|
frameOwner.finallyExpression?.handleAndDropResult(this)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -68,7 +68,7 @@ internal class CallStack {
|
|||||||
val tryBlock = currentFrame.dropInstructions()!!.element as IrTry// last instruction in `catch` block is `try`
|
val tryBlock = currentFrame.dropInstructions()!!.element as IrTry// last instruction in `catch` block is `try`
|
||||||
dropSubFrame()
|
dropSubFrame()
|
||||||
pushState(result)
|
pushState(result)
|
||||||
pushInstruction(SimpleInstruction(irReturn))
|
pushSimpleInstruction(irReturn)
|
||||||
tryBlock.finallyExpression?.handleAndDropResult(this)
|
tryBlock.finallyExpression?.handleAndDropResult(this)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -81,7 +81,7 @@ internal class CallStack {
|
|||||||
}
|
}
|
||||||
|
|
||||||
currentFrame.dropInstructions()
|
currentFrame.dropInstructions()
|
||||||
pushInstruction(SimpleInstruction(returnTarget))
|
pushSimpleInstruction(returnTarget)
|
||||||
if (returnTarget !is IrConstructor) pushState(result)
|
if (returnTarget !is IrConstructor) pushState(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,15 +91,15 @@ internal class CallStack {
|
|||||||
when (frameOwner) {
|
when (frameOwner) {
|
||||||
is IrTry -> {
|
is IrTry -> {
|
||||||
currentFrame.removeSubFrameWithoutDataPropagation()
|
currentFrame.removeSubFrameWithoutDataPropagation()
|
||||||
pushInstruction(CompoundInstruction(breakOrContinue))
|
pushCompoundInstruction(breakOrContinue)
|
||||||
newSubFrame(frameOwner) // will be deleted when interpret 'try'
|
newSubFrame(frameOwner) // will be deleted when interpret 'try'
|
||||||
pushInstruction(SimpleInstruction(frameOwner))
|
pushSimpleInstruction(frameOwner)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
is IrCatch -> {
|
is IrCatch -> {
|
||||||
val tryInstruction = currentFrame.dropInstructions()!! // last instruction in `catch` block is `try`
|
val tryInstruction = currentFrame.dropInstructions()!! // last instruction in `catch` block is `try`
|
||||||
currentFrame.removeSubFrameWithoutDataPropagation()
|
currentFrame.removeSubFrameWithoutDataPropagation()
|
||||||
pushInstruction(CompoundInstruction(breakOrContinue))
|
pushCompoundInstruction(breakOrContinue)
|
||||||
newSubFrame(tryInstruction.element!!) // will be deleted when interpret 'try'
|
newSubFrame(tryInstruction.element!!) // will be deleted when interpret 'try'
|
||||||
pushInstruction(tryInstruction)
|
pushInstruction(tryInstruction)
|
||||||
return
|
return
|
||||||
@@ -114,10 +114,10 @@ internal class CallStack {
|
|||||||
when (breakOrContinue) {
|
when (breakOrContinue) {
|
||||||
is IrBreak -> currentFrame.removeSubFrameWithoutDataPropagation() // drop loop
|
is IrBreak -> currentFrame.removeSubFrameWithoutDataPropagation() // drop loop
|
||||||
else -> if (breakOrContinue.loop is IrDoWhileLoop) {
|
else -> if (breakOrContinue.loop is IrDoWhileLoop) {
|
||||||
pushInstruction(SimpleInstruction(breakOrContinue.loop))
|
pushSimpleInstruction(breakOrContinue.loop)
|
||||||
pushInstruction(CompoundInstruction(breakOrContinue.loop.condition))
|
pushCompoundInstruction(breakOrContinue.loop.condition)
|
||||||
} else {
|
} else {
|
||||||
pushInstruction(CompoundInstruction(breakOrContinue.loop))
|
pushCompoundInstruction(breakOrContinue.loop)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -133,8 +133,8 @@ internal class CallStack {
|
|||||||
is IrTry -> {
|
is IrTry -> {
|
||||||
dropSubFrame() // drop all instructions that left
|
dropSubFrame() // drop all instructions that left
|
||||||
newSubFrame(frameOwner)
|
newSubFrame(frameOwner)
|
||||||
pushInstruction(SimpleInstruction(frameOwner)) // to evaluate finally at the end
|
pushSimpleInstruction(frameOwner) // to evaluate finally at the end
|
||||||
frameOwner.catches.reversed().forEach { pushInstruction(CompoundInstruction(it)) }
|
frameOwner.catches.reversed().forEach { pushCompoundInstruction(it) }
|
||||||
pushState(exception)
|
pushState(exception)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user