Add new intrinsic handler for sourceLocation function

This commit is contained in:
Ivan Kylchik
2020-11-08 02:53:54 +03:00
committed by TeamCityServer
parent 7fe776fe10
commit ac7a1c7762
4 changed files with 27 additions and 1 deletions
@@ -268,6 +268,7 @@ class IrInterpreter(val irBuiltIns: IrBuiltIns, private val bodyMap: Map<IdSigna
}
private fun interpretCall(expression: IrCall): ExecutionResult {
stack.fixCallEntryPoint(expression)
val valueArguments = mutableListOf<Variable>()
// dispatch receiver processing
val rawDispatchReceiver = expression.dispatchReceiver
@@ -309,7 +310,6 @@ class IrInterpreter(val irBuiltIns: IrBuiltIns, private val bodyMap: Map<IdSigna
generateSequence(dispatchReceiver.outerClass) { (it.state as? Complex)?.outerClass }.forEach { valueArguments.add(it) }
}
stack.fixCallEntryPoint(expression)
return stack.newFrame(irFunction, initPool = valueArguments) {
// inline only methods are not presented in lookup table, so must be interpreted instead of execution
val isInlineOnly = irFunction.hasAnnotation(FqName("kotlin.internal.InlineOnly"))
@@ -22,6 +22,7 @@ internal class IntrinsicEvaluator {
EnumHashCode.equalTo(irFunction) -> EnumHashCode.evaluate(irFunction, stack, interpret)
JsPrimitives.equalTo(irFunction) -> JsPrimitives.evaluate(irFunction, stack, interpret)
ArrayConstructor.equalTo(irFunction) -> ArrayConstructor.evaluate(irFunction, stack, interpret)
SourceLocation.equalTo(irFunction) -> SourceLocation.evaluate(irFunction, stack, interpret)
else -> throw InterpreterMethodNotFoundError("Method ${irFunction.name} hasn't implemented")
}
}
@@ -193,4 +193,16 @@ internal object ArrayConstructor : IntrinsicBase() {
stack.pushReturnValue(arrayValue.toPrimitiveStateArray(irFunction.parentAsClass.defaultType))
return Next
}
}
internal object SourceLocation : IntrinsicBase() {
override fun equalTo(irFunction: IrFunction): Boolean {
val fqName = irFunction.fqNameWhenAvailable.toString()
return fqName == "kotlin.experimental.sourceLocation" || fqName == "kotlin.experimental.SourceLocationKt.sourceLocation"
}
override fun evaluate(irFunction: IrFunction, stack: Stack, interpret: IrElement.() -> ExecutionResult): ExecutionResult {
stack.pushReturnValue(stack.getCurrentStackInfo().toState(irFunction.returnType))
return Next
}
}
@@ -25,6 +25,7 @@ internal interface Stack {
fun fixCallEntryPoint(irExpression: IrExpression)
fun getStackTrace(): List<String>
fun getCurrentStackInfo(): String
fun getStackCount(): Int
fun clean(rootFile: IrFile?)
@@ -97,6 +98,13 @@ internal class StackImpl : Stack {
return frameList.map { it.toString() }
}
override fun getCurrentStackInfo(): String {
val frame = getCurrentFrame()
frame.irFile ?: return "Not defined"
val lineNum = if (frame.lineNumber != -1) ":${frame.lineNumber}" else ""
return "${frame.irFile.name}$lineNum"
}
override fun getStackCount(): Int = stackCount
override fun clean(rootFile: IrFile?) {
@@ -143,6 +151,11 @@ internal class StackImpl : Stack {
}
private class FrameContainer(val irFile: IrFile? = null, private val entryPoint: IrFunction? = null, current: Frame = InterpreterFrame()) {
/*var lineNumber: Int
get() = getTopFrame().lineOfCall
set(value) {
getTopFrame().lineOfCall = value
}*/
var lineNumber: Int = -1
private val innerStack = mutableListOf(current)
private fun getTopFrame() = innerStack.first()