Get rid of dynamic cast interpretation
This commit is contained in:
+15
-3
@@ -355,6 +355,20 @@ class IrInterpreter(irModule: IrModuleFragment) {
|
|||||||
data.pushReturnValue(Lambda(irLambdaFunction.symbol.owner, irLambdaFunction.type.classOrNull!!.owner))
|
data.pushReturnValue(Lambda(irLambdaFunction.symbol.owner, irLambdaFunction.type.classOrNull!!.owner))
|
||||||
return Code.NEXT
|
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)
|
return interpretStatements(block.statements, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -466,9 +480,7 @@ class IrInterpreter(irModule: IrModuleFragment) {
|
|||||||
|
|
||||||
private fun interpretTypeOperatorCall(expression: IrTypeOperatorCall, data: Frame): Code {
|
private fun interpretTypeOperatorCall(expression: IrTypeOperatorCall, data: Frame): Code {
|
||||||
return when (expression.operator) {
|
return when (expression.operator) {
|
||||||
IrTypeOperator.IMPLICIT_COERCION_TO_UNIT, IrTypeOperator.IMPLICIT_DYNAMIC_CAST -> {
|
IrTypeOperator.IMPLICIT_COERCION_TO_UNIT -> expression.argument.interpret(data)
|
||||||
expression.argument.interpret(data)
|
|
||||||
}
|
|
||||||
IrTypeOperator.CAST, IrTypeOperator.IMPLICIT_CAST -> {
|
IrTypeOperator.CAST, IrTypeOperator.IMPLICIT_CAST -> {
|
||||||
val code = expression.argument.interpret(data)
|
val code = expression.argument.interpret(data)
|
||||||
if (!data.peekReturnValue().irClass.defaultType.isSubtypeOf(expression.type, irBuiltIns)) {
|
if (!data.peekReturnValue().irClass.defaultType.isSubtypeOf(expression.type, irBuiltIns)) {
|
||||||
|
|||||||
+5
-2
@@ -106,7 +106,8 @@ fun State.toIrExpression(expression: IrExpression): IrExpression {
|
|||||||
fun Any?.toState(irType: IrType): State {
|
fun Any?.toState(irType: IrType): State {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
is State -> 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)
|
null -> Primitive(this, irType)
|
||||||
else -> Wrapper(this, irType.classOrNull!!.owner)
|
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 }
|
?: ((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? {
|
fun IrAnnotationContainer.getEvaluateIntrinsicValue(): String? {
|
||||||
if (!this.hasAnnotation(evaluateIntrinsicAnnotation)) return null
|
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<*>? {
|
fun getPrimitiveClass(fqName: String, asObject: Boolean = false): Class<*>? {
|
||||||
|
|||||||
+12
@@ -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?>
|
||||||
+2
-4
@@ -16,7 +16,6 @@ import org.jetbrains.kotlin.ir.declarations.IrClass
|
|||||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrProperty
|
import org.jetbrains.kotlin.ir.declarations.IrProperty
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
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.symbols.IrFunctionSymbol
|
||||||
import org.jetbrains.kotlin.ir.types.*
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
import org.jetbrains.kotlin.ir.util.defaultType
|
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 {
|
fun getStaticMethod(irFunction: IrFunction): MethodHandle {
|
||||||
val annotation = irFunction.getAnnotation(evaluateIntrinsicAnnotation)
|
val jvmClassName = Class.forName(irFunction.getEvaluateIntrinsicValue()!!)
|
||||||
val jvmFileName = Class.forName((annotation.getValueArgument(0) as IrConst<*>).value.toString())
|
|
||||||
|
|
||||||
val methodType = irFunction.getMethodType()
|
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 {
|
private fun IrFunction.getMethodType(): MethodType {
|
||||||
|
|||||||
Reference in New Issue
Block a user