Get rid of dynamic cast interpretation

This commit is contained in:
Ivan Kylchik
2020-06-10 19:22:57 +03:00
parent 3ccf542b38
commit 792ae8d272
4 changed files with 34 additions and 9 deletions
@@ -355,6 +355,20 @@ class IrInterpreter(irModule: IrModuleFragment) {
data.pushReturnValue(Lambda(irLambdaFunction.symbol.owner, irLambdaFunction.type.classOrNull!!.owner))
return Code.NEXT
}
val inlineFunOwner = (block as? IrReturnableBlock)?.inlineFunctionSymbol?.owner
if (inlineFunOwner?.hasAnnotation(evaluateIntrinsicAnnotation) == true) {
val rawArgs = block.statements.filterIsInstance<IrVariable>().zip(inlineFunOwner.valueParameters)
val args = mutableListOf<Variable>()
for ((variable, valueParameter) in rawArgs) {
val tempFrame = data.copy().apply { variable.initializer!!.interpret(this).also { if (it != Code.NEXT) return it } }
// must set variable descriptor here because temp variables inside ir returnable block have different from methods args names
args += Variable(valueParameter.descriptor, tempFrame.popReturnValue())
}
val newFrame = data.copy().apply { addAll(args) }
return Wrapper.getStaticMethod(inlineFunOwner).invokeMethod(inlineFunOwner, newFrame).apply { data.pushReturnValue(newFrame) }
}
return interpretStatements(block.statements, data)
}
@@ -466,9 +480,7 @@ class IrInterpreter(irModule: IrModuleFragment) {
private fun interpretTypeOperatorCall(expression: IrTypeOperatorCall, data: Frame): Code {
return when (expression.operator) {
IrTypeOperator.IMPLICIT_COERCION_TO_UNIT, IrTypeOperator.IMPLICIT_DYNAMIC_CAST -> {
expression.argument.interpret(data)
}
IrTypeOperator.IMPLICIT_COERCION_TO_UNIT -> expression.argument.interpret(data)
IrTypeOperator.CAST, IrTypeOperator.IMPLICIT_CAST -> {
val code = expression.argument.interpret(data)
if (!data.peekReturnValue().irClass.defaultType.isSubtypeOf(expression.type, irBuiltIns)) {
@@ -106,7 +106,8 @@ fun State.toIrExpression(expression: IrExpression): IrExpression {
fun Any?.toState(irType: IrType): State {
return when (this) {
is State -> this
is Boolean, is Char, is Byte, is Short, is Int, is Long, is String, is Float, is Double -> Primitive(this, irType)
is Boolean, is Char, is Byte, is Short, is Int, is Long, is String, is Float, is Double, is Array<*>, is ByteArray,
is CharArray, is ShortArray, is IntArray, is LongArray, is FloatArray, is DoubleArray, is BooleanArray -> Primitive(this, irType)
null -> Primitive(this, irType)
else -> Wrapper(this, irType.classOrNull!!.owner)
}
@@ -145,9 +146,11 @@ fun IrAnnotationContainer.getAnnotation(annotation: FqName): IrConstructorCall {
?: ((this as IrFunction).parent as IrClass).annotations.first { it.symbol.descriptor.containingDeclaration.fqNameSafe == annotation }
}
const val defaultIntrinsicLocation = "org.jetbrains.kotlin.backend.common.interpreter.intrinsic.InterpreterIntrinsicsKt"
fun IrAnnotationContainer.getEvaluateIntrinsicValue(): String? {
if (!this.hasAnnotation(evaluateIntrinsicAnnotation)) return null
return (this.getAnnotation(evaluateIntrinsicAnnotation).getValueArgument(0) as IrConst<*>).value.toString()
val value = (this.getAnnotation(evaluateIntrinsicAnnotation).getValueArgument(0) as IrConst<*>).value.toString()
return if (value.isEmpty()) defaultIntrinsicLocation else value
}
fun getPrimitiveClass(fqName: String, asObject: Boolean = false): Class<*>? {
@@ -0,0 +1,12 @@
/*
* Copyright 2010-2020 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.
*/
@file:JvmName("InterpreterIntrinsicsKt")
package org.jetbrains.kotlin.backend.common.interpreter.intrinsic
public fun emptyArray(): Array<Any?> = kotlin.emptyArray()
public fun arrayOf(vararg elements: Any?): Array<Any?> = elements as Array<Any?>
@@ -16,7 +16,6 @@ import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrProperty
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
import org.jetbrains.kotlin.ir.expressions.IrConst
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.defaultType
@@ -166,11 +165,10 @@ class Wrapper(val value: Any, override var irClass: IrClass) : Complex(irClass,
}
fun getStaticMethod(irFunction: IrFunction): MethodHandle {
val annotation = irFunction.getAnnotation(evaluateIntrinsicAnnotation)
val jvmFileName = Class.forName((annotation.getValueArgument(0) as IrConst<*>).value.toString())
val jvmClassName = Class.forName(irFunction.getEvaluateIntrinsicValue()!!)
val methodType = irFunction.getMethodType()
return MethodHandles.lookup().findStatic(jvmFileName, irFunction.name.asString(), methodType)
return MethodHandles.lookup().findStatic(jvmClassName, irFunction.name.asString(), methodType)
}
private fun IrFunction.getMethodType(): MethodType {