Add simple handler for StackOverflowError in ir interpreter

This commit is contained in:
Ivan Kylchik
2020-08-07 21:27:00 +03:00
committed by TeamCityServer
parent f3d7dc5f22
commit 6a483a8464
2 changed files with 10 additions and 1 deletions
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.name.Name
import java.lang.invoke.MethodHandle
private const val MAX_COMMANDS = 500_000
private const val MAX_STACK = 500
class IrInterpreter(private val irBuiltIns: IrBuiltIns, private val bodyMap: Map<IdSignature, IrBody> = emptyMap()) {
private val irExceptions = mutableListOf<IrClass>()
@@ -82,7 +83,7 @@ class IrInterpreter(private val irBuiltIns: IrBuiltIns, private val bodyMap: Map
}
else -> TODO("$returnLabel not supported as result of interpretation")
}
} catch (e: InterpreterException) {
} catch (e: Throwable) {
// TODO don't handle, throw to lowering
IrErrorExpressionImpl(expression.startOffset, expression.endOffset, expression.type, "\n" + e.message)
}
@@ -142,6 +143,7 @@ class IrInterpreter(private val irBuiltIns: IrBuiltIns, private val bodyMap: Map
// this method is used to get stack trace after exception
private fun interpretFunction(irFunction: IrSimpleFunction): ExecutionResult {
if (stack.getStackCount() >= MAX_STACK) StackOverflowError().throwAsUserException()
if (irFunction.fileOrNull != null) stack.setCurrentFrameName(irFunction)
if (irFunction.body is IrSyntheticBody) return handleIntrinsicMethods(irFunction)
@@ -22,6 +22,7 @@ internal interface Stack {
fun setCurrentFrameName(irFunction: IrFunction)
fun getStackTrace(): List<String>
fun getStackCount(): Int
fun clean()
fun addVar(variable: Variable)
@@ -39,6 +40,7 @@ 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 fun getCurrentFrame() = frameList.last()
private var stackCount = 0
override fun newFrame(asSubFrame: Boolean, initPool: List<Variable>, block: () -> ExecutionResult): ExecutionResult {
val typeArgumentsPool = initPool.filter { it.symbol is IrTypeParameterSymbol }
@@ -47,8 +49,10 @@ internal class StackImpl : Stack {
if (asSubFrame) getCurrentFrame().addSubFrame(newFrame) else frameList.add(FrameContainer(newFrame))
return try {
stackCount++
block()
} finally {
stackCount--
if (asSubFrame) getCurrentFrame().removeSubFrame() else removeLastFrame()
}
}
@@ -71,7 +75,10 @@ internal class StackImpl : Stack {
return frameList.mapNotNull { it.frameEntryPoint }
}
override fun getStackCount(): Int = stackCount
override fun clean() {
stackCount = 0
frameList.clear()
frameList.add(FrameContainer())
}