Add simple handler for StackOverflowError in ir interpreter
This commit is contained in:
committed by
TeamCityServer
parent
f3d7dc5f22
commit
6a483a8464
@@ -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())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user