Remove all usages of descriptors from interpreter

This commit is contained in:
Ivan Kylchik
2020-06-18 21:16:14 +03:00
parent e4f88e83fe
commit 49124709b8
5 changed files with 24 additions and 16 deletions
@@ -52,8 +52,7 @@ class IrCompileTimeChecker(
private fun IrDeclaration.isMarkedWith(annotation: FqName): Boolean { private fun IrDeclaration.isMarkedWith(annotation: FqName): Boolean {
if (this is IrClass && this.isCompanion) return false if (this is IrClass && this.isCompanion) return false
// must check descriptor annotations too because ir builtins operators don't have annotation on ir element if (this.hasAnnotation(annotation)) return true
if (this.hasAnnotation(annotation) || this.descriptor.annotations.hasAnnotation(annotation)) return true
return (this.parent as? IrClass)?.isMarkedWith(annotation) ?: false return (this.parent as? IrClass)?.isMarkedWith(annotation) ?: false
} }
@@ -16,7 +16,6 @@ import org.jetbrains.kotlin.backend.common.interpreter.intrinsics.IntrinsicEvalu
import org.jetbrains.kotlin.backend.common.interpreter.stack.StackImpl import org.jetbrains.kotlin.backend.common.interpreter.stack.StackImpl
import org.jetbrains.kotlin.backend.common.interpreter.stack.Variable import org.jetbrains.kotlin.backend.common.interpreter.stack.Variable
import org.jetbrains.kotlin.backend.common.interpreter.state.* import org.jetbrains.kotlin.backend.common.interpreter.state.*
import org.jetbrains.kotlin.builtins.UnsignedTypes
import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
@@ -27,6 +26,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrConstructorCallImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrErrorExpressionImpl import org.jetbrains.kotlin.ir.expressions.impl.IrErrorExpressionImpl
import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.types.impl.originalKotlinType
import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -169,15 +169,14 @@ class IrInterpreter(irModule: IrModuleFragment, private val bodyMap: Map<IdSigna
} }
private suspend fun calculateBuiltIns(irFunction: IrFunction): ExecutionResult { private suspend fun calculateBuiltIns(irFunction: IrFunction): ExecutionResult {
val descriptor = irFunction.descriptor
val methodName = when (val property = (irFunction as? IrSimpleFunction)?.correspondingPropertySymbol) { val methodName = when (val property = (irFunction as? IrSimpleFunction)?.correspondingPropertySymbol) {
null -> descriptor.name.asString() null -> irFunction.name.asString()
else -> property.owner.name.asString() else -> property.owner.name.asString()
} }
val args = stack.getAll().map { it.state } val args = stack.getAll().map { it.state }
val receiverType = descriptor.dispatchReceiverParameter?.type val receiverType = irFunction.dispatchReceiverParameter?.type
val argsType = listOfNotNull(receiverType) + descriptor.valueParameters.map { it.original.type } val argsType = listOfNotNull(receiverType) + irFunction.valueParameters.map { it.type }
val argsValues = args.map { val argsValues = args.map {
when (it) { when (it) {
is Complex -> when (irFunction.fqNameWhenAvailable?.asString()) { is Complex -> when (irFunction.fqNameWhenAvailable?.asString()) {
@@ -190,7 +189,16 @@ class IrInterpreter(irModule: IrModuleFragment, private val bodyMap: Map<IdSigna
else -> TODO("unsupported type of argument for builtins calculations: ${it::class.java}") else -> TODO("unsupported type of argument for builtins calculations: ${it::class.java}")
} }
} }
val signature = CompileTimeFunction(methodName, argsType.map { it.toString() })
fun IrType.getOnlyName(): String {
return when {
this.originalKotlinType != null -> this.originalKotlinType.toString()
this is IrSimpleType -> (this.classifierOrFail.owner as IrDeclarationWithName).name.asString() + (if (this.hasQuestionMark) "?" else "")
else -> this.render()
}
}
val signature = CompileTimeFunction(methodName, argsType.map { it.getOnlyName() })
// TODO replace unary, binary, ternary functions with vararg // TODO replace unary, binary, ternary functions with vararg
val result = when (argsType.size) { val result = when (argsType.size) {
@@ -424,7 +432,7 @@ class IrInterpreter(irModule: IrModuleFragment, private val bodyMap: Map<IdSigna
} }
} }
return if (UnsignedTypes.isUnsignedType(expression.type.toKotlinType())) { return if (expression.type.isUnsigned()) {
val unsignedClass = expression.type.classOrNull!! val unsignedClass = expression.type.classOrNull!!
val constructor = unsignedClass.constructors.single().owner val constructor = unsignedClass.constructors.single().owner
val constructorCall = IrConstructorCallImpl.fromSymbolOwner(constructor.returnType, constructor.symbol) val constructorCall = IrConstructorCallImpl.fromSymbolOwner(constructor.returnType, constructor.symbol)
@@ -608,11 +616,11 @@ class IrInterpreter(irModule: IrModuleFragment, private val bodyMap: Map<IdSigna
val valueArguments = listOf( val valueArguments = listOf(
enumEntry.name.asString().toIrConst(irBuiltIns.stringType), enumEntries.indexOf(enumEntry).toIrConst(irBuiltIns.intType) enumEntry.name.asString().toIrConst(irBuiltIns.stringType), enumEntries.indexOf(enumEntry).toIrConst(irBuiltIns.intType)
) )
enumSuperCall.mapValueParameters { valueArguments[it.index] } valueArguments.forEachIndexed { index, irConst -> enumSuperCall.putValueArgument(index, irConst) }
} }
val executionResult = enumEntry.initializerExpression?.interpret()?.check { return it } val executionResult = enumEntry.initializerExpression?.interpret()?.check { return it }
enumSuperCall?.mapValueParameters { null } // restore to null enumSuperCall?.apply { (0 until this.valueArgumentsCount).forEach { putValueArgument(it, null) } } // restore to null
return executionResult ?: throw InterpreterException("Initializer at enum entry ${enumEntry.fqNameWhenAvailable} is null") return executionResult ?: throw InterpreterException("Initializer at enum entry ${enumEntry.fqNameWhenAvailable} is null")
} }
@@ -43,9 +43,9 @@ internal fun State.toIrExpression(expression: IrExpression): IrExpression {
else -> expression // TODO support for arrays else -> expression // TODO support for arrays
} }
is Complex -> { is Complex -> {
val stateType = this.irClass.defaultType.toKotlinType() val stateType = this.irClass.defaultType
when { when {
UnsignedTypes.isUnsignedType(stateType) -> (this.fields.single().state as Primitive<*>).value.toIrConst(type, start, end) stateType.isUnsigned() -> (this.fields.single().state as Primitive<*>).value.toIrConst(type, start, end)
else -> expression else -> expression
} }
} }
@@ -43,8 +43,8 @@ internal class Common private constructor(
fun getToStringFunction(): IrFunction { fun getToStringFunction(): IrFunction {
return irClass.declarations.filterIsInstance<IrFunction>() return irClass.declarations.filterIsInstance<IrFunction>()
.filter { it.descriptor.name.asString() == "toString" } .filter { it.name.asString() == "toString" }
.first { it.descriptor.valueParameters.isEmpty() } .first { it.valueParameters.isEmpty() }
.let { getOverridden(it as IrSimpleFunction, this) } .let { getOverridden(it as IrSimpleFunction, this) }
} }
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.classOrNull import org.jetbrains.kotlin.ir.types.classOrNull
import org.jetbrains.kotlin.ir.util.defaultType
import org.jetbrains.kotlin.ir.util.isFakeOverride import org.jetbrains.kotlin.ir.util.isFakeOverride
import org.jetbrains.kotlin.ir.util.overrides import org.jetbrains.kotlin.ir.util.overrides
@@ -57,6 +58,6 @@ internal class Primitive<T>(var value: T, val type: IrType) : State {
} }
override fun toString(): String { override fun toString(): String {
return "Primitive(value=$value, type=${irClass.descriptor.defaultType})" return "Primitive(value=$value, type=${irClass.defaultType})"
} }
} }