From 4345294ac1087cf6a70a810434343a03df89c765 Mon Sep 17 00:00:00 2001 From: Ivan Kylchik Date: Thu, 30 Jan 2020 17:35:59 +0300 Subject: [PATCH] Add all methods from Any class in ir builtins map --- .../common/interpreter/IrInterpreter.kt | 64 ++++++++----------- .../builtins/IrBuiltInsMapGenerated.kt | 9 ++- generators/evaluate/GenerateBuiltInsMap.kt | 13 ++-- 3 files changed, 42 insertions(+), 44 deletions(-) diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/interpreter/IrInterpreter.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/interpreter/IrInterpreter.kt index 01eedebc9aa..1758d9b52b1 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/interpreter/IrInterpreter.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/interpreter/IrInterpreter.kt @@ -165,7 +165,8 @@ class IrInterpreter(irModule: IrModuleFragment) { private fun calculateOverridden(owner: IrFunctionImpl, data: Frame): Code { val variableDescriptor = owner.symbol.getReceiver()!! - val superQualifier = (data.getVariableState(variableDescriptor) as Complex).superType!! + val superQualifier = (data.getVariableState(variableDescriptor) as? Complex)?.superType + ?: return calculateBuiltIns(owner.overriddenSymbols.first().owner, data) val overridden = owner.overriddenSymbols.first { it.getReceiver()?.equalTo(superQualifier.getReceiver()) == true } val newStates = InterpreterFrame(mutableListOf(Variable(overridden.getReceiver()!!, superQualifier))) @@ -186,46 +187,33 @@ class IrInterpreter(irModule: IrModuleFragment) { val methodName = descriptor.name.asString() val args = data.getAll().map { it.state } - val result: Any? - if (irFunction.parent.fqNameForIrSerialization.toString() == "kotlin.Any" || args.any { it !is Primitive<*> }) { - // if ir function is declaration in Any class OR it is ir builtin operator for non primitive types - val receiver = (args[0] as Complex).instance - result = when (methodName) { - "equals", "EQEQ", "EQEQEQ" -> (args[1] as Complex).instance === receiver - "hashCode" -> System.identityHashCode(receiver) - "toString" -> receiver?.irClass?.name?.asString() + "@" + System.identityHashCode(receiver).toString(16).padStart(8) - else -> throw IllegalStateException("Method $methodName can not be interpreted") - } - } else { - val receiverType = descriptor.dispatchReceiverParameter?.type ?: descriptor.extensionReceiverParameter?.type - val argsType = listOfNotNull(receiverType) + descriptor.valueParameters.map { it.original.type } - val argsValues = args - .map { it as? Primitive<*> ?: throw IllegalArgumentException("Builtin functions accept only const args") } - .map { it.value } - val signature = CompileTimeFunction(methodName, argsType.map { it.toString() }) + val receiverType = descriptor.dispatchReceiverParameter?.type ?: descriptor.extensionReceiverParameter?.type + val argsType = listOfNotNull(receiverType) + descriptor.valueParameters.map { it.original.type } + val argsValues = args.map { (it as? Complex)?.instance ?: (it as Primitive<*>).value } + val signature = CompileTimeFunction(methodName, argsType.map { it.toString() }) - result = when (argsType.size) { - 1 -> { - val function = unaryFunctions[signature] - ?: throw NoSuchMethodException("For given function $signature there is no entry in unary map") - function.invoke(argsValues.first()) - } - 2 -> { - val function = binaryFunctions[signature] - ?: throw NoSuchMethodException("For given function $signature there is no entry in binary map") - when (methodName) { - "rangeTo" -> return calculateRangeTo(irFunction.returnType, data) - else -> function.invoke(argsValues[0], argsValues[1]) - } - } - 3 -> { - val function = ternaryFunctions[signature] - ?: throw NoSuchMethodException("For given function $signature there is no entry in ternary map") - function.invoke(argsValues[0], argsValues[1], argsValues[2]) - } - else -> throw UnsupportedOperationException("Unsupported number of arguments") + val result = when (argsType.size) { + 1 -> { + val function = unaryFunctions[signature] + ?: throw NoSuchMethodException("For given function $signature there is no entry in unary map") + function.invoke(argsValues.first()) } + 2 -> { + val function = binaryFunctions[signature] + ?: throw NoSuchMethodException("For given function $signature there is no entry in binary map") + when (methodName) { + "rangeTo" -> return calculateRangeTo(irFunction.returnType, data) + else -> function.invoke(argsValues[0], argsValues[1]) + } + } + 3 -> { + val function = ternaryFunctions[signature] + ?: throw NoSuchMethodException("For given function $signature there is no entry in ternary map") + function.invoke(argsValues[0], argsValues[1], argsValues[2]) + } + else -> throw UnsupportedOperationException("Unsupported number of arguments") } + data.pushReturnValue(result.toState(result.getType(irFunction.returnType))) return Code.NEXT } diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/interpreter/builtins/IrBuiltInsMapGenerated.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/interpreter/builtins/IrBuiltInsMapGenerated.kt index b8bc6ef8192..b8b703cfc2b 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/interpreter/builtins/IrBuiltInsMapGenerated.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/interpreter/builtins/IrBuiltInsMapGenerated.kt @@ -14,10 +14,10 @@ * limitations under the License. */ -@file:Suppress("DEPRECATION_ERROR") - package org.jetbrains.kotlin.backend.common.interpreter.builtins +import org.jetbrains.kotlin.backend.common.interpreter.stack.State + /** This file is generated by org.jetbrains.kotlin.backend.common.interpreter.builtins.GenerateBuiltInsMap.generateMap(). DO NOT MODIFY MANUALLY */ val unaryFunctions = mapOf>( @@ -113,6 +113,10 @@ val unaryFunctions = mapOf>( unaryOperation("iterator", "LongArray") { a -> a.iterator() }, unaryOperation("size", "DoubleArray") { a -> a.size }, unaryOperation("iterator", "DoubleArray") { a -> a.iterator() }, + unaryOperation("hashCode", "Any") { a -> a.hashCode() }, + unaryOperation("toString", "Any") { a -> + if (a is State) "${a.irClass.name}@" + System.identityHashCode(a).toString(16).padStart(8) else a.toString() + }, unaryOperation("CHECK_NOT_NULL", "T0?") { a -> a!! } ) @@ -390,6 +394,7 @@ val binaryFunctions = mapOf>( binaryOperation("get", "FloatArray", "Int") { a, b -> a.get(b) }, binaryOperation("get", "LongArray", "Int") { a, b -> a.get(b) }, binaryOperation("get", "DoubleArray", "Int") { a, b -> a.get(b) }, + binaryOperation("equals", "Any", "Any?") { a, b -> a.equals(b) }, binaryOperation("less", "Char", "Char") { a, b -> a < b }, binaryOperation("less", "Byte", "Byte") { a, b -> a < b }, binaryOperation("less", "Short", "Short") { a, b -> a < b }, diff --git a/generators/evaluate/GenerateBuiltInsMap.kt b/generators/evaluate/GenerateBuiltInsMap.kt index 95c83ff089c..463ff924017 100644 --- a/generators/evaluate/GenerateBuiltInsMap.kt +++ b/generators/evaluate/GenerateBuiltInsMap.kt @@ -39,10 +39,10 @@ fun generateMap(): String { val sb = StringBuilder() val p = Printer(sb) p.println(File("license/COPYRIGHT.txt").readText()) - p.println("@file:Suppress(\"DEPRECATION_ERROR\")") - p.println() p.println("package org.jetbrains.kotlin.backend.common.interpreter.builtins") p.println() + p.println("import org.jetbrains.kotlin.backend.common.interpreter.stack.State") + p.println() p.println("/** This file is generated by org.jetbrains.kotlin.backend.common.interpreter.builtins.GenerateBuiltInsMap.generateMap(). DO NOT MODIFY MANUALLY */") p.println() @@ -58,10 +58,11 @@ fun generateMap(): String { val arrays = listOf(builtIns.array) + PrimitiveType.values().map { builtIns.getPrimitiveArrayClassDescriptor(it) } - for (descriptor in allPrimitiveTypes + builtIns.string + arrays) { + for (descriptor in allPrimitiveTypes + builtIns.string + arrays + builtIns.any) { val typeParameters = descriptor.typeConstructor.parameters.map { it.name.asString() } val typeParametersAsAny = if (typeParameters.isNotEmpty()) typeParameters.joinToString(prefix = "<", postfix = ">") { "Any?" } else "" val descriptorType = descriptor.defaultType + @Suppress("UNCHECKED_CAST") val functions = descriptor.getMemberScope(listOf()).getContributedDescriptors() .filter { @@ -117,7 +118,11 @@ fun generateMap(): String { val unaryBody = unaryOperationsMap.entries.joinToString(",\n", postfix = ",\n") { (function, parameters) -> val methodName = "${function.name}" val parentheses = if (function is FunctionDescriptor) "()" else "" - " unaryOperation${parameters.first}(\"$methodName\", ${parameters.second}) { a -> a.$methodName$parentheses }" + val body = if (methodName == "toString" && parameters.first == "") + "\n\t\tif (a is State) \"\${a.irClass.name}@\" + System.identityHashCode(a).toString(16).padStart(8) else a.toString()\n\t" + else + "a.$methodName$parentheses " + " unaryOperation${parameters.first}(\"$methodName\", ${parameters.second}) { a -> $body}" } + " unaryOperation(\"${irNullCheck.name}\", \"${irNullCheck.valueParameters.first().type}\") { a -> a!! }" p.println(unaryBody) p.println(")")