JVM: cleanup intrinsics code

Remove unused methods, remove dependency on old backend structures,
reformat, fix some inspections.
This commit is contained in:
Alexander Udalov
2023-07-18 23:54:15 +02:00
committed by Space Team
parent ad3583ac38
commit f8faa0fe5a
27 changed files with 84 additions and 130 deletions
@@ -12,7 +12,6 @@ import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
import org.jetbrains.org.objectweb.asm.Label import org.jetbrains.org.objectweb.asm.Label
object AndAnd : IntrinsicMethod() { object AndAnd : IntrinsicMethod() {
private class BooleanConjunction(val arg0: IrExpression, val arg1: IrExpression, codegen: ExpressionCodegen, val data: BlockInfo) : private class BooleanConjunction(val arg0: IrExpression, val arg1: IrExpression, codegen: ExpressionCodegen, val data: BlockInfo) :
BooleanValue(codegen) { BooleanValue(codegen) {
@@ -36,7 +35,7 @@ object AndAnd : IntrinsicMethod() {
} }
} }
override fun invoke(expression: IrFunctionAccessExpression, codegen: ExpressionCodegen, data: BlockInfo): PromisedValue? { override fun invoke(expression: IrFunctionAccessExpression, codegen: ExpressionCodegen, data: BlockInfo): PromisedValue {
val (left, right) = expression.receiverAndArgs() val (left, right) = expression.receiverAndArgs()
return BooleanConjunction(left, right, codegen, data) return BooleanConjunction(left, right, codegen, data)
} }
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.Type
object ArrayGet : IntrinsicMethod() { object ArrayGet : IntrinsicMethod() {
override fun invoke(expression: IrFunctionAccessExpression, codegen: ExpressionCodegen, data: BlockInfo): PromisedValue? { override fun invoke(expression: IrFunctionAccessExpression, codegen: ExpressionCodegen, data: BlockInfo): PromisedValue {
val dispatchReceiver = expression.dispatchReceiver!! val dispatchReceiver = expression.dispatchReceiver!!
val receiver = dispatchReceiver.accept(codegen, data).materializedAt(dispatchReceiver.type) val receiver = dispatchReceiver.accept(codegen, data).materializedAt(dispatchReceiver.type)
val elementType = AsmUtil.correctElementType(receiver.type) val elementType = AsmUtil.correctElementType(receiver.type)
@@ -27,10 +27,10 @@ object ArrayIterator : IntrinsicMethod() {
override fun toCallable( override fun toCallable(
expression: IrFunctionAccessExpression, expression: IrFunctionAccessExpression,
signature: JvmMethodSignature, signature: JvmMethodSignature,
classCodegen: ClassCodegen classCodegen: ClassCodegen,
): IrIntrinsicFunction { ): IrIntrinsicFunction {
val owner = classCodegen.typeMapper.mapClass(expression.symbol.owner.parentAsClass) val owner = classCodegen.typeMapper.mapClass(expression.symbol.owner.parentAsClass)
return IrIntrinsicFunction.create(expression, signature, classCodegen, owner) { return IrIntrinsicFunction.create(expression, signature, classCodegen, listOf(owner)) {
val methodSignature = "(${owner.descriptor})${signature.returnType.descriptor}" val methodSignature = "(${owner.descriptor})${signature.returnType.descriptor}"
val intrinsicOwner = val intrinsicOwner =
if (AsmUtil.isPrimitive(owner.elementType)) if (AsmUtil.isPrimitive(owner.elementType))
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.ir.types.getArrayElementType
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.Type
object ArraySet : IntrinsicMethod() { object ArraySet : IntrinsicMethod() {
override fun invoke(expression: IrFunctionAccessExpression, codegen: ExpressionCodegen, data: BlockInfo): PromisedValue? { override fun invoke(expression: IrFunctionAccessExpression, codegen: ExpressionCodegen, data: BlockInfo): PromisedValue {
val dispatchReceiver = expression.dispatchReceiver!! val dispatchReceiver = expression.dispatchReceiver!!
val receiver = dispatchReceiver.accept(codegen, data).materializedAt(dispatchReceiver.type) val receiver = dispatchReceiver.accept(codegen, data).materializedAt(dispatchReceiver.type)
val elementType = AsmUtil.correctElementType(receiver.type) val elementType = AsmUtil.correctElementType(receiver.type)
@@ -21,11 +21,11 @@ import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
object ArraySize : IntrinsicMethod() { object ArraySize : IntrinsicMethod() {
override fun toCallable(
override fun toCallable(expression: IrFunctionAccessExpression, signature: JvmMethodSignature, classCodegen: ClassCodegen): IrIntrinsicFunction { expression: IrFunctionAccessExpression, signature: JvmMethodSignature, classCodegen: ClassCodegen,
): IrIntrinsicFunction {
return IrIntrinsicFunction.create(expression, signature, classCodegen) { return IrIntrinsicFunction.create(expression, signature, classCodegen) {
it.arraylength() it.arraylength()
} }
} }
} }
@@ -67,7 +67,7 @@ object CompareTo : IntrinsicMethod() {
} }
} }
class IntegerZeroComparison(val op: IElementType, val a: MaterialValue) : BooleanValue(a.codegen) { class IntegerZeroComparison(val a: MaterialValue) : BooleanValue(a.codegen) {
override fun jumpIfFalse(target: Label) { override fun jumpIfFalse(target: Label) {
mv.visitJumpInsn(Opcodes.IFNE, target) mv.visitJumpInsn(Opcodes.IFNE, target)
} }
@@ -19,12 +19,13 @@ import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.ir.declarations.isSingleFieldValueClass import org.jetbrains.kotlin.ir.declarations.isSingleFieldValueClass
import org.jetbrains.kotlin.ir.descriptors.toIrBasedKotlinType import org.jetbrains.kotlin.ir.descriptors.toIrBasedKotlinType
import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.*
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.types.isNullable import org.jetbrains.kotlin.ir.types.isNullable
import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.util.isEnumClass
import org.jetbrains.kotlin.ir.util.isEnumEntry
import org.jetbrains.kotlin.ir.util.isIntegerConst
import org.jetbrains.kotlin.ir.util.isNullConst
import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
import org.jetbrains.kotlin.resolve.jvm.AsmTypes import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
import org.jetbrains.kotlin.types.isNullable import org.jetbrains.kotlin.types.isNullable
@@ -36,7 +37,7 @@ import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
class ExplicitEquals : IntrinsicMethod() { class ExplicitEquals : IntrinsicMethod() {
override fun invoke(expression: IrFunctionAccessExpression, codegen: ExpressionCodegen, data: BlockInfo): PromisedValue? { override fun invoke(expression: IrFunctionAccessExpression, codegen: ExpressionCodegen, data: BlockInfo): PromisedValue {
val (a, b) = expression.receiverAndArgs() val (a, b) = expression.receiverAndArgs()
// TODO use specialized boxed type - this might require types like 'java.lang.Integer' in IR // TODO use specialized boxed type - this might require types like 'java.lang.Integer' in IR
@@ -64,7 +65,7 @@ class Equals(val operator: IElementType) : IntrinsicMethod() {
} }
} }
override fun invoke(expression: IrFunctionAccessExpression, codegen: ExpressionCodegen, data: BlockInfo): PromisedValue? { override fun invoke(expression: IrFunctionAccessExpression, codegen: ExpressionCodegen, data: BlockInfo): PromisedValue {
val (a, b) = expression.receiverAndArgs() val (a, b) = expression.receiverAndArgs()
if (a.isNullConst() || b.isNullConst()) { if (a.isNullConst() || b.isNullConst()) {
val irValue = if (a.isNullConst()) b else a val irValue = if (a.isNullConst()) b else a
@@ -136,7 +137,7 @@ class Equals(val operator: IElementType) : IntrinsicMethod() {
val operandType = if (!isPrimitive(leftType)) AsmTypes.OBJECT_TYPE else leftType val operandType = if (!isPrimitive(leftType)) AsmTypes.OBJECT_TYPE else leftType
return if (operandType == Type.INT_TYPE && (left.isIntegerConst(0) || right.isIntegerConst(0))) { return if (operandType == Type.INT_TYPE && (left.isIntegerConst(0) || right.isIntegerConst(0))) {
val nonZero = if (left.isIntegerConst(0)) right else left val nonZero = if (left.isIntegerConst(0)) right else left
IntegerZeroComparison(operator, nonZero.accept(codegen, data).materializedAt(operandType, nonZero.type)) IntegerZeroComparison(nonZero.accept(codegen, data).materializedAt(operandType, nonZero.type))
} else { } else {
val leftValue = left.accept(codegen, data).materializedAt(operandType, left.type) val leftValue = left.accept(codegen, data).materializedAt(operandType, left.type)
val rightValue = right.accept(codegen, data).materializedAt(operandType, right.type) val rightValue = right.accept(codegen, data).materializedAt(operandType, right.type)
@@ -22,7 +22,9 @@ import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
class Increment(private val myDelta: Int) : IntrinsicMethod() { class Increment(private val myDelta: Int) : IntrinsicMethod() {
override fun toCallable(expression: IrFunctionAccessExpression, signature: JvmMethodSignature, classCodegen: ClassCodegen): IrIntrinsicFunction { override fun toCallable(
expression: IrFunctionAccessExpression, signature: JvmMethodSignature, classCodegen: ClassCodegen,
): IrIntrinsicFunction {
return IrIntrinsicFunction.create(expression, signature, classCodegen) { return IrIntrinsicFunction.create(expression, signature, classCodegen) {
genIncrement(signature.returnType, myDelta, it) genIncrement(signature.returnType, myDelta, it)
} }
@@ -23,15 +23,15 @@ import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.Type
object Inv : IntrinsicMethod() { object Inv : IntrinsicMethod() {
/*TODO new this type*/ override fun toCallable(
override fun toCallable(expression: IrFunctionAccessExpression, signature: JvmMethodSignature, classCodegen: ClassCodegen): IrIntrinsicFunction { expression: IrFunctionAccessExpression, signature: JvmMethodSignature, classCodegen: ClassCodegen,
): IrIntrinsicFunction {
val returnType = signature.returnType val returnType = signature.returnType
val type = numberFunctionOperandType(returnType) val type = numberFunctionOperandType(returnType)
return IrIntrinsicFunction.create(expression, signature, classCodegen, type) { return IrIntrinsicFunction.create(expression, signature, classCodegen, listOf(type)) {
if (returnType == Type.LONG_TYPE) { if (returnType == Type.LONG_TYPE) {
it.lconst(-1) it.lconst(-1)
} } else {
else {
it.iconst(-1) it.iconst(-1)
} }
it.xor(returnType) it.xor(returnType)
@@ -5,7 +5,10 @@
package org.jetbrains.kotlin.backend.jvm.intrinsics package org.jetbrains.kotlin.backend.jvm.intrinsics
import org.jetbrains.kotlin.backend.jvm.codegen.* import org.jetbrains.kotlin.backend.jvm.codegen.BlockInfo
import org.jetbrains.kotlin.backend.jvm.codegen.ExpressionCodegen
import org.jetbrains.kotlin.backend.jvm.codegen.PromisedValue
import org.jetbrains.kotlin.backend.jvm.codegen.materialized
import org.jetbrains.kotlin.codegen.AsmUtil import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
@@ -14,7 +17,7 @@ import org.jetbrains.org.objectweb.asm.Label
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.Type
object IrCheckNotNull : IntrinsicMethod() { object IrCheckNotNull : IntrinsicMethod() {
override fun invoke(expression: IrFunctionAccessExpression, codegen: ExpressionCodegen, data: BlockInfo): PromisedValue? { override fun invoke(expression: IrFunctionAccessExpression, codegen: ExpressionCodegen, data: BlockInfo): PromisedValue {
val arg0 = expression.getValueArgument(0)!!.accept(codegen, data) val arg0 = expression.getValueArgument(0)!!.accept(codegen, data)
if (AsmUtil.isPrimitive(arg0.type)) return arg0 if (AsmUtil.isPrimitive(arg0.type)) return arg0
return object : PromisedValue(codegen, arg0.type, arg0.irType) { return object : PromisedValue(codegen, arg0.type, arg0.irType) {
@@ -12,7 +12,7 @@ import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
import org.jetbrains.kotlin.ir.util.isPrimitiveArray import org.jetbrains.kotlin.ir.util.isPrimitiveArray
object IrDataClassArrayMemberHashCode : IntrinsicMethod() { object IrDataClassArrayMemberHashCode : IntrinsicMethod() {
override fun invoke(expression: IrFunctionAccessExpression, codegen: ExpressionCodegen, data: BlockInfo): PromisedValue? = override fun invoke(expression: IrFunctionAccessExpression, codegen: ExpressionCodegen, data: BlockInfo): PromisedValue =
with(codegen) { with(codegen) {
val arrayType = expression.getValueArgument(0)!!.type val arrayType = expression.getValueArgument(0)!!.type
val asmArrayType = codegen.typeMapper.mapType(arrayType) val asmArrayType = codegen.typeMapper.mapType(arrayType)
@@ -12,7 +12,7 @@ import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
import org.jetbrains.kotlin.ir.util.isPrimitiveArray import org.jetbrains.kotlin.ir.util.isPrimitiveArray
object IrDataClassArrayMemberToString : IntrinsicMethod() { object IrDataClassArrayMemberToString : IntrinsicMethod() {
override fun invoke(expression: IrFunctionAccessExpression, codegen: ExpressionCodegen, data: BlockInfo): PromisedValue? = override fun invoke(expression: IrFunctionAccessExpression, codegen: ExpressionCodegen, data: BlockInfo): PromisedValue =
with(codegen) { with(codegen) {
val arrayType = expression.getValueArgument(0)!!.type val arrayType = expression.getValueArgument(0)!!.type
val asmArrayType = codegen.typeMapper.mapType(arrayType) val asmArrayType = codegen.typeMapper.mapType(arrayType)
@@ -10,7 +10,6 @@ import org.jetbrains.kotlin.backend.jvm.codegen.ClassCodegen
import org.jetbrains.kotlin.backend.jvm.codegen.ExpressionCodegen import org.jetbrains.kotlin.backend.jvm.codegen.ExpressionCodegen
import org.jetbrains.kotlin.backend.jvm.mapping.mapClass import org.jetbrains.kotlin.backend.jvm.mapping.mapClass
import org.jetbrains.kotlin.codegen.AsmUtil import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.StackValue import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
@@ -20,59 +19,27 @@ import org.jetbrains.kotlin.ir.util.isVararg
import org.jetbrains.kotlin.ir.util.parentAsClass import org.jetbrains.kotlin.ir.util.parentAsClass
import org.jetbrains.kotlin.ir.util.substitute import org.jetbrains.kotlin.ir.util.substitute
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
open class IrIntrinsicFunction( abstract class IrIntrinsicFunction(
val expression: IrFunctionAccessExpression, val expression: IrFunctionAccessExpression,
val signature: JvmMethodSignature, val signature: JvmMethodSignature,
val classCodegen: ClassCodegen, val classCodegen: ClassCodegen,
val argsTypes: List<Type> = expression.argTypes(classCodegen) val argsTypes: List<Type>,
) : Callable { ) {
override val owner: Type abstract fun genInvokeInstruction(v: InstructionAdapter)
get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates.
override val dispatchReceiverType: Type?
get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates.
override val dispatchReceiverKotlinType: KotlinType?
get() = null
override val extensionReceiverType: Type?
get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates.
override val extensionReceiverKotlinType: KotlinType?
get() = null
override val generateCalleeType: Type?
get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates.
override val valueParameterTypes: List<Type>
get() = signature.valueParameters.map { it.asmType }
override val parameterTypes: Array<Type>
get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates.
override val returnType: Type
get() = signature.returnType
override val returnKotlinType: KotlinType?
get() = null
override fun isStaticCall(): Boolean {
return false
}
override fun genInvokeInstruction(v: InstructionAdapter) {
TODO("not implemented for $this")
}
open fun genInvokeInstructionWithResult(v: InstructionAdapter): Type {
genInvokeInstruction(v)
return returnType
}
open fun invoke( open fun invoke(
v: InstructionAdapter, v: InstructionAdapter,
codegen: ExpressionCodegen, codegen: ExpressionCodegen,
data: BlockInfo, data: BlockInfo,
expression: IrFunctionAccessExpression expression: IrFunctionAccessExpression,
): StackValue { ): StackValue {
loadArguments(codegen, data) loadArguments(codegen, data)
with(codegen) { expression.markLineNumber(startOffset = true) } with(codegen) { expression.markLineNumber(startOffset = true) }
return StackValue.onStack(genInvokeInstructionWithResult(v)) genInvokeInstruction(v)
return StackValue.onStack(signature.returnType)
} }
private fun loadArguments(codegen: ExpressionCodegen, data: BlockInfo) { private fun loadArguments(codegen: ExpressionCodegen, data: BlockInfo) {
@@ -112,39 +79,15 @@ open class IrIntrinsicFunction(
signature: JvmMethodSignature, signature: JvmMethodSignature,
classCodegen: ClassCodegen, classCodegen: ClassCodegen,
argsTypes: List<Type> = expression.argTypes(classCodegen), argsTypes: List<Type> = expression.argTypes(classCodegen),
invokeInstruction: IrIntrinsicFunction.(InstructionAdapter) -> Unit invokeInstruction: IrIntrinsicFunction.(InstructionAdapter) -> Unit,
): IrIntrinsicFunction { ): IrIntrinsicFunction =
return object : IrIntrinsicFunction(expression, signature, classCodegen, argsTypes) { object : IrIntrinsicFunction(expression, signature, classCodegen, argsTypes) {
override fun genInvokeInstruction(v: InstructionAdapter) = invokeInstruction(v) override fun genInvokeInstruction(v: InstructionAdapter) = invokeInstruction(v)
} }
}
fun createWithResult(
expression: IrFunctionAccessExpression, signature: JvmMethodSignature,
classCodegen: ClassCodegen,
argsTypes: List<Type> = expression.argTypes(classCodegen ),
invokeInstruction: IrIntrinsicFunction.(InstructionAdapter) -> Type
): IrIntrinsicFunction {
return object : IrIntrinsicFunction(expression, signature, classCodegen, argsTypes) {
override fun genInvokeInstructionWithResult(v: InstructionAdapter) = invokeInstruction(v)
}
}
fun create(
expression: IrFunctionAccessExpression,
signature: JvmMethodSignature,
classCodegen: ClassCodegen,
type: Type,
invokeInstruction: IrIntrinsicFunction.(InstructionAdapter) -> Unit
): IrIntrinsicFunction {
return create(expression, signature, classCodegen, listOf(type), invokeInstruction)
}
} }
} }
fun IrFunctionAccessExpression.argTypes(classCodegen: ClassCodegen): ArrayList<Type> { internal fun IrFunctionAccessExpression.argTypes(classCodegen: ClassCodegen): List<Type> {
val callee = symbol.owner val callee = symbol.owner
val signature = classCodegen.methodSignatureMapper.mapSignatureSkipGeneric(callee) val signature = classCodegen.methodSignatureMapper.mapSignatureSkipGeneric(callee)
return arrayListOf<Type>().apply { return arrayListOf<Type>().apply {
@@ -140,12 +140,12 @@ class IrIntrinsicMethods(val irBuiltIns: IrBuiltIns, val symbols: JvmSymbols) {
fun getIntrinsic(symbol: IrFunctionSymbol): IntrinsicMethod? = intrinsicsMap[symbol.toKey()] fun getIntrinsic(symbol: IrFunctionSymbol): IntrinsicMethod? = intrinsicsMap[symbol.toKey()]
private fun unaryFunForPrimitives(name: String, intrinsic: IntrinsicMethod): List<Pair<Key, IntrinsicMethod>> = private fun unaryFunForPrimitives(name: String, intrinsic: IntrinsicMethod): List<Pair<Key, IntrinsicMethod>> =
PrimitiveType.values().map { type -> PrimitiveType.entries.map { type ->
createKeyMapping(intrinsic, type.symbol, name) createKeyMapping(intrinsic, type.symbol, name)
} }
private fun binaryFunForPrimitivesAcrossPrimitives(name: String, intrinsic: IntrinsicMethod): List<Pair<Key, IntrinsicMethod>> = private fun binaryFunForPrimitivesAcrossPrimitives(name: String, intrinsic: IntrinsicMethod): List<Pair<Key, IntrinsicMethod>> =
PrimitiveType.values().flatMap { parameter -> PrimitiveType.entries.flatMap { parameter ->
binaryFunForPrimitives(name, intrinsic, parameter.symbol) binaryFunForPrimitives(name, intrinsic, parameter.symbol)
} }
@@ -155,7 +155,7 @@ class IrIntrinsicMethods(val irBuiltIns: IrBuiltIns, val symbols: JvmSymbols) {
intrinsic: IntrinsicMethod, intrinsic: IntrinsicMethod,
parameter: IrClassifierSymbol parameter: IrClassifierSymbol
): List<Pair<Key, IntrinsicMethod>> = ): List<Pair<Key, IntrinsicMethod>> =
PrimitiveType.values().map { type -> PrimitiveType.entries.map { type ->
createKeyMapping(intrinsic, type.symbol, name, parameter) createKeyMapping(intrinsic, type.symbol, name, parameter)
} }
@@ -186,7 +186,7 @@ class IrIntrinsicMethods(val irBuiltIns: IrBuiltIns, val symbols: JvmSymbols) {
typeToIrFun: Map<IrClassifierSymbol, IrSimpleFunctionSymbol>, typeToIrFun: Map<IrClassifierSymbol, IrSimpleFunctionSymbol>,
operator: KtSingleValueToken operator: KtSingleValueToken
): List<Pair<Key, PrimitiveComparison>> = ): List<Pair<Key, PrimitiveComparison>> =
PrimitiveType.values().mapNotNull { primitiveType -> PrimitiveType.entries.mapNotNull { primitiveType ->
val irPrimitiveClassifier = irBuiltIns.primitiveTypeToIrType[primitiveType]!!.classifierOrFail val irPrimitiveClassifier = irBuiltIns.primitiveTypeToIrType[primitiveType]!!.classifierOrFail
val irFunSymbol = typeToIrFun[irPrimitiveClassifier] ?: return@mapNotNull null val irFunSymbol = typeToIrFun[irPrimitiveClassifier] ?: return@mapNotNull null
irFunSymbol.toKey()!! to PrimitiveComparison(primitiveType, operator) irFunSymbol.toKey()!! to PrimitiveComparison(primitiveType, operator)
@@ -22,9 +22,11 @@ import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
object IrNoWhenBranchMatchedException : IntrinsicMethod() { object IrNoWhenBranchMatchedException : IntrinsicMethod() {
override fun toCallable(expression: IrFunctionAccessExpression, signature: JvmMethodSignature, classCodegen: ClassCodegen): IrIntrinsicFunction { override fun toCallable(
expression: IrFunctionAccessExpression, signature: JvmMethodSignature, classCodegen: ClassCodegen,
): IrIntrinsicFunction {
return IrIntrinsicFunction.create(expression, signature, classCodegen) { return IrIntrinsicFunction.create(expression, signature, classCodegen) {
genThrow(it, "kotlin/NoWhenBranchMatchedException", null) genThrow(it, "kotlin/NoWhenBranchMatchedException", null)
} }
} }
} }
@@ -27,13 +27,14 @@ import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.Type
object IteratorNext : IntrinsicMethod() { object IteratorNext : IntrinsicMethod() {
override fun toCallable(
override fun toCallable(expression: IrFunctionAccessExpression, signature: JvmMethodSignature, classCodegen: ClassCodegen): IrIntrinsicFunction { expression: IrFunctionAccessExpression, signature: JvmMethodSignature, classCodegen: ClassCodegen,
): IrIntrinsicFunction {
// If the array element type is unboxed primitive, do not unbox. Otherwise AsmUtil.unbox throws exception // If the array element type is unboxed primitive, do not unbox. Otherwise AsmUtil.unbox throws exception
val type = if (AsmUtil.isBoxedPrimitiveType(signature.returnType)) AsmUtil.unboxType(signature.returnType) else signature.returnType val type = if (AsmUtil.isBoxedPrimitiveType(signature.returnType)) AsmUtil.unboxType(signature.returnType) else signature.returnType
val newSignature = signature.newReturnType(type) val newSignature = signature.newReturnType(type)
val primitiveClassName = getKotlinPrimitiveClassName(type) val primitiveClassName = getKotlinPrimitiveClassName(type)
return IrIntrinsicFunction.create(expression, newSignature, classCodegen, getPrimitiveIteratorType(primitiveClassName)) { return IrIntrinsicFunction.create(expression, newSignature, classCodegen, listOf(getPrimitiveIteratorType(primitiveClassName))) {
it.invokevirtual( it.invokevirtual(
getPrimitiveIteratorType(primitiveClassName).internalName, getPrimitiveIteratorType(primitiveClassName).internalName,
"next${primitiveClassName.asString()}", "next${primitiveClassName.asString()}",
@@ -49,7 +50,7 @@ object IteratorNext : IntrinsicMethod() {
} }
// "Char" -> type for kotlin.collections.CharIterator // "Char" -> type for kotlin.collections.CharIterator
fun getPrimitiveIteratorType(primitiveClassName: Name): Type { private fun getPrimitiveIteratorType(primitiveClassName: Name): Type {
val iteratorName = Name.identifier(primitiveClassName.asString() + "Iterator") val iteratorName = Name.identifier(primitiveClassName.asString() + "Iterator")
return Type.getObjectType(COLLECTIONS_PACKAGE_FQ_NAME.child(iteratorName).internalNameWithoutInnerClasses) return Type.getObjectType(COLLECTIONS_PACKAGE_FQ_NAME.child(iteratorName).internalNameWithoutInnerClasses)
} }
@@ -31,11 +31,11 @@ class MonitorInstruction private constructor(private val opcode: Int) : Intrinsi
val MONITOR_EXIT: MonitorInstruction = MonitorInstruction(Opcodes.MONITOREXIT) val MONITOR_EXIT: MonitorInstruction = MonitorInstruction(Opcodes.MONITOREXIT)
} }
/*TODO void return type*/ override fun toCallable(
override fun toCallable(expression: IrFunctionAccessExpression, signature: JvmMethodSignature, classCodegen: ClassCodegen): IrIntrinsicFunction { expression: IrFunctionAccessExpression, signature: JvmMethodSignature, classCodegen: ClassCodegen,
return IrIntrinsicFunction.create(expression, signature, classCodegen, OBJECT_TYPE) { ): IrIntrinsicFunction {
return IrIntrinsicFunction.create(expression, signature, classCodegen, listOf(OBJECT_TYPE)) {
it.visitInsn(opcode) it.visitInsn(opcode)
} }
} }
} }
@@ -22,11 +22,11 @@ import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
object NumberCast : IntrinsicMethod() { object NumberCast : IntrinsicMethod() {
override fun toCallable(
override fun toCallable(expression: IrFunctionAccessExpression, signature: JvmMethodSignature, classCodegen: ClassCodegen): IrIntrinsicFunction { expression: IrFunctionAccessExpression, signature: JvmMethodSignature, classCodegen: ClassCodegen,
): IrIntrinsicFunction {
return IrIntrinsicFunction.create(expression, signature, classCodegen) { return IrIntrinsicFunction.create(expression, signature, classCodegen) {
StackValue.coerce(argsTypes[0], signature.returnType, it) StackValue.coerce(argsTypes[0], signature.returnType, it)
} }
} }
} }
@@ -37,7 +37,7 @@ object OrOr : IntrinsicMethod() {
} }
} }
override fun invoke(expression: IrFunctionAccessExpression, codegen: ExpressionCodegen, data: BlockInfo): PromisedValue? { override fun invoke(expression: IrFunctionAccessExpression, codegen: ExpressionCodegen, data: BlockInfo): PromisedValue {
val (left, right) = expression.receiverAndArgs() val (left, right) = expression.receiverAndArgs()
return BooleanDisjunction(left, right, codegen, data) return BooleanDisjunction(left, right, codegen, data)
} }
@@ -16,10 +16,12 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
object RangeTo : IntrinsicMethod() { object RangeTo : IntrinsicMethod() {
override fun toCallable( override fun toCallable(
expression: IrFunctionAccessExpression, signature: JvmMethodSignature, classCodegen: ClassCodegen expression: IrFunctionAccessExpression, signature: JvmMethodSignature, classCodegen: ClassCodegen,
): IrIntrinsicFunction { ): IrIntrinsicFunction {
val argType = mapRangeTypeToPrimitiveType(signature.returnType) val argType = mapRangeTypeToPrimitiveType(signature.returnType)
return object : IrIntrinsicFunction(expression, signature, classCodegen, listOf(argType) + signature.valueParameters.map { argType }) { return object : IrIntrinsicFunction(
expression, signature, classCodegen, listOf(argType) + signature.valueParameters.map { argType }
) {
override fun genInvokeInstruction(v: InstructionAdapter) { override fun genInvokeInstruction(v: InstructionAdapter) {
v.invokespecial( v.invokespecial(
signature.returnType.internalName, signature.returnType.internalName,
@@ -33,10 +35,10 @@ object RangeTo : IntrinsicMethod() {
v: InstructionAdapter, v: InstructionAdapter,
codegen: ExpressionCodegen, codegen: ExpressionCodegen,
data: BlockInfo, data: BlockInfo,
expression: IrFunctionAccessExpression expression: IrFunctionAccessExpression,
): StackValue { ): StackValue {
with(codegen) { expression.markLineNumber(startOffset = true) } with(codegen) { expression.markLineNumber(startOffset = true) }
v.anew(returnType) v.anew(signature.returnType)
v.dup() v.dup()
return super.invoke(v, codegen, data, expression) return super.invoke(v, codegen, data, expression)
} }
@@ -15,7 +15,7 @@ object RangeUntil : IntrinsicMethod() {
override fun toCallable( override fun toCallable(
expression: IrFunctionAccessExpression, signature: JvmMethodSignature, classCodegen: ClassCodegen expression: IrFunctionAccessExpression, signature: JvmMethodSignature, classCodegen: ClassCodegen
): IrIntrinsicFunction { ): IrIntrinsicFunction {
return object : IrIntrinsicFunction(expression, signature, classCodegen) { return object : IrIntrinsicFunction(expression, signature, classCodegen, expression.argTypes(classCodegen)) {
override fun genInvokeInstruction(v: InstructionAdapter) { override fun genInvokeInstruction(v: InstructionAdapter) {
v.invokestatic( v.invokestatic(
"kotlin/ranges/RangesKt", "until", "kotlin/ranges/RangesKt", "until",
@@ -10,7 +10,7 @@ import org.jetbrains.kotlin.backend.jvm.ir.unwrapInlineLambda
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
object SingleArgumentInlineFunctionIntrinsic : IntrinsicMethod() { object SingleArgumentInlineFunctionIntrinsic : IntrinsicMethod() {
override fun invoke(expression: IrFunctionAccessExpression, codegen: ExpressionCodegen, data: BlockInfo): PromisedValue? { override fun invoke(expression: IrFunctionAccessExpression, codegen: ExpressionCodegen, data: BlockInfo): PromisedValue {
val sourceCompiler = IrSourceCompilerForInline(codegen.state, expression, expression.symbol.owner, codegen, data) val sourceCompiler = IrSourceCompilerForInline(codegen.state, expression, expression.symbol.owner, codegen, data)
val argumentExpression = expression.getValueArgument(0)!! val argumentExpression = expression.getValueArgument(0)!!
val inlineLambda = argumentExpression.unwrapInlineLambda() val inlineLambda = argumentExpression.unwrapInlineLambda()
@@ -22,4 +22,4 @@ object SingleArgumentInlineFunctionIntrinsic : IntrinsicMethod() {
return codegen.unitValue return codegen.unitValue
} }
} }
@@ -21,9 +21,11 @@ import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
object StringGetChar : IntrinsicMethod() { object StringGetChar : IntrinsicMethod() {
override fun toCallable(expression: IrFunctionAccessExpression, signature: JvmMethodSignature, classCodegen: ClassCodegen): IrIntrinsicFunction { override fun toCallable(
expression: IrFunctionAccessExpression, signature: JvmMethodSignature, classCodegen: ClassCodegen,
): IrIntrinsicFunction {
return IrIntrinsicFunction.create(expression, signature, classCodegen) { return IrIntrinsicFunction.create(expression, signature, classCodegen) {
it.invokevirtual("java/lang/String", "charAt", "(I)C", false) it.invokevirtual("java/lang/String", "charAt", "(I)C", false)
} }
} }
} }
@@ -12,7 +12,7 @@ import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
import org.jetbrains.kotlin.resolve.jvm.AsmTypes import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.Type
class ThrowException(val exceptionClass: Type) : IntrinsicMethod() { class ThrowException(private val exceptionClass: Type) : IntrinsicMethod() {
override fun invoke(expression: IrFunctionAccessExpression, codegen: ExpressionCodegen, data: BlockInfo): PromisedValue? { override fun invoke(expression: IrFunctionAccessExpression, codegen: ExpressionCodegen, data: BlockInfo): PromisedValue? {
with(codegen) { with(codegen) {
mv.anew(exceptionClass) mv.anew(exceptionClass)
@@ -24,4 +24,3 @@ class ThrowException(val exceptionClass: Type) : IntrinsicMethod() {
} }
} }
} }
@@ -10,9 +10,7 @@ import org.jetbrains.kotlin.backend.jvm.codegen.ExpressionCodegen
import org.jetbrains.kotlin.backend.jvm.codegen.IrInlineIntrinsicsSupport import org.jetbrains.kotlin.backend.jvm.codegen.IrInlineIntrinsicsSupport
import org.jetbrains.kotlin.backend.jvm.ir.fileParent import org.jetbrains.kotlin.backend.jvm.ir.fileParent
import org.jetbrains.kotlin.codegen.extractUsedReifiedParameters import org.jetbrains.kotlin.codegen.extractUsedReifiedParameters
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner
import org.jetbrains.kotlin.codegen.inline.generateTypeOf import org.jetbrains.kotlin.codegen.inline.generateTypeOf
import org.jetbrains.kotlin.codegen.putReifiedOperationMarkerIfTypeIsReifiedParameter
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
object TypeOf : IntrinsicMethod() { object TypeOf : IntrinsicMethod() {
@@ -22,11 +22,11 @@ import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
object UnaryMinus : IntrinsicMethod() { object UnaryMinus : IntrinsicMethod() {
/*TODO return type*/ override fun toCallable(
override fun toCallable(expression: IrFunctionAccessExpression, signature: JvmMethodSignature, classCodegen: ClassCodegen): IrIntrinsicFunction { expression: IrFunctionAccessExpression, signature: JvmMethodSignature, classCodegen: ClassCodegen,
): IrIntrinsicFunction {
return IrIntrinsicFunction.create(expression, signature, classCodegen) { return IrIntrinsicFunction.create(expression, signature, classCodegen) {
it.neg(numberFunctionOperandType(signature.returnType)) it.neg(numberFunctionOperandType(signature.returnType))
} }
} }
} }
@@ -21,9 +21,11 @@ import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
object UnaryPlus : IntrinsicMethod() { object UnaryPlus : IntrinsicMethod() {
override fun toCallable(expression: IrFunctionAccessExpression, signature: JvmMethodSignature, classCodegen: ClassCodegen): IrIntrinsicFunction { override fun toCallable(
expression: IrFunctionAccessExpression, signature: JvmMethodSignature, classCodegen: ClassCodegen,
): IrIntrinsicFunction {
return IrIntrinsicFunction.create(expression, signature, classCodegen) { return IrIntrinsicFunction.create(expression, signature, classCodegen) {
// Do nothing.
} }
} }
} }