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
This commit is contained in:
Ivan Kylchik
2021-06-02 19:25:45 +03:00
committed by TeamCityServer
parent 3326cbd9c0
commit 06a8156376
3 changed files with 13 additions and 4 deletions
@@ -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
@@ -200,11 +200,17 @@ private fun unfoldBlock(block: IrBlock, callStack: CallStack) {
}
private fun unfoldStatements(statements: List<IrStatement>, 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))
}
}
@@ -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))
}
}