From a27a07ce81e767cd21916636ae916429d64809c4 Mon Sep 17 00:00:00 2001 From: Ivan Kylchik Date: Thu, 11 Jun 2020 00:00:59 +0300 Subject: [PATCH] Create generator for map with builtin operations --- .../interpreter/builtins/CompileTimeUtils.kt | 22 + .../builtins/IrBuiltInsMapGenerated.kt | 383 ++++++++++++++++++ generators/build.gradle.kts | 2 + generators/evaluate/GenerateBuiltInsMap.kt | 154 +++++++ 4 files changed, 561 insertions(+) create mode 100644 compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/interpreter/builtins/CompileTimeUtils.kt create mode 100644 compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/interpreter/builtins/IrBuiltInsMapGenerated.kt create mode 100644 generators/evaluate/GenerateBuiltInsMap.kt diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/interpreter/builtins/CompileTimeUtils.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/interpreter/builtins/CompileTimeUtils.kt new file mode 100644 index 00000000000..f417dd55e2a --- /dev/null +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/interpreter/builtins/CompileTimeUtils.kt @@ -0,0 +1,22 @@ +/* + * Copyright 2010-2019 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. + */ + +package org.jetbrains.kotlin.backend.common.interpreter.builtins + +data class CompileTimeFunction(val methodName: String, val args: List) + +@Suppress("UNCHECKED_CAST") +fun unaryOperation( + methodName: String, receiverType: String, function: (T) -> Any +): Pair> { + return CompileTimeFunction(methodName, listOf(receiverType)) to function as Function1 +} + +@Suppress("UNCHECKED_CAST") +fun binaryOperation( + methodName: String, receiverType: String, parameterType: String, function: (T, E) -> Any +): Pair> { + return CompileTimeFunction(methodName, listOfNotNull(receiverType, parameterType)) to function as Function2 +} 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 new file mode 100644 index 00000000000..01901315160 --- /dev/null +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/interpreter/builtins/IrBuiltInsMapGenerated.kt @@ -0,0 +1,383 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@file:Suppress("DEPRECATION_ERROR") + +package org.jetbrains.kotlin.backend.common.interpreter.builtins + +/** This file is generated by org.jetbrains.kotlin.backend.common.interpreter.builtins.GenerateBuiltInsMap.generateMap(). DO NOT MODIFY MANUALLY */ + +val unaryFunctions = mapOf>( + unaryOperation("not", "Boolean") { a -> a.not() }, + unaryOperation("toString", "Boolean") { a -> a.toString() }, + unaryOperation("toByte", "Byte") { a -> a.toByte() }, + unaryOperation("toChar", "Byte") { a -> a.toChar() }, + unaryOperation("toDouble", "Byte") { a -> a.toDouble() }, + unaryOperation("toFloat", "Byte") { a -> a.toFloat() }, + unaryOperation("toInt", "Byte") { a -> a.toInt() }, + unaryOperation("toLong", "Byte") { a -> a.toLong() }, + unaryOperation("toShort", "Byte") { a -> a.toShort() }, + unaryOperation("toString", "Byte") { a -> a.toString() }, + unaryOperation("unaryMinus", "Byte") { a -> a.unaryMinus() }, + unaryOperation("unaryPlus", "Byte") { a -> a.unaryPlus() }, + unaryOperation("toByte", "Char") { a -> a.toByte() }, + unaryOperation("toChar", "Char") { a -> a.toChar() }, + unaryOperation("toDouble", "Char") { a -> a.toDouble() }, + unaryOperation("toFloat", "Char") { a -> a.toFloat() }, + unaryOperation("toInt", "Char") { a -> a.toInt() }, + unaryOperation("toLong", "Char") { a -> a.toLong() }, + unaryOperation("toShort", "Char") { a -> a.toShort() }, + unaryOperation("toString", "Char") { a -> a.toString() }, + unaryOperation("toByte", "Double") { a -> a.toByte() }, + unaryOperation("toChar", "Double") { a -> a.toChar() }, + unaryOperation("toDouble", "Double") { a -> a.toDouble() }, + unaryOperation("toFloat", "Double") { a -> a.toFloat() }, + unaryOperation("toInt", "Double") { a -> a.toInt() }, + unaryOperation("toLong", "Double") { a -> a.toLong() }, + unaryOperation("toShort", "Double") { a -> a.toShort() }, + unaryOperation("toString", "Double") { a -> a.toString() }, + unaryOperation("unaryMinus", "Double") { a -> a.unaryMinus() }, + unaryOperation("unaryPlus", "Double") { a -> a.unaryPlus() }, + unaryOperation("toByte", "Float") { a -> a.toByte() }, + unaryOperation("toChar", "Float") { a -> a.toChar() }, + unaryOperation("toDouble", "Float") { a -> a.toDouble() }, + unaryOperation("toFloat", "Float") { a -> a.toFloat() }, + unaryOperation("toInt", "Float") { a -> a.toInt() }, + unaryOperation("toLong", "Float") { a -> a.toLong() }, + unaryOperation("toShort", "Float") { a -> a.toShort() }, + unaryOperation("toString", "Float") { a -> a.toString() }, + unaryOperation("unaryMinus", "Float") { a -> a.unaryMinus() }, + unaryOperation("unaryPlus", "Float") { a -> a.unaryPlus() }, + unaryOperation("inv", "Int") { a -> a.inv() }, + unaryOperation("toByte", "Int") { a -> a.toByte() }, + unaryOperation("toChar", "Int") { a -> a.toChar() }, + unaryOperation("toDouble", "Int") { a -> a.toDouble() }, + unaryOperation("toFloat", "Int") { a -> a.toFloat() }, + unaryOperation("toInt", "Int") { a -> a.toInt() }, + unaryOperation("toLong", "Int") { a -> a.toLong() }, + unaryOperation("toShort", "Int") { a -> a.toShort() }, + unaryOperation("toString", "Int") { a -> a.toString() }, + unaryOperation("unaryMinus", "Int") { a -> a.unaryMinus() }, + unaryOperation("unaryPlus", "Int") { a -> a.unaryPlus() }, + unaryOperation("inv", "Long") { a -> a.inv() }, + unaryOperation("toByte", "Long") { a -> a.toByte() }, + unaryOperation("toChar", "Long") { a -> a.toChar() }, + unaryOperation("toDouble", "Long") { a -> a.toDouble() }, + unaryOperation("toFloat", "Long") { a -> a.toFloat() }, + unaryOperation("toInt", "Long") { a -> a.toInt() }, + unaryOperation("toLong", "Long") { a -> a.toLong() }, + unaryOperation("toShort", "Long") { a -> a.toShort() }, + unaryOperation("toString", "Long") { a -> a.toString() }, + unaryOperation("unaryMinus", "Long") { a -> a.unaryMinus() }, + unaryOperation("unaryPlus", "Long") { a -> a.unaryPlus() }, + unaryOperation("toByte", "Short") { a -> a.toByte() }, + unaryOperation("toChar", "Short") { a -> a.toChar() }, + unaryOperation("toDouble", "Short") { a -> a.toDouble() }, + unaryOperation("toFloat", "Short") { a -> a.toFloat() }, + unaryOperation("toInt", "Short") { a -> a.toInt() }, + unaryOperation("toLong", "Short") { a -> a.toLong() }, + unaryOperation("toShort", "Short") { a -> a.toShort() }, + unaryOperation("toString", "Short") { a -> a.toString() }, + unaryOperation("unaryMinus", "Short") { a -> a.unaryMinus() }, + unaryOperation("unaryPlus", "Short") { a -> a.unaryPlus() }, + unaryOperation("length", "String") { a -> a.length }, + unaryOperation("toString", "String") { a -> a.toString() } +) + +val binaryFunctions = mapOf>( + binaryOperation("and", "Boolean", "Boolean") { a, b -> a.and(b) }, + binaryOperation("compareTo", "Boolean", "Boolean") { a, b -> a.compareTo(b) }, + binaryOperation("equals", "Boolean", "Any") { a, b -> a.equals(b) }, + binaryOperation("or", "Boolean", "Boolean") { a, b -> a.or(b) }, + binaryOperation("xor", "Boolean", "Boolean") { a, b -> a.xor(b) }, + binaryOperation("compareTo", "Byte", "Byte") { a, b -> a.compareTo(b) }, + binaryOperation("compareTo", "Byte", "Double") { a, b -> a.compareTo(b) }, + binaryOperation("compareTo", "Byte", "Float") { a, b -> a.compareTo(b) }, + binaryOperation("compareTo", "Byte", "Int") { a, b -> a.compareTo(b) }, + binaryOperation("compareTo", "Byte", "Long") { a, b -> a.compareTo(b) }, + binaryOperation("compareTo", "Byte", "Short") { a, b -> a.compareTo(b) }, + binaryOperation("div", "Byte", "Byte") { a, b -> a.div(b) }, + binaryOperation("div", "Byte", "Double") { a, b -> a.div(b) }, + binaryOperation("div", "Byte", "Float") { a, b -> a.div(b) }, + binaryOperation("div", "Byte", "Int") { a, b -> a.div(b) }, + binaryOperation("div", "Byte", "Long") { a, b -> a.div(b) }, + binaryOperation("div", "Byte", "Short") { a, b -> a.div(b) }, + binaryOperation("equals", "Byte", "Any") { a, b -> a.equals(b) }, + binaryOperation("minus", "Byte", "Byte") { a, b -> a.minus(b) }, + binaryOperation("minus", "Byte", "Double") { a, b -> a.minus(b) }, + binaryOperation("minus", "Byte", "Float") { a, b -> a.minus(b) }, + binaryOperation("minus", "Byte", "Int") { a, b -> a.minus(b) }, + binaryOperation("minus", "Byte", "Long") { a, b -> a.minus(b) }, + binaryOperation("minus", "Byte", "Short") { a, b -> a.minus(b) }, + binaryOperation("plus", "Byte", "Byte") { a, b -> a.plus(b) }, + binaryOperation("plus", "Byte", "Double") { a, b -> a.plus(b) }, + binaryOperation("plus", "Byte", "Float") { a, b -> a.plus(b) }, + binaryOperation("plus", "Byte", "Int") { a, b -> a.plus(b) }, + binaryOperation("plus", "Byte", "Long") { a, b -> a.plus(b) }, + binaryOperation("plus", "Byte", "Short") { a, b -> a.plus(b) }, + binaryOperation("rem", "Byte", "Byte") { a, b -> a.rem(b) }, + binaryOperation("rem", "Byte", "Double") { a, b -> a.rem(b) }, + binaryOperation("rem", "Byte", "Float") { a, b -> a.rem(b) }, + binaryOperation("rem", "Byte", "Int") { a, b -> a.rem(b) }, + binaryOperation("rem", "Byte", "Long") { a, b -> a.rem(b) }, + binaryOperation("rem", "Byte", "Short") { a, b -> a.rem(b) }, + binaryOperation("times", "Byte", "Byte") { a, b -> a.times(b) }, + binaryOperation("times", "Byte", "Double") { a, b -> a.times(b) }, + binaryOperation("times", "Byte", "Float") { a, b -> a.times(b) }, + binaryOperation("times", "Byte", "Int") { a, b -> a.times(b) }, + binaryOperation("times", "Byte", "Long") { a, b -> a.times(b) }, + binaryOperation("times", "Byte", "Short") { a, b -> a.times(b) }, + binaryOperation("compareTo", "Char", "Char") { a, b -> a.compareTo(b) }, + binaryOperation("equals", "Char", "Any") { a, b -> a.equals(b) }, + binaryOperation("minus", "Char", "Char") { a, b -> a.minus(b) }, + binaryOperation("minus", "Char", "Int") { a, b -> a.minus(b) }, + binaryOperation("plus", "Char", "Int") { a, b -> a.plus(b) }, + binaryOperation("compareTo", "Double", "Byte") { a, b -> a.compareTo(b) }, + binaryOperation("compareTo", "Double", "Double") { a, b -> a.compareTo(b) }, + binaryOperation("compareTo", "Double", "Float") { a, b -> a.compareTo(b) }, + binaryOperation("compareTo", "Double", "Int") { a, b -> a.compareTo(b) }, + binaryOperation("compareTo", "Double", "Long") { a, b -> a.compareTo(b) }, + binaryOperation("compareTo", "Double", "Short") { a, b -> a.compareTo(b) }, + binaryOperation("div", "Double", "Byte") { a, b -> a.div(b) }, + binaryOperation("div", "Double", "Double") { a, b -> a.div(b) }, + binaryOperation("div", "Double", "Float") { a, b -> a.div(b) }, + binaryOperation("div", "Double", "Int") { a, b -> a.div(b) }, + binaryOperation("div", "Double", "Long") { a, b -> a.div(b) }, + binaryOperation("div", "Double", "Short") { a, b -> a.div(b) }, + binaryOperation("equals", "Double", "Any") { a, b -> a.equals(b) }, + binaryOperation("minus", "Double", "Byte") { a, b -> a.minus(b) }, + binaryOperation("minus", "Double", "Double") { a, b -> a.minus(b) }, + binaryOperation("minus", "Double", "Float") { a, b -> a.minus(b) }, + binaryOperation("minus", "Double", "Int") { a, b -> a.minus(b) }, + binaryOperation("minus", "Double", "Long") { a, b -> a.minus(b) }, + binaryOperation("minus", "Double", "Short") { a, b -> a.minus(b) }, + binaryOperation("plus", "Double", "Byte") { a, b -> a.plus(b) }, + binaryOperation("plus", "Double", "Double") { a, b -> a.plus(b) }, + binaryOperation("plus", "Double", "Float") { a, b -> a.plus(b) }, + binaryOperation("plus", "Double", "Int") { a, b -> a.plus(b) }, + binaryOperation("plus", "Double", "Long") { a, b -> a.plus(b) }, + binaryOperation("plus", "Double", "Short") { a, b -> a.plus(b) }, + binaryOperation("rem", "Double", "Byte") { a, b -> a.rem(b) }, + binaryOperation("rem", "Double", "Double") { a, b -> a.rem(b) }, + binaryOperation("rem", "Double", "Float") { a, b -> a.rem(b) }, + binaryOperation("rem", "Double", "Int") { a, b -> a.rem(b) }, + binaryOperation("rem", "Double", "Long") { a, b -> a.rem(b) }, + binaryOperation("rem", "Double", "Short") { a, b -> a.rem(b) }, + binaryOperation("times", "Double", "Byte") { a, b -> a.times(b) }, + binaryOperation("times", "Double", "Double") { a, b -> a.times(b) }, + binaryOperation("times", "Double", "Float") { a, b -> a.times(b) }, + binaryOperation("times", "Double", "Int") { a, b -> a.times(b) }, + binaryOperation("times", "Double", "Long") { a, b -> a.times(b) }, + binaryOperation("times", "Double", "Short") { a, b -> a.times(b) }, + binaryOperation("compareTo", "Float", "Byte") { a, b -> a.compareTo(b) }, + binaryOperation("compareTo", "Float", "Double") { a, b -> a.compareTo(b) }, + binaryOperation("compareTo", "Float", "Float") { a, b -> a.compareTo(b) }, + binaryOperation("compareTo", "Float", "Int") { a, b -> a.compareTo(b) }, + binaryOperation("compareTo", "Float", "Long") { a, b -> a.compareTo(b) }, + binaryOperation("compareTo", "Float", "Short") { a, b -> a.compareTo(b) }, + binaryOperation("div", "Float", "Byte") { a, b -> a.div(b) }, + binaryOperation("div", "Float", "Double") { a, b -> a.div(b) }, + binaryOperation("div", "Float", "Float") { a, b -> a.div(b) }, + binaryOperation("div", "Float", "Int") { a, b -> a.div(b) }, + binaryOperation("div", "Float", "Long") { a, b -> a.div(b) }, + binaryOperation("div", "Float", "Short") { a, b -> a.div(b) }, + binaryOperation("equals", "Float", "Any") { a, b -> a.equals(b) }, + binaryOperation("minus", "Float", "Byte") { a, b -> a.minus(b) }, + binaryOperation("minus", "Float", "Double") { a, b -> a.minus(b) }, + binaryOperation("minus", "Float", "Float") { a, b -> a.minus(b) }, + binaryOperation("minus", "Float", "Int") { a, b -> a.minus(b) }, + binaryOperation("minus", "Float", "Long") { a, b -> a.minus(b) }, + binaryOperation("minus", "Float", "Short") { a, b -> a.minus(b) }, + binaryOperation("plus", "Float", "Byte") { a, b -> a.plus(b) }, + binaryOperation("plus", "Float", "Double") { a, b -> a.plus(b) }, + binaryOperation("plus", "Float", "Float") { a, b -> a.plus(b) }, + binaryOperation("plus", "Float", "Int") { a, b -> a.plus(b) }, + binaryOperation("plus", "Float", "Long") { a, b -> a.plus(b) }, + binaryOperation("plus", "Float", "Short") { a, b -> a.plus(b) }, + binaryOperation("rem", "Float", "Byte") { a, b -> a.rem(b) }, + binaryOperation("rem", "Float", "Double") { a, b -> a.rem(b) }, + binaryOperation("rem", "Float", "Float") { a, b -> a.rem(b) }, + binaryOperation("rem", "Float", "Int") { a, b -> a.rem(b) }, + binaryOperation("rem", "Float", "Long") { a, b -> a.rem(b) }, + binaryOperation("rem", "Float", "Short") { a, b -> a.rem(b) }, + binaryOperation("times", "Float", "Byte") { a, b -> a.times(b) }, + binaryOperation("times", "Float", "Double") { a, b -> a.times(b) }, + binaryOperation("times", "Float", "Float") { a, b -> a.times(b) }, + binaryOperation("times", "Float", "Int") { a, b -> a.times(b) }, + binaryOperation("times", "Float", "Long") { a, b -> a.times(b) }, + binaryOperation("times", "Float", "Short") { a, b -> a.times(b) }, + binaryOperation("and", "Int", "Int") { a, b -> a.and(b) }, + binaryOperation("compareTo", "Int", "Byte") { a, b -> a.compareTo(b) }, + binaryOperation("compareTo", "Int", "Double") { a, b -> a.compareTo(b) }, + binaryOperation("compareTo", "Int", "Float") { a, b -> a.compareTo(b) }, + binaryOperation("compareTo", "Int", "Int") { a, b -> a.compareTo(b) }, + binaryOperation("compareTo", "Int", "Long") { a, b -> a.compareTo(b) }, + binaryOperation("compareTo", "Int", "Short") { a, b -> a.compareTo(b) }, + binaryOperation("div", "Int", "Byte") { a, b -> a.div(b) }, + binaryOperation("div", "Int", "Double") { a, b -> a.div(b) }, + binaryOperation("div", "Int", "Float") { a, b -> a.div(b) }, + binaryOperation("div", "Int", "Int") { a, b -> a.div(b) }, + binaryOperation("div", "Int", "Long") { a, b -> a.div(b) }, + binaryOperation("div", "Int", "Short") { a, b -> a.div(b) }, + binaryOperation("equals", "Int", "Any") { a, b -> a.equals(b) }, + binaryOperation("minus", "Int", "Byte") { a, b -> a.minus(b) }, + binaryOperation("minus", "Int", "Double") { a, b -> a.minus(b) }, + binaryOperation("minus", "Int", "Float") { a, b -> a.minus(b) }, + binaryOperation("minus", "Int", "Int") { a, b -> a.minus(b) }, + binaryOperation("minus", "Int", "Long") { a, b -> a.minus(b) }, + binaryOperation("minus", "Int", "Short") { a, b -> a.minus(b) }, + binaryOperation("or", "Int", "Int") { a, b -> a.or(b) }, + binaryOperation("plus", "Int", "Byte") { a, b -> a.plus(b) }, + binaryOperation("plus", "Int", "Double") { a, b -> a.plus(b) }, + binaryOperation("plus", "Int", "Float") { a, b -> a.plus(b) }, + binaryOperation("plus", "Int", "Int") { a, b -> a.plus(b) }, + binaryOperation("plus", "Int", "Long") { a, b -> a.plus(b) }, + binaryOperation("plus", "Int", "Short") { a, b -> a.plus(b) }, + binaryOperation("rem", "Int", "Byte") { a, b -> a.rem(b) }, + binaryOperation("rem", "Int", "Double") { a, b -> a.rem(b) }, + binaryOperation("rem", "Int", "Float") { a, b -> a.rem(b) }, + binaryOperation("rem", "Int", "Int") { a, b -> a.rem(b) }, + binaryOperation("rem", "Int", "Long") { a, b -> a.rem(b) }, + binaryOperation("rem", "Int", "Short") { a, b -> a.rem(b) }, + binaryOperation("shl", "Int", "Int") { a, b -> a.shl(b) }, + binaryOperation("shr", "Int", "Int") { a, b -> a.shr(b) }, + binaryOperation("times", "Int", "Byte") { a, b -> a.times(b) }, + binaryOperation("times", "Int", "Double") { a, b -> a.times(b) }, + binaryOperation("times", "Int", "Float") { a, b -> a.times(b) }, + binaryOperation("times", "Int", "Int") { a, b -> a.times(b) }, + binaryOperation("times", "Int", "Long") { a, b -> a.times(b) }, + binaryOperation("times", "Int", "Short") { a, b -> a.times(b) }, + binaryOperation("ushr", "Int", "Int") { a, b -> a.ushr(b) }, + binaryOperation("xor", "Int", "Int") { a, b -> a.xor(b) }, + binaryOperation("and", "Long", "Long") { a, b -> a.and(b) }, + binaryOperation("compareTo", "Long", "Byte") { a, b -> a.compareTo(b) }, + binaryOperation("compareTo", "Long", "Double") { a, b -> a.compareTo(b) }, + binaryOperation("compareTo", "Long", "Float") { a, b -> a.compareTo(b) }, + binaryOperation("compareTo", "Long", "Int") { a, b -> a.compareTo(b) }, + binaryOperation("compareTo", "Long", "Long") { a, b -> a.compareTo(b) }, + binaryOperation("compareTo", "Long", "Short") { a, b -> a.compareTo(b) }, + binaryOperation("div", "Long", "Byte") { a, b -> a.div(b) }, + binaryOperation("div", "Long", "Double") { a, b -> a.div(b) }, + binaryOperation("div", "Long", "Float") { a, b -> a.div(b) }, + binaryOperation("div", "Long", "Int") { a, b -> a.div(b) }, + binaryOperation("div", "Long", "Long") { a, b -> a.div(b) }, + binaryOperation("div", "Long", "Short") { a, b -> a.div(b) }, + binaryOperation("equals", "Long", "Any") { a, b -> a.equals(b) }, + binaryOperation("minus", "Long", "Byte") { a, b -> a.minus(b) }, + binaryOperation("minus", "Long", "Double") { a, b -> a.minus(b) }, + binaryOperation("minus", "Long", "Float") { a, b -> a.minus(b) }, + binaryOperation("minus", "Long", "Int") { a, b -> a.minus(b) }, + binaryOperation("minus", "Long", "Long") { a, b -> a.minus(b) }, + binaryOperation("minus", "Long", "Short") { a, b -> a.minus(b) }, + binaryOperation("or", "Long", "Long") { a, b -> a.or(b) }, + binaryOperation("plus", "Long", "Byte") { a, b -> a.plus(b) }, + binaryOperation("plus", "Long", "Double") { a, b -> a.plus(b) }, + binaryOperation("plus", "Long", "Float") { a, b -> a.plus(b) }, + binaryOperation("plus", "Long", "Int") { a, b -> a.plus(b) }, + binaryOperation("plus", "Long", "Long") { a, b -> a.plus(b) }, + binaryOperation("plus", "Long", "Short") { a, b -> a.plus(b) }, + binaryOperation("rem", "Long", "Byte") { a, b -> a.rem(b) }, + binaryOperation("rem", "Long", "Double") { a, b -> a.rem(b) }, + binaryOperation("rem", "Long", "Float") { a, b -> a.rem(b) }, + binaryOperation("rem", "Long", "Int") { a, b -> a.rem(b) }, + binaryOperation("rem", "Long", "Long") { a, b -> a.rem(b) }, + binaryOperation("rem", "Long", "Short") { a, b -> a.rem(b) }, + binaryOperation("shl", "Long", "Int") { a, b -> a.shl(b) }, + binaryOperation("shr", "Long", "Int") { a, b -> a.shr(b) }, + binaryOperation("times", "Long", "Byte") { a, b -> a.times(b) }, + binaryOperation("times", "Long", "Double") { a, b -> a.times(b) }, + binaryOperation("times", "Long", "Float") { a, b -> a.times(b) }, + binaryOperation("times", "Long", "Int") { a, b -> a.times(b) }, + binaryOperation("times", "Long", "Long") { a, b -> a.times(b) }, + binaryOperation("times", "Long", "Short") { a, b -> a.times(b) }, + binaryOperation("ushr", "Long", "Int") { a, b -> a.ushr(b) }, + binaryOperation("xor", "Long", "Long") { a, b -> a.xor(b) }, + binaryOperation("compareTo", "Short", "Byte") { a, b -> a.compareTo(b) }, + binaryOperation("compareTo", "Short", "Double") { a, b -> a.compareTo(b) }, + binaryOperation("compareTo", "Short", "Float") { a, b -> a.compareTo(b) }, + binaryOperation("compareTo", "Short", "Int") { a, b -> a.compareTo(b) }, + binaryOperation("compareTo", "Short", "Long") { a, b -> a.compareTo(b) }, + binaryOperation("compareTo", "Short", "Short") { a, b -> a.compareTo(b) }, + binaryOperation("div", "Short", "Byte") { a, b -> a.div(b) }, + binaryOperation("div", "Short", "Double") { a, b -> a.div(b) }, + binaryOperation("div", "Short", "Float") { a, b -> a.div(b) }, + binaryOperation("div", "Short", "Int") { a, b -> a.div(b) }, + binaryOperation("div", "Short", "Long") { a, b -> a.div(b) }, + binaryOperation("div", "Short", "Short") { a, b -> a.div(b) }, + binaryOperation("equals", "Short", "Any") { a, b -> a.equals(b) }, + binaryOperation("minus", "Short", "Byte") { a, b -> a.minus(b) }, + binaryOperation("minus", "Short", "Double") { a, b -> a.minus(b) }, + binaryOperation("minus", "Short", "Float") { a, b -> a.minus(b) }, + binaryOperation("minus", "Short", "Int") { a, b -> a.minus(b) }, + binaryOperation("minus", "Short", "Long") { a, b -> a.minus(b) }, + binaryOperation("minus", "Short", "Short") { a, b -> a.minus(b) }, + binaryOperation("plus", "Short", "Byte") { a, b -> a.plus(b) }, + binaryOperation("plus", "Short", "Double") { a, b -> a.plus(b) }, + binaryOperation("plus", "Short", "Float") { a, b -> a.plus(b) }, + binaryOperation("plus", "Short", "Int") { a, b -> a.plus(b) }, + binaryOperation("plus", "Short", "Long") { a, b -> a.plus(b) }, + binaryOperation("plus", "Short", "Short") { a, b -> a.plus(b) }, + binaryOperation("rem", "Short", "Byte") { a, b -> a.rem(b) }, + binaryOperation("rem", "Short", "Double") { a, b -> a.rem(b) }, + binaryOperation("rem", "Short", "Float") { a, b -> a.rem(b) }, + binaryOperation("rem", "Short", "Int") { a, b -> a.rem(b) }, + binaryOperation("rem", "Short", "Long") { a, b -> a.rem(b) }, + binaryOperation("rem", "Short", "Short") { a, b -> a.rem(b) }, + binaryOperation("times", "Short", "Byte") { a, b -> a.times(b) }, + binaryOperation("times", "Short", "Double") { a, b -> a.times(b) }, + binaryOperation("times", "Short", "Float") { a, b -> a.times(b) }, + binaryOperation("times", "Short", "Int") { a, b -> a.times(b) }, + binaryOperation("times", "Short", "Long") { a, b -> a.times(b) }, + binaryOperation("times", "Short", "Short") { a, b -> a.times(b) }, + binaryOperation("compareTo", "String", "String") { a, b -> a.compareTo(b) }, + binaryOperation("equals", "String", "Any") { a, b -> a.equals(b) }, + binaryOperation("get", "String", "Int") { a, b -> a.get(b) }, + binaryOperation("plus", "String", "Any") { a, b -> a.plus(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 }, + binaryOperation("less", "Int", "Int") { a, b -> a < b }, + binaryOperation("less", "Float", "Float") { a, b -> a < b }, + binaryOperation("less", "Long", "Long") { a, b -> a < b }, + binaryOperation("less", "Double", "Double") { a, b -> a < b }, + binaryOperation("lessOrEqual", "Char", "Char") { a, b -> a <= b }, + binaryOperation("lessOrEqual", "Byte", "Byte") { a, b -> a <= b }, + binaryOperation("lessOrEqual", "Short", "Short") { a, b -> a <= b }, + binaryOperation("lessOrEqual", "Int", "Int") { a, b -> a <= b }, + binaryOperation("lessOrEqual", "Float", "Float") { a, b -> a <= b }, + binaryOperation("lessOrEqual", "Long", "Long") { a, b -> a <= b }, + binaryOperation("lessOrEqual", "Double", "Double") { a, b -> a <= b }, + binaryOperation("greater", "Char", "Char") { a, b -> a > b }, + binaryOperation("greater", "Byte", "Byte") { a, b -> a > b }, + binaryOperation("greater", "Short", "Short") { a, b -> a > b }, + binaryOperation("greater", "Int", "Int") { a, b -> a > b }, + binaryOperation("greater", "Float", "Float") { a, b -> a > b }, + binaryOperation("greater", "Long", "Long") { a, b -> a > b }, + binaryOperation("greater", "Double", "Double") { a, b -> a > b }, + binaryOperation("greaterOrEqual", "Char", "Char") { a, b -> a >= b }, + binaryOperation("greaterOrEqual", "Byte", "Byte") { a, b -> a >= b }, + binaryOperation("greaterOrEqual", "Short", "Short") { a, b -> a >= b }, + binaryOperation("greaterOrEqual", "Int", "Int") { a, b -> a >= b }, + binaryOperation("greaterOrEqual", "Float", "Float") { a, b -> a >= b }, + binaryOperation("greaterOrEqual", "Long", "Long") { a, b -> a >= b }, + binaryOperation("greaterOrEqual", "Double", "Double") { a, b -> a >= b }, + binaryOperation("EQEQ", "Any", "Any") { a, b -> a == b }, + binaryOperation("EQEQEQ", "Any", "Any") { a, b -> a === b }, + binaryOperation("ieee754equals", "Float", "Float") { a, b -> a == b }, + binaryOperation("ieee754equals", "Double", "Double") { a, b -> a == b }, + binaryOperation("ANDAND", "Boolean", "Boolean") { a, b -> a && b }, + binaryOperation("OROR", "Boolean", "Boolean") { a, b -> a || b } +) diff --git a/generators/build.gradle.kts b/generators/build.gradle.kts index e9fa74ceb42..748cba6cfca 100644 --- a/generators/build.gradle.kts +++ b/generators/build.gradle.kts @@ -31,6 +31,7 @@ dependencies { builtinsApi("org.jetbrains.kotlin:kotlin-stdlib:$bootstrapKotlinVersion") { isTransitive = false } evaluateApi(project(":core:deserialization")) + evaluateApi(project(":compiler:ir.serialization.jvm")) // used to get ir builtins testCompile(builtinsSourceSet.output) testCompile(evaluateSourceSet.output) @@ -88,5 +89,6 @@ val generateKeywordStrings by generator("org.jetbrains.kotlin.generators.fronten val generateBuiltins by generator("org.jetbrains.kotlin.generators.builtins.generateBuiltIns.GenerateBuiltInsKt", builtinsSourceSet) val generateOperationsMap by generator("org.jetbrains.kotlin.generators.evaluate.GenerateOperationsMapKt", evaluateSourceSet) +val generateInterpreterBuiltinsMap by generator("org.jetbrains.kotlin.generators.evaluate.GenerateBuiltInsMapKt", evaluateSourceSet) testsJar() diff --git a/generators/evaluate/GenerateBuiltInsMap.kt b/generators/evaluate/GenerateBuiltInsMap.kt new file mode 100644 index 00000000000..07ef20efe46 --- /dev/null +++ b/generators/evaluate/GenerateBuiltInsMap.kt @@ -0,0 +1,154 @@ +/* + * Copyright 2010-2019 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. + */ + +package org.jetbrains.kotlin.generators.evaluate + +import org.jetbrains.kotlin.backend.jvm.serialization.JvmIdSignatureDescriptor +import org.jetbrains.kotlin.builtins.DefaultBuiltIns +import org.jetbrains.kotlin.builtins.KotlinBuiltIns +import org.jetbrains.kotlin.config.ApiVersion +import org.jetbrains.kotlin.config.LanguageVersion +import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl +import org.jetbrains.kotlin.descriptors.CallableDescriptor +import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.descriptors.FunctionDescriptor +import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl +import org.jetbrains.kotlin.ir.backend.jvm.serialization.JvmManglerDesc +import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns +import org.jetbrains.kotlin.ir.util.ConstantValueGenerator +import org.jetbrains.kotlin.ir.util.SymbolTable +import org.jetbrains.kotlin.ir.util.TypeTranslator +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.storage.LockBasedStorageManager +import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.types.TypeUtils +import org.jetbrains.kotlin.utils.Printer +import java.io.File + +val DESTINATION = File("compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/interpreter/builtins/IrBuiltInsMapGenerated.kt") +val compileTimeAnnotation = FqName("kotlin.CompileTimeCalculation") + +fun main() { + DESTINATION.writeText(generateMap()) +} + +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("/** This file is generated by org.jetbrains.kotlin.backend.common.interpreter.builtins.GenerateBuiltInsMap.generateMap(). DO NOT MODIFY MANUALLY */") + p.println() + + val unaryOperationsMap = mutableMapOf>() + val binaryOperationsMap = mutableMapOf>() + val builtIns = DefaultBuiltIns.Instance + + //save common built ins + @Suppress("UNCHECKED_CAST") + val allPrimitiveTypes = builtIns.builtInsPackageScope.getContributedDescriptors() + .filter { it is ClassDescriptor && KotlinBuiltIns.isPrimitiveType(it.defaultType) } as List + + for (descriptor in allPrimitiveTypes + builtIns.string) { + val descriptorType = descriptor.defaultType + @Suppress("UNCHECKED_CAST") + val functions = descriptor.getMemberScope(listOf()).getContributedDescriptors() + .filter { it is CallableDescriptor && it.annotations.hasAnnotation(compileTimeAnnotation) } as List + + for (function in functions) { + val parametersTypes = function.valueParameters.map { TypeUtils.makeNotNullable(it.type) } + listOf(descriptorType) + + when (parametersTypes.size) { + 1 -> unaryOperationsMap[function] = parametersTypes + 2 -> binaryOperationsMap[function] = parametersTypes + else -> throw IllegalStateException("Couldn't add following method from builtins to operations map: ${function.name} in class ${descriptor.name}") + } + } + } + + //save ir built ins + val binaryIrOperationsMap = mutableMapOf>() + val irBuiltIns = getIrBuiltIns() + val irFunSymbols = + (irBuiltIns.lessFunByOperandType.values + + irBuiltIns.lessOrEqualFunByOperandType.values + + irBuiltIns.greaterFunByOperandType.values + + irBuiltIns.greaterOrEqualFunByOperandType.values + + irBuiltIns.eqeqSymbol + + irBuiltIns.eqeqeqSymbol + + irBuiltIns.ieee754equalsFunByOperandType.values + + irBuiltIns.andandSymbol + + irBuiltIns.ororSymbol) + .map { it.descriptor } + .filter { it.annotations.hasAnnotation(compileTimeAnnotation) } + + for (function in irFunSymbols) { + val parametersTypes = function.valueParameters.map { TypeUtils.makeNotNullable(it.type) } + + check(parametersTypes.size == 2) { "Couldn't add following method from ir builtins to operations map: ${function.name}" } + binaryIrOperationsMap[function] = parametersTypes + } + + //save to file + p.println("val unaryFunctions = mapOf>(") + val unaryBody = unaryOperationsMap.entries.joinToString(",\n") { (function, parameters) -> + val receiverType = parameters.last().toString() + val methodName = "${function.name}" + val parentheses = if (function is FunctionDescriptor) "()" else "" + " unaryOperation<$receiverType>(\"$methodName\", \"$receiverType\") { a -> a.$methodName$parentheses }" + } + p.println(unaryBody) + p.println(")") + p.println() + + p.println("val binaryFunctions = mapOf>(") + val binaryBody = binaryOperationsMap.entries.joinToString(",\n", postfix = ",\n") { (function, parameters) -> + val receiverType = parameters.last().toString() + val parameter = parameters.first().toString() + val methodName = "${function.name}" + " binaryOperation<$receiverType, $parameter>(\"$methodName\", \"$receiverType\", \"$parameter\") { a, b -> a.$methodName(b) }" + } + binaryIrOperationsMap.entries.joinToString(",\n") { (function, parameters) -> + val firstParameterType = parameters.last().toString() + val secondParameterType = parameters.first().toString() + val methodName = "${function.name}" + val methodSymbol = when (methodName) { + IrBuiltIns.OperatorNames.LESS -> "<" + IrBuiltIns.OperatorNames.LESS_OR_EQUAL -> "<=" + IrBuiltIns.OperatorNames.GREATER -> ">" + IrBuiltIns.OperatorNames.GREATER_OR_EQUAL -> ">=" + IrBuiltIns.OperatorNames.EQEQ -> "==" + IrBuiltIns.OperatorNames.EQEQEQ -> "===" + IrBuiltIns.OperatorNames.IEEE754_EQUALS -> "==" + IrBuiltIns.OperatorNames.ANDAND -> "&&" + IrBuiltIns.OperatorNames.OROR -> "||" + else -> throw UnsupportedOperationException("Unknown ir operation \"$methodName\"") + } + " binaryOperation<$firstParameterType, $secondParameterType>(\"$methodName\", \"$firstParameterType\", \"$secondParameterType\") { a, b -> a $methodSymbol b }" + } + p.println(binaryBody) + p.println(")") + + return sb.toString() +} + +private fun getIrBuiltIns(): IrBuiltIns { + val builtIns = DefaultBuiltIns.Instance + val languageSettings = LanguageVersionSettingsImpl(LanguageVersion.KOTLIN_1_3, ApiVersion.KOTLIN_1_3) + + val moduleDescriptor = ModuleDescriptorImpl(Name.special(""), LockBasedStorageManager(""), builtIns) + val mangler = JvmManglerDesc() + val signaturer = JvmIdSignatureDescriptor(mangler) + val symbolTable = SymbolTable(signaturer) + val constantValueGenerator = ConstantValueGenerator(moduleDescriptor, symbolTable) + val typeTranslator = TypeTranslator(symbolTable, languageSettings, builtIns) + constantValueGenerator.typeTranslator = typeTranslator + typeTranslator.constantValueGenerator = constantValueGenerator + + return IrBuiltIns(builtIns, typeTranslator, signaturer) +} \ No newline at end of file