JVM_IR: rework IrIntrinsicMethods
This commit is contained in:
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.PrimitiveType
|
||||
import org.jetbrains.kotlin.builtins.UnsignedType
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.findClassAcrossModuleDependencies
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
@@ -46,6 +47,20 @@ abstract class Symbols<out T : CommonBackendContext>(val context: T, private val
|
||||
protected fun builtInsPackage(vararg packageNameSegments: String) =
|
||||
context.builtIns.builtInsModule.getPackage(FqName.fromSegments(listOf(*packageNameSegments))).memberScope
|
||||
|
||||
private fun getSimpleFunction(
|
||||
name: Name,
|
||||
vararg packageNameSegments: String = arrayOf("kotlin"),
|
||||
condition: (SimpleFunctionDescriptor) -> Boolean
|
||||
): IrSimpleFunctionSymbol =
|
||||
symbolTable.referenceSimpleFunction(
|
||||
builtInsPackage(*packageNameSegments).getContributedFunctions(name, NoLookupLocation.FROM_BACKEND)
|
||||
.first(condition)
|
||||
)
|
||||
|
||||
private fun getClass(name: Name, vararg packageNameSegments: String = arrayOf("kotlin")): IrClassSymbol =
|
||||
symbolTable.referenceClass(
|
||||
builtInsPackage(*packageNameSegments).getContributedClassifier(name, NoLookupLocation.FROM_BACKEND) as ClassDescriptor
|
||||
)
|
||||
|
||||
/**
|
||||
* Use this table to reference external dependencies.
|
||||
@@ -63,21 +78,18 @@ abstract class Symbols<out T : CommonBackendContext>(val context: T, private val
|
||||
|
||||
abstract val defaultConstructorMarker: IrClassSymbol
|
||||
|
||||
val iterator = symbolTable.referenceClass(
|
||||
builtInsPackage("kotlin", "collections").getContributedClassifier(
|
||||
Name.identifier("Iterator"), NoLookupLocation.FROM_BACKEND
|
||||
) as ClassDescriptor
|
||||
)
|
||||
val iterator = getClass(Name.identifier("Iterator"), "kotlin", "collections")
|
||||
|
||||
val primitiveIteratorsByType = PrimitiveType.values().associate { type ->
|
||||
val iteratorClass = getClass(Name.identifier(type.typeName.asString() + "Iterator"), "kotlin", "collections")
|
||||
type to iteratorClass
|
||||
}
|
||||
|
||||
val asserts = builtInsPackage("kotlin")
|
||||
.getContributedFunctions(Name.identifier("assert"), NoLookupLocation.FROM_BACKEND)
|
||||
.map { symbolTable.referenceFunction(it) }
|
||||
|
||||
private fun progression(name: String) = symbolTable.referenceClass(
|
||||
builtInsPackage("kotlin", "ranges").getContributedClassifier(
|
||||
Name.identifier(name), NoLookupLocation.FROM_BACKEND
|
||||
) as ClassDescriptor
|
||||
)
|
||||
private fun progression(name: String) = getClass(Name.identifier(name), "kotlin", "ranges")
|
||||
|
||||
val charProgression = progression("CharProgression")
|
||||
val intProgression = progression("IntProgression")
|
||||
@@ -98,14 +110,23 @@ abstract class Symbols<out T : CommonBackendContext>(val context: T, private val
|
||||
val integerClasses = listOf(byte, short, int, long)
|
||||
val integerClassesTypes = integerClasses.map { it.descriptor.defaultType }
|
||||
|
||||
val arrayOf = symbolTable.referenceSimpleFunction(
|
||||
builtInsPackage("kotlin").getContributedFunctions(
|
||||
Name.identifier("arrayOf"), NoLookupLocation.FROM_BACKEND
|
||||
).first {
|
||||
val arrayOf = getSimpleFunction(Name.identifier("arrayOf")) {
|
||||
it.extensionReceiverParameter == null && it.dispatchReceiverParameter == null && it.valueParameters.size == 1 &&
|
||||
it.valueParameters[0].isVararg
|
||||
}
|
||||
|
||||
val primitiveArrayOfByType = PrimitiveType.values().associate { type ->
|
||||
val function = getSimpleFunction(Name.identifier(type.name.toLowerCase() + "ArrayOf")) {
|
||||
it.extensionReceiverParameter == null && it.dispatchReceiverParameter == null && it.valueParameters.size == 1 &&
|
||||
it.valueParameters[0].isVararg
|
||||
}
|
||||
)
|
||||
type to function
|
||||
}
|
||||
|
||||
val arrayOfNulls = getSimpleFunction(Name.identifier("arrayOfNulls")) {
|
||||
it.extensionReceiverParameter == null && it.dispatchReceiverParameter == null && it.valueParameters.size == 1 &&
|
||||
KotlinBuiltIns.isInt(it.valueParameters[0].type)
|
||||
}
|
||||
|
||||
val array = symbolTable.referenceClass(builtIns.array)
|
||||
|
||||
@@ -134,16 +155,6 @@ abstract class Symbols<out T : CommonBackendContext>(val context: T, private val
|
||||
|
||||
val arrays = primitiveArrays.values + unsignedArrays.values + array
|
||||
|
||||
protected fun arrayExtensionFun(type: KotlinType, name: String): IrSimpleFunctionSymbol {
|
||||
val descriptor = builtInsPackage("kotlin")
|
||||
.getContributedFunctions(Name.identifier(name), NoLookupLocation.FROM_BACKEND)
|
||||
.firstOrNull {
|
||||
it.valueParameters.isEmpty()
|
||||
&& (it.extensionReceiverParameter?.type?.constructor?.declarationDescriptor as? ClassDescriptor)?.defaultType == type
|
||||
} ?: throw Error(type.toString())
|
||||
return symbolTable.referenceSimpleFunction(descriptor)
|
||||
}
|
||||
|
||||
abstract val copyRangeTo: Map<ClassDescriptor, IrSimpleFunctionSymbol>
|
||||
|
||||
abstract val coroutineImpl: IrClassSymbol
|
||||
@@ -152,32 +163,28 @@ abstract class Symbols<out T : CommonBackendContext>(val context: T, private val
|
||||
|
||||
abstract val getContinuation: IrSimpleFunctionSymbol
|
||||
|
||||
private val binaryOperatorCache = mutableMapOf<Triple<Name, KotlinType, KotlinType>, IrFunctionSymbol>()
|
||||
private val binaryOperatorCache = mutableMapOf<Triple<Name, KotlinType, KotlinType>, IrSimpleFunctionSymbol>()
|
||||
|
||||
fun getBinaryOperator(name: Name, lhsType: KotlinType, rhsType: KotlinType): IrFunctionSymbol {
|
||||
fun getBinaryOperator(name: Name, lhsType: KotlinType, rhsType: KotlinType): IrSimpleFunctionSymbol {
|
||||
val key = Triple(name, lhsType, rhsType)
|
||||
var result = binaryOperatorCache[key]
|
||||
if (result == null) {
|
||||
result = symbolTable.referenceFunction(lhsType.memberScope.getContributedFunctions(name, NoLookupLocation.FROM_BACKEND)
|
||||
.first { it.valueParameters.size == 1 && it.valueParameters[0].type == rhsType }
|
||||
return binaryOperatorCache.getOrPut(key) {
|
||||
symbolTable.referenceSimpleFunction(
|
||||
lhsType.memberScope.getContributedFunctions(name, NoLookupLocation.FROM_BACKEND)
|
||||
.first { it.valueParameters.size == 1 && it.valueParameters[0].type == rhsType }
|
||||
)
|
||||
binaryOperatorCache[key] = result
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private val unaryOperatorCache = mutableMapOf<Pair<Name, KotlinType>, IrFunctionSymbol>()
|
||||
private val unaryOperatorCache = mutableMapOf<Pair<Name, KotlinType>, IrSimpleFunctionSymbol>()
|
||||
|
||||
fun getUnaryOperator(name: Name, receiverType: KotlinType): IrFunctionSymbol {
|
||||
fun getUnaryOperator(name: Name, receiverType: KotlinType): IrSimpleFunctionSymbol {
|
||||
val key = name to receiverType
|
||||
var result = unaryOperatorCache[key]
|
||||
if (result == null) {
|
||||
result = symbolTable.referenceFunction(receiverType.memberScope.getContributedFunctions(name, NoLookupLocation.FROM_BACKEND)
|
||||
.first { it.valueParameters.isEmpty() }
|
||||
return unaryOperatorCache.getOrPut(key) {
|
||||
symbolTable.referenceSimpleFunction(
|
||||
receiverType.memberScope.getContributedFunctions(name, NoLookupLocation.FROM_BACKEND)
|
||||
.first { it.valueParameters.isEmpty() }
|
||||
)
|
||||
unaryOperatorCache[key] = result
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
val intAnd = getBinaryOperator(OperatorNameConventions.AND, builtIns.intType, builtIns.intType)
|
||||
@@ -186,6 +193,17 @@ abstract class Symbols<out T : CommonBackendContext>(val context: T, private val
|
||||
fun functionN(n: Int): IrClassSymbol = symbolTable.referenceClass(builtIns.getFunction(n))
|
||||
fun suspendFunctionN(n: Int): IrClassSymbol = symbolTable.referenceClass(builtIns.getSuspendFunction(n))
|
||||
|
||||
val extensionToString = getSimpleFunction(Name.identifier("toString")) {
|
||||
it.dispatchReceiverParameter == null && it.extensionReceiverParameter != null &&
|
||||
KotlinBuiltIns.isNullableAny(it.extensionReceiverParameter!!.type) && it.valueParameters.size == 0
|
||||
}
|
||||
|
||||
val stringPlus = getSimpleFunction(Name.identifier("plus")) {
|
||||
it.dispatchReceiverParameter == null && it.extensionReceiverParameter != null &&
|
||||
KotlinBuiltIns.isStringOrNullableString(it.extensionReceiverParameter!!.type) && it.valueParameters.size == 1 &&
|
||||
KotlinBuiltIns.isNullableAny(it.valueParameters.first().type)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun isLateinitIsInitializedPropertyGetter(symbol: IrFunctionSymbol): Boolean =
|
||||
symbol is IrSimpleFunctionSymbol && symbol.owner.let { function ->
|
||||
|
||||
@@ -39,7 +39,7 @@ class JvmBackendContext(
|
||||
private val symbolTable = symbolTable.lazyWrapper
|
||||
override val ir = JvmIr(irModuleFragment, this.symbolTable)
|
||||
|
||||
val irIntrinsics = IrIntrinsicMethods(irBuiltIns)
|
||||
val irIntrinsics = IrIntrinsicMethods(irBuiltIns, ir.symbols)
|
||||
|
||||
override var inVerbosePhase: Boolean = false
|
||||
|
||||
|
||||
@@ -6,23 +6,27 @@
|
||||
package org.jetbrains.kotlin.backend.jvm
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.ir.Symbols
|
||||
import org.jetbrains.kotlin.backend.common.ir.addChild
|
||||
import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.descriptors.impl.EmptyPackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.declarations.IrPackageFragment
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrExternalPackageFragmentImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrExternalPackageFragmentSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.defaultType
|
||||
import org.jetbrains.kotlin.ir.types.typeWith
|
||||
import org.jetbrains.kotlin.ir.util.ReferenceSymbolTable
|
||||
import org.jetbrains.kotlin.ir.util.defaultType
|
||||
import org.jetbrains.kotlin.ir.util.functions
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
@@ -49,7 +53,10 @@ class JvmSymbols(
|
||||
private fun createPackage(fqName: FqName): IrPackageFragment =
|
||||
IrExternalPackageFragmentImpl(IrExternalPackageFragmentSymbolImpl(EmptyPackageFragmentDescriptor(context.state.module, fqName)))
|
||||
|
||||
private val kotlinPackage: IrPackageFragment = createPackage(FqName("kotlin"))
|
||||
private val kotlinJvmPackage: IrPackageFragment = createPackage(FqName("kotlin.jvm"))
|
||||
private val kotlinJvmInternalPackage: IrPackageFragment = createPackage(FqName("kotlin.jvm.internal"))
|
||||
private val kotlinJvmInternalUnsafePackage: IrPackageFragment = createPackage(FqName("kotlin.jvm.internal.unsafe"))
|
||||
private val kotlinJvmFunctionsPackage: IrPackageFragment = createPackage(FqName("kotlin.jvm.functions"))
|
||||
|
||||
private fun createClass(fqName: FqName, classKind: ClassKind = ClassKind.CLASS, block: (IrClass) -> Unit): IrClass =
|
||||
@@ -254,4 +261,47 @@ class JvmSymbols(
|
||||
|
||||
val getOrCreateKotlinClasses: IrSimpleFunctionSymbol =
|
||||
reflection.functions.single { it.owner.name.asString() == "getOrCreateKotlinClasses" }
|
||||
|
||||
val javaClassProperty: IrPropertySymbol = kotlinJvmPackage.addProperty {
|
||||
name = Name.identifier("javaClass")
|
||||
}.apply {
|
||||
addGetter().apply {
|
||||
val typeParameter = addTypeParameter {
|
||||
name = Name.identifier("T")
|
||||
}.apply {
|
||||
superTypes.add(irBuiltIns.anyType)
|
||||
}
|
||||
addExtensionReceiver(typeParameter.defaultType)
|
||||
returnType = javaLangClass.typeWith(typeParameter.defaultType)
|
||||
}
|
||||
}.symbol
|
||||
|
||||
val kClassJavaProperty: IrPropertySymbol = kotlinJvmPackage.addProperty {
|
||||
name = Name.identifier("java")
|
||||
}.apply {
|
||||
addGetter().apply {
|
||||
val extensionReceiverType = irBuiltIns.kClassClass.typeWith()
|
||||
addExtensionReceiver(extensionReceiverType)
|
||||
returnType = javaLangClass.typeWith(extensionReceiverType)
|
||||
}
|
||||
}.symbol
|
||||
|
||||
val monitorEnter = kotlinJvmInternalUnsafePackage.addFunction("monitorEnter", irBuiltIns.unitType, isStatic = true).apply {
|
||||
addValueParameter("monitor", irBuiltIns.anyType)
|
||||
}.symbol
|
||||
|
||||
val monitorExit = kotlinJvmInternalUnsafePackage.addFunction("monitorExit", irBuiltIns.unitType, isStatic = true).apply {
|
||||
addValueParameter("monitor", irBuiltIns.anyType)
|
||||
}.symbol
|
||||
|
||||
val isArrayOf = kotlinJvmPackage.addFunction("isArrayOf", irBuiltIns.booleanType, isStatic = true).apply {
|
||||
addExtensionReceiver(irBuiltIns.arrayClass.owner.defaultType)
|
||||
addTypeParameter("T", irBuiltIns.anyNType)
|
||||
}.symbol
|
||||
|
||||
// We cannot create Cloneable reference out of thin air, since we have to preserve the information that it is a Java interface and
|
||||
// it has no DefaultImpls counterpart.
|
||||
val cloneable = symbolTable.referenceClass(
|
||||
builtInsPackage("kotlin").getContributedClassifier(Name.identifier("Cloneable"), NoLookupLocation.FROM_BACKEND) as ClassDescriptor
|
||||
)
|
||||
}
|
||||
|
||||
+1
-1
@@ -302,7 +302,7 @@ class ExpressionCodegen(
|
||||
}
|
||||
|
||||
private fun generateCall(expression: IrFunctionAccessExpression, superQualifier: ClassDescriptor?, data: BlockInfo): PromisedValue {
|
||||
classCodegen.context.irIntrinsics.getIntrinsic(expression.descriptor.original as CallableMemberDescriptor)
|
||||
classCodegen.context.irIntrinsics.getIntrinsic(expression.symbol)
|
||||
?.invoke(expression, this, data)?.let { return it.coerce(expression.asmType) }
|
||||
val isSuperCall = superQualifier != null
|
||||
val callable = resolveToCallable(expression, isSuperCall)
|
||||
|
||||
+2
-2
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.BlockInfo
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.ExpressionCodegen
|
||||
import org.jetbrains.kotlin.codegen.StackValue
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
@@ -28,7 +28,7 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
|
||||
object ArrayConstructor : IntrinsicMethod() {
|
||||
override fun toCallable(
|
||||
expression: IrMemberAccessExpression,
|
||||
expression: IrFunctionAccessExpression,
|
||||
signature: JvmMethodSignature,
|
||||
context: JvmBackendContext
|
||||
): IrIntrinsicFunction {
|
||||
|
||||
@@ -18,12 +18,13 @@ package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
|
||||
class ArrayGet : IntrinsicMethod() {
|
||||
override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
object ArrayGet : IntrinsicMethod() {
|
||||
override fun toCallable(expression: IrFunctionAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
val arrayType = calcReceiverType(expression, context)
|
||||
val elementType = AsmUtil.correctElementType(arrayType)
|
||||
return IrIntrinsicFunction.create(expression, signature.newReturnType(elementType), context, listOf(arrayType, Type.INT_TYPE)) {
|
||||
|
||||
+3
-2
@@ -19,11 +19,12 @@ package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
|
||||
class ArrayIterator : IntrinsicMethod() {
|
||||
override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
object ArrayIterator : IntrinsicMethod() {
|
||||
override fun toCallable(expression: IrFunctionAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
val method = context.state.typeMapper.mapToCallableMethod(expression.descriptor as FunctionDescriptor, false)
|
||||
return IrIntrinsicFunction.create(expression, signature, context, method.owner) {
|
||||
val methodSignature = "(${method.owner.descriptor})${method.returnType.descriptor}"
|
||||
|
||||
@@ -17,11 +17,11 @@
|
||||
package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
|
||||
class ArrayOf : IntrinsicMethod() {
|
||||
override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
object ArrayOf : IntrinsicMethod() {
|
||||
override fun toCallable(expression: IrFunctionAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
return IrIntrinsicFunction.create(expression, signature, context, signature.returnType) {
|
||||
//do nothing all generated as vararg
|
||||
}
|
||||
|
||||
@@ -18,13 +18,14 @@ package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
|
||||
class ArraySet : IntrinsicMethod() {
|
||||
object ArraySet : IntrinsicMethod() {
|
||||
|
||||
override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
override fun toCallable(expression: IrFunctionAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
val arrayType = expressionType(expression.dispatchReceiver!!, context)
|
||||
val elementType = AsmUtil.correctElementType(arrayType)
|
||||
return IrIntrinsicFunction.create(expression, signature, context, listOf(arrayType, Type.INT_TYPE, elementType)) {
|
||||
|
||||
+3
-2
@@ -17,12 +17,13 @@
|
||||
package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
|
||||
class ArraySize : IntrinsicMethod() {
|
||||
object ArraySize : IntrinsicMethod() {
|
||||
|
||||
override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
override fun toCallable(expression: IrFunctionAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
return IrIntrinsicFunction.create(expression, signature, context) {
|
||||
it.arraylength()
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil.numberFunctionOperandType
|
||||
import org.jetbrains.kotlin.codegen.StackValue
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes.*
|
||||
@@ -28,7 +29,7 @@ class BinaryOp(private val opcode: Int) : IntrinsicMethod() {
|
||||
private fun shift(): Boolean =
|
||||
opcode == ISHL || opcode == ISHR || opcode == IUSHR
|
||||
|
||||
override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
override fun toCallable(expression: IrFunctionAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
val owner = context.state.typeMapper.mapOwner(expression.descriptor)
|
||||
val returnType = signature.returnType
|
||||
val intermediateResultType: Type = numberFunctionOperandType(returnType)
|
||||
|
||||
@@ -18,14 +18,15 @@ package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
|
||||
class Clone : IntrinsicMethod() {
|
||||
object Clone : IntrinsicMethod() {
|
||||
|
||||
override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
override fun toCallable(expression: IrFunctionAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
return IrIntrinsicFunction.create(expression, signature.newReturnType(AsmTypes.OBJECT_TYPE), context) {
|
||||
val opcode = if (expression is IrCall && expression.superQualifier != null) Opcodes.INVOKESPECIAL else Opcodes.INVOKEVIRTUAL
|
||||
it.visitMethodInsn(opcode, "java/lang/Object", "clone", "()Ljava/lang/Object;", false)
|
||||
|
||||
+4
-5
@@ -24,7 +24,6 @@ import org.jetbrains.kotlin.codegen.BranchedValue
|
||||
import org.jetbrains.kotlin.codegen.NumberCompare
|
||||
import org.jetbrains.kotlin.codegen.ObjectCompare
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.lexer.KtSingleValueToken
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
@@ -33,17 +32,17 @@ import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
import java.lang.UnsupportedOperationException
|
||||
|
||||
class CompareTo : IntrinsicMethod() {
|
||||
object CompareTo : IntrinsicMethod() {
|
||||
private fun genInvoke(type: Type?, v: InstructionAdapter) {
|
||||
when (type) {
|
||||
Type.CHAR_TYPE, Type.BYTE_TYPE, Type.SHORT_TYPE, Type.INT_TYPE ->
|
||||
v.invokestatic(
|
||||
IntrinsicMethods.INTRINSICS_CLASS_NAME,
|
||||
IrIntrinsicMethods.INTRINSICS_CLASS_NAME,
|
||||
"compare",
|
||||
"(II)I",
|
||||
false
|
||||
)
|
||||
Type.LONG_TYPE -> v.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, "compare", "(JJ)I", false)
|
||||
Type.LONG_TYPE -> v.invokestatic(IrIntrinsicMethods.INTRINSICS_CLASS_NAME, "compare", "(JJ)I", false)
|
||||
Type.FLOAT_TYPE -> v.invokestatic("java/lang/Float", "compare", "(FF)I", false)
|
||||
Type.DOUBLE_TYPE -> v.invokestatic("java/lang/Double", "compare", "(DD)I", false)
|
||||
else -> throw UnsupportedOperationException()
|
||||
@@ -51,7 +50,7 @@ class CompareTo : IntrinsicMethod() {
|
||||
}
|
||||
|
||||
override fun toCallable(
|
||||
expression: IrMemberAccessExpression,
|
||||
expression: IrFunctionAccessExpression,
|
||||
signature: JvmMethodSignature,
|
||||
context: JvmBackendContext
|
||||
): IrIntrinsicFunction {
|
||||
|
||||
@@ -61,7 +61,7 @@ class Ieee754Equals(val operandType: Type) : IntrinsicMethod() {
|
||||
private val boxedOperandType = AsmUtil.boxType(operandType)
|
||||
|
||||
override fun toCallable(
|
||||
expression: IrMemberAccessExpression,
|
||||
expression: IrFunctionAccessExpression,
|
||||
signature: JvmMethodSignature,
|
||||
context: JvmBackendContext
|
||||
): IrIntrinsicFunction {
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.kotlin.codegen.Callable
|
||||
import org.jetbrains.kotlin.codegen.CallableMethod
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
@@ -28,9 +29,9 @@ import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
|
||||
class HashCode : IntrinsicMethod() {
|
||||
object HashCode : IntrinsicMethod() {
|
||||
|
||||
override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
override fun toCallable(expression: IrFunctionAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
return IrIntrinsicFunction.create(expression, signature, context, AsmTypes.OBJECT_TYPE) {
|
||||
it.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "hashCode", "()I", false)
|
||||
}
|
||||
|
||||
+2
-1
@@ -18,11 +18,12 @@ package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil.genIncrement
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
|
||||
class Increment(private val myDelta: Int) : IntrinsicMethod() {
|
||||
override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
override fun toCallable(expression: IrFunctionAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
return IrIntrinsicFunction.create(expression, signature, context) {
|
||||
genIncrement(signature.returnType, myDelta, it)
|
||||
}
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ import org.jetbrains.org.objectweb.asm.commons.Method
|
||||
|
||||
abstract class IntrinsicMethod {
|
||||
open fun toCallable(
|
||||
expression: IrMemberAccessExpression,
|
||||
expression: IrFunctionAccessExpression,
|
||||
signature: JvmMethodSignature,
|
||||
context: JvmBackendContext
|
||||
): IrIntrinsicFunction = TODO("implement toCallable() or invoke() of $this")
|
||||
|
||||
-181
@@ -1,181 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2016 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.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.intrinsics;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import kotlin.text.StringsKt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
import org.jetbrains.kotlin.builtins.PrimitiveType;
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor;
|
||||
import org.jetbrains.kotlin.lexer.KtTokens;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.name.FqNameUnsafe;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes;
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType;
|
||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
|
||||
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.*;
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
||||
|
||||
public class IntrinsicMethods {
|
||||
public static final String INTRINSICS_CLASS_NAME = "kotlin/jvm/internal/Intrinsics";
|
||||
|
||||
private static final FqName KOTLIN_JVM = new FqName("kotlin.jvm");
|
||||
/* package */ static final FqNameUnsafe RECEIVER_PARAMETER_FQ_NAME = new FqNameUnsafe("T");
|
||||
|
||||
private static final IntrinsicMethod UNARY_MINUS = new UnaryMinus();
|
||||
private static final IntrinsicMethod UNARY_PLUS = new UnaryPlus();
|
||||
private static final IntrinsicMethod NUMBER_CAST = new NumberCast();
|
||||
private static final IntrinsicMethod INV = new Inv();
|
||||
private static final IntrinsicMethod RANGE_TO = new RangeTo();
|
||||
private static final IntrinsicMethod INC = new Increment(1);
|
||||
private static final IntrinsicMethod DEC = new Increment(-1);
|
||||
private static final IntrinsicMethod HASH_CODE = new HashCode();
|
||||
|
||||
private static final IntrinsicMethod ARRAY_SIZE = new ArraySize();
|
||||
private static final Equals EQUALS = new Equals(KtTokens.EQEQ);
|
||||
private static final IteratorNext ITERATOR_NEXT = new IteratorNext();
|
||||
private static final ArraySet ARRAY_SET = new ArraySet();
|
||||
private static final ArrayGet ARRAY_GET = new ArrayGet();
|
||||
private static final ToString TO_STRING = new ToString();
|
||||
private static final Clone CLONE = new Clone();
|
||||
|
||||
private static final IntrinsicMethod ARRAY_ITERATOR = new ArrayIterator();
|
||||
private final IntrinsicsMap intrinsicsMap = new IntrinsicsMap();
|
||||
|
||||
public IntrinsicMethods() {
|
||||
intrinsicsMap.registerIntrinsic(KOTLIN_JVM, RECEIVER_PARAMETER_FQ_NAME, "javaClass", -1, JavaClassProperty.INSTANCE);
|
||||
intrinsicsMap.registerIntrinsic(KOTLIN_JVM, KotlinBuiltIns.FQ_NAMES.kClass, "java", -1, new KClassJavaProperty());
|
||||
intrinsicsMap.registerIntrinsic(new FqName("kotlin.jvm.internal.unsafe"), null, "monitorEnter", 1, MonitorInstruction.MONITOR_ENTER);
|
||||
intrinsicsMap.registerIntrinsic(new FqName("kotlin.jvm.internal.unsafe"), null, "monitorExit", 1, MonitorInstruction.MONITOR_EXIT);
|
||||
intrinsicsMap.registerIntrinsic(KOTLIN_JVM, KotlinBuiltIns.FQ_NAMES.array, "isArrayOf", 0, new IsArrayOf());
|
||||
|
||||
intrinsicsMap.registerIntrinsic(BUILT_INS_PACKAGE_FQ_NAME, null, "arrayOf", 1, new ArrayOf());
|
||||
|
||||
ImmutableList<Name> primitiveCastMethods = OperatorConventions.NUMBER_CONVERSIONS.asList();
|
||||
for (Name method : primitiveCastMethods) {
|
||||
String methodName = method.asString();
|
||||
declareIntrinsicFunction(FQ_NAMES.number, methodName, 0, NUMBER_CAST);
|
||||
for (PrimitiveType type : PrimitiveType.NUMBER_TYPES) {
|
||||
declareIntrinsicFunction(type.getTypeFqName(), methodName, 0, NUMBER_CAST);
|
||||
}
|
||||
}
|
||||
|
||||
for (PrimitiveType type : PrimitiveType.NUMBER_TYPES) {
|
||||
FqName typeFqName = type.getTypeFqName();
|
||||
declareIntrinsicFunction(typeFqName, "plus", 0, UNARY_PLUS);
|
||||
declareIntrinsicFunction(typeFqName, "unaryPlus", 0, UNARY_PLUS);
|
||||
declareIntrinsicFunction(typeFqName, "minus", 0, UNARY_MINUS);
|
||||
declareIntrinsicFunction(typeFqName, "unaryMinus", 0, UNARY_MINUS);
|
||||
declareIntrinsicFunction(typeFqName, "inv", 0, INV);
|
||||
declareIntrinsicFunction(typeFqName, "rangeTo", 1, RANGE_TO);
|
||||
declareIntrinsicFunction(typeFqName, "inc", 0, INC);
|
||||
declareIntrinsicFunction(typeFqName, "dec", 0, DEC);
|
||||
}
|
||||
|
||||
for (PrimitiveType type : PrimitiveType.values()) {
|
||||
FqName typeFqName = type.getTypeFqName();
|
||||
Type asmPrimitiveType = AsmTypes.valueTypeForPrimitive(type);
|
||||
declareIntrinsicFunction(typeFqName, "equals", 1, EQUALS);
|
||||
declareIntrinsicFunction(typeFqName, "hashCode", 0, HASH_CODE);
|
||||
declareIntrinsicFunction(typeFqName, "toString", 0, TO_STRING);
|
||||
|
||||
intrinsicsMap.registerIntrinsic(
|
||||
BUILT_INS_PACKAGE_FQ_NAME, null, StringsKt.decapitalize(type.getArrayTypeName().asString()) + "Of", 1, new ArrayOf()
|
||||
);
|
||||
}
|
||||
|
||||
declareBinaryOp("plus", IADD);
|
||||
declareBinaryOp("minus", ISUB);
|
||||
declareBinaryOp("times", IMUL);
|
||||
declareBinaryOp("div", IDIV);
|
||||
declareBinaryOp("mod", IREM);
|
||||
declareBinaryOp("rem", IREM);
|
||||
declareBinaryOp("shl", ISHL);
|
||||
declareBinaryOp("shr", ISHR);
|
||||
declareBinaryOp("ushr", IUSHR);
|
||||
declareBinaryOp("and", IAND);
|
||||
declareBinaryOp("or", IOR);
|
||||
declareBinaryOp("xor", IXOR);
|
||||
|
||||
declareIntrinsicFunction(FQ_NAMES._boolean, "not", 0, new Not());
|
||||
|
||||
declareIntrinsicFunction(FQ_NAMES.string, "get", 1, new StringGetChar());
|
||||
|
||||
declareIntrinsicFunction(FQ_NAMES.cloneable, "clone", 0, CLONE);
|
||||
|
||||
intrinsicsMap.registerIntrinsic(BUILT_INS_PACKAGE_FQ_NAME, KotlinBuiltIns.FQ_NAMES.any, "toString", 0, TO_STRING);
|
||||
intrinsicsMap.registerIntrinsic(BUILT_INS_PACKAGE_FQ_NAME, null, "arrayOfNulls", 1, new NewArray());
|
||||
|
||||
for (PrimitiveType type : PrimitiveType.values()) {
|
||||
declareIntrinsicFunction(type.getTypeFqName(), "compareTo", 1, new CompareTo());
|
||||
declareIntrinsicFunction(COLLECTIONS_PACKAGE_FQ_NAME.child(Name.identifier(type.getTypeName().asString() + "Iterator")), "next", 0, ITERATOR_NEXT);
|
||||
}
|
||||
|
||||
declareArrayMethods();
|
||||
}
|
||||
|
||||
private void declareArrayMethods() {
|
||||
for (JvmPrimitiveType jvmPrimitiveType : JvmPrimitiveType.values()) {
|
||||
declareArrayMethods(jvmPrimitiveType.getPrimitiveType().getArrayTypeFqName());
|
||||
}
|
||||
declareArrayMethods(FQ_NAMES.array.toSafe());
|
||||
}
|
||||
|
||||
private void declareArrayMethods(@NotNull FqName arrayTypeFqName) {
|
||||
declareIntrinsicFunction(arrayTypeFqName, "size", -1, ARRAY_SIZE);
|
||||
declareIntrinsicFunction(arrayTypeFqName, "set", 2, ARRAY_SET);
|
||||
declareIntrinsicFunction(arrayTypeFqName, "get", 1, ARRAY_GET);
|
||||
declareIntrinsicFunction(arrayTypeFqName, "clone", 0, CLONE);
|
||||
declareIntrinsicFunction(arrayTypeFqName, "iterator", 0, ARRAY_ITERATOR);
|
||||
declareIntrinsicFunction(arrayTypeFqName, "<init>", 2, ArrayConstructor.INSTANCE);
|
||||
}
|
||||
|
||||
private void declareBinaryOp(@NotNull String methodName, int opcode) {
|
||||
BinaryOp op = new BinaryOp(opcode);
|
||||
for (PrimitiveType type : PrimitiveType.values()) {
|
||||
declareIntrinsicFunction(type.getTypeFqName(), methodName, 1, op);
|
||||
}
|
||||
}
|
||||
|
||||
private void declareIntrinsicFunction(
|
||||
@NotNull FqName classFqName,
|
||||
@NotNull String methodName,
|
||||
int arity,
|
||||
@NotNull IntrinsicMethod implementation
|
||||
) {
|
||||
intrinsicsMap.registerIntrinsic(classFqName, null, methodName, arity, implementation);
|
||||
}
|
||||
|
||||
private void declareIntrinsicFunction(
|
||||
@NotNull FqNameUnsafe classFqName,
|
||||
@NotNull String methodName,
|
||||
int arity,
|
||||
@NotNull IntrinsicMethod implementation
|
||||
) {
|
||||
intrinsicsMap.registerIntrinsic(classFqName.toSafe(), null, methodName, arity, implementation);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public IntrinsicMethod getIntrinsic(@NotNull CallableMemberDescriptor descriptor) {
|
||||
return intrinsicsMap.getIntrinsic(descriptor);
|
||||
}
|
||||
}
|
||||
-118
@@ -1,118 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2016 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.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.intrinsics;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.name.FqNameUnsafe;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
class IntrinsicsMap {
|
||||
private static final class Key {
|
||||
private final FqNameUnsafe owner;
|
||||
private final FqNameUnsafe receiverParameter;
|
||||
private final String name;
|
||||
private final int valueParameterCount;
|
||||
|
||||
private Key(@NotNull FqNameUnsafe owner, @Nullable FqNameUnsafe receiverParameter, @NotNull String name, int valueParameterCount) {
|
||||
this.owner = owner;
|
||||
this.receiverParameter = receiverParameter;
|
||||
this.name = name;
|
||||
this.valueParameterCount = valueParameterCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
Key key = (Key) o;
|
||||
|
||||
if (valueParameterCount != key.valueParameterCount) return false;
|
||||
if (!name.equals(key.name)) return false;
|
||||
if (!owner.equals(key.owner)) return false;
|
||||
if (receiverParameter == null ? key.receiverParameter != null : !receiverParameter.equals(key.receiverParameter)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = owner.hashCode();
|
||||
result = 31 * result + name.hashCode();
|
||||
result = 31 * result + valueParameterCount;
|
||||
result = 31 * result + (receiverParameter != null ? receiverParameter.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
private static int valueParameterCountForKey(@NotNull CallableMemberDescriptor member) {
|
||||
if (member instanceof PropertyDescriptor) {
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
return member.getValueParameters().size();
|
||||
}
|
||||
}
|
||||
|
||||
private final Map<Key, IntrinsicMethod> intrinsicsMap = new HashMap<>();
|
||||
|
||||
|
||||
/**
|
||||
* @param valueParameterCount -1 for property
|
||||
*/
|
||||
public void registerIntrinsic(
|
||||
@NotNull FqName owner,
|
||||
@Nullable FqNameUnsafe receiverParameter,
|
||||
@NotNull String name,
|
||||
int valueParameterCount,
|
||||
@NotNull IntrinsicMethod impl
|
||||
) {
|
||||
intrinsicsMap.put(new Key(owner.toUnsafe(), receiverParameter, name, valueParameterCount), impl);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public IntrinsicMethod getIntrinsic(@NotNull CallableMemberDescriptor descriptor) {
|
||||
Key key = new Key(
|
||||
DescriptorUtils.getFqName(descriptor.getContainingDeclaration()),
|
||||
getReceiverParameterFqName(descriptor),
|
||||
descriptor.getName().asString(),
|
||||
valueParameterCountForKey(descriptor)
|
||||
);
|
||||
return intrinsicsMap.get(key);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static FqNameUnsafe getReceiverParameterFqName(@NotNull CallableMemberDescriptor descriptor) {
|
||||
ReceiverParameterDescriptor receiverParameter = descriptor.getExtensionReceiverParameter();
|
||||
if (receiverParameter == null) return null;
|
||||
|
||||
ClassifierDescriptor classifier = receiverParameter.getType().getConstructor().getDeclarationDescriptor();
|
||||
if (classifier == null) return null;
|
||||
|
||||
if (classifier instanceof TypeParameterDescriptor) {
|
||||
return IntrinsicMethods.RECEIVER_PARAMETER_FQ_NAME;
|
||||
}
|
||||
|
||||
return DescriptorUtils.getFqName(classifier);
|
||||
}
|
||||
}
|
||||
@@ -18,13 +18,14 @@ package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil.numberFunctionOperandType
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
|
||||
class Inv : IntrinsicMethod() {
|
||||
object Inv : IntrinsicMethod() {
|
||||
/*TODO new this type*/
|
||||
override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
override fun toCallable(expression: IrFunctionAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
val returnType = signature.returnType
|
||||
val type = numberFunctionOperandType(returnType)
|
||||
return IrIntrinsicFunction.create(expression, signature, context, type) {
|
||||
|
||||
+3
-2
@@ -22,13 +22,14 @@ import org.jetbrains.kotlin.backend.jvm.codegen.ExpressionCodegen
|
||||
import org.jetbrains.kotlin.codegen.OwnerKind
|
||||
import org.jetbrains.kotlin.codegen.StackValue
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
|
||||
class IrEnumValueOf : IntrinsicMethod() {
|
||||
override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
object IrEnumValueOf : IntrinsicMethod() {
|
||||
override fun toCallable(expression: IrFunctionAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
val enumType = context.state.typeMapper.mapType(expression.descriptor.returnType!!)
|
||||
val newSignature = context.state.typeMapper.mapSignatureSkipGeneric(expression.descriptor as FunctionDescriptor, OwnerKind.IMPLEMENTATION)
|
||||
val stringType = AsmTypes.JAVA_STRING_TYPE;
|
||||
|
||||
+3
-2
@@ -20,17 +20,18 @@ import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.BlockInfo
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.ExpressionCodegen
|
||||
import org.jetbrains.kotlin.codegen.StackValue
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.JAVA_STRING_TYPE
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
|
||||
class IrIllegalArgumentException : IntrinsicMethod() {
|
||||
object IrIllegalArgumentException : IntrinsicMethod() {
|
||||
val exceptionTypeDescriptor = Type.getType(IllegalArgumentException::class.java)!!
|
||||
|
||||
override fun toCallable(
|
||||
expression: IrMemberAccessExpression,
|
||||
expression: IrFunctionAccessExpression,
|
||||
signature: JvmMethodSignature,
|
||||
context: JvmBackendContext
|
||||
): IrIntrinsicFunction {
|
||||
|
||||
+149
-38
@@ -16,59 +16,170 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmSymbols
|
||||
import org.jetbrains.kotlin.builtins.PrimitiveType
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrPackageFragment
|
||||
import org.jetbrains.kotlin.ir.declarations.IrTypeParameter
|
||||
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
|
||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrSimpleType
|
||||
import org.jetbrains.kotlin.ir.types.classOrNull
|
||||
import org.jetbrains.kotlin.ir.util.constructors
|
||||
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
|
||||
import org.jetbrains.kotlin.ir.util.functions
|
||||
import org.jetbrains.kotlin.ir.util.properties
|
||||
import org.jetbrains.kotlin.lexer.KtSingleValueToken
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.types.SimpleType
|
||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes.*
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
|
||||
class IrIntrinsicMethods(irBuiltIns: IrBuiltIns) {
|
||||
|
||||
val intrinsics = IntrinsicMethods()
|
||||
class IrIntrinsicMethods(val irBuiltIns: IrBuiltIns, val symbols: JvmSymbols) {
|
||||
|
||||
val andandSymbol = irBuiltIns.run { defineOperator(OperatorNames.ANDAND, bool, listOf(bool, bool)) }
|
||||
|
||||
private val andand = andandSymbol.descriptor
|
||||
private val intrinsicsMap = (
|
||||
listOf(
|
||||
symbols.javaClassProperty.owner.getter!!.symbol.toKey() to JavaClassProperty,
|
||||
symbols.kClassJavaProperty.owner.getter!!.symbol.toKey() to KClassJavaProperty,
|
||||
symbols.monitorEnter.toKey() to MonitorInstruction.MONITOR_ENTER,
|
||||
symbols.monitorExit.toKey() to MonitorInstruction.MONITOR_EXIT,
|
||||
symbols.isArrayOf.toKey() to IsArrayOf,
|
||||
symbols.arrayOf.toKey() to ArrayOf,
|
||||
symbols.extensionToString.toKey() to ToString,
|
||||
symbols.arrayOfNulls.toKey() to NewArray,
|
||||
irBuiltIns.eqeqSymbol.toKey()!! to Equals(KtTokens.EQEQ),
|
||||
irBuiltIns.eqeqeqSymbol.toKey()!! to Equals(KtTokens.EQEQEQ),
|
||||
irBuiltIns.ieee754equalsFunByOperandType[irBuiltIns.float]!!.toKey()!! to Ieee754Equals(Type.FLOAT_TYPE),
|
||||
irBuiltIns.ieee754equalsFunByOperandType[irBuiltIns.double]!!.toKey()!! to Ieee754Equals(Type.DOUBLE_TYPE),
|
||||
irBuiltIns.booleanNotSymbol.toKey()!! to Not,
|
||||
irBuiltIns.enumValueOfSymbol.toKey()!! to IrEnumValueOf,
|
||||
irBuiltIns.noWhenBranchMatchedExceptionSymbol.toKey()!! to IrNoWhenBranchMatchedException,
|
||||
irBuiltIns.illegalArgumentExceptionSymbol.toKey()!! to IrIllegalArgumentException,
|
||||
irBuiltIns.throwNpeSymbol.toKey()!! to ThrowNPE,
|
||||
andandSymbol.toKey() to AndAnd
|
||||
) +
|
||||
numberConversionMethods() +
|
||||
unaryFunForPrimitives("plus", UnaryPlus) +
|
||||
unaryFunForPrimitives("unaryPlus", UnaryPlus) +
|
||||
unaryFunForPrimitives("minus", UnaryMinus) +
|
||||
unaryFunForPrimitives("unaryMinus", UnaryMinus) +
|
||||
unaryFunForPrimitives("inv", Inv) +
|
||||
unaryFunForPrimitives("inc", INC) +
|
||||
unaryFunForPrimitives("dec", DEC) +
|
||||
unaryFunForPrimitives("hashCode", HashCode) +
|
||||
unaryFunForPrimitives("toString", ToString) +
|
||||
binaryFunForPrimitives("equals", EQUALS) +
|
||||
symbols.primitiveArrayOfByType.values.map { it.toKey() to ArrayOf } +
|
||||
binaryFunForPrimitives("rangeTo", RangeTo) +
|
||||
binaryOp("plus", IADD) +
|
||||
binaryOp("minus", ISUB) +
|
||||
binaryOp("times", IMUL) +
|
||||
binaryOp("div", IDIV) +
|
||||
binaryOp("mod", IREM) +
|
||||
binaryOp("rem", IREM) +
|
||||
binaryOp("shl", ISHL) +
|
||||
binaryOp("shr", ISHR) +
|
||||
binaryOp("ushr", IUSHR) +
|
||||
binaryOp("and", IAND) +
|
||||
binaryOp("or", IOR) +
|
||||
binaryOp("xor", IXOR) +
|
||||
binaryFunForPrimitives("compareTo", CompareTo) +
|
||||
methodWithArity(irBuiltIns.booleanClass, "not", 0, Not) +
|
||||
methodWithArity(irBuiltIns.stringClass, "get", 1, StringGetChar) +
|
||||
methodWithArity(symbols.cloneable, "clone", 0, Clone) +
|
||||
symbols.primitiveIteratorsByType.values.flatMap { iteratorClass ->
|
||||
methodWithArity(iteratorClass, "next", 0, IteratorNext)
|
||||
} +
|
||||
arrayMethods() +
|
||||
primitiveComparisonIntrinsics(irBuiltIns.lessFunByOperandType, KtTokens.LT) +
|
||||
primitiveComparisonIntrinsics(irBuiltIns.lessOrEqualFunByOperandType, KtTokens.LTEQ) +
|
||||
primitiveComparisonIntrinsics(irBuiltIns.greaterFunByOperandType, KtTokens.GT) +
|
||||
primitiveComparisonIntrinsics(irBuiltIns.greaterOrEqualFunByOperandType, KtTokens.GTEQ)
|
||||
).toMap()
|
||||
|
||||
private val irMapping = hashMapOf<CallableMemberDescriptor, IntrinsicMethod>()
|
||||
fun getIntrinsic(symbol: IrFunctionSymbol): IntrinsicMethod? = intrinsicsMap[symbol.toKey()]
|
||||
|
||||
private fun createPrimitiveComparisonIntrinsics(typeToIrFun: Map<SimpleType, IrSimpleFunctionSymbol>, operator: KtSingleValueToken) {
|
||||
for ((type, irFunSymbol) in typeToIrFun) {
|
||||
irMapping[irFunSymbol.descriptor] = PrimitiveComparison(type, operator)
|
||||
private fun unaryFunForPrimitives(name: String, intrinsic: IntrinsicMethod): List<Pair<Key, IntrinsicMethod>> =
|
||||
PrimitiveType.values().flatMap { type ->
|
||||
methodWithArity(irBuiltIns.primitiveTypeToIrType[type]!!.classOrNull!!, name, 0, intrinsic)
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
irMapping[irBuiltIns.eqeq] = Equals(KtTokens.EQEQ)
|
||||
irMapping[irBuiltIns.eqeqeq] = Equals(KtTokens.EQEQEQ)
|
||||
irMapping[irBuiltIns.ieee754equalsFunByOperandType[irBuiltIns.float]!!.descriptor] = Ieee754Equals(Type.FLOAT_TYPE)
|
||||
irMapping[irBuiltIns.ieee754equalsFunByOperandType[irBuiltIns.double]!!.descriptor] = Ieee754Equals(Type.DOUBLE_TYPE)
|
||||
irMapping[irBuiltIns.booleanNot] = Not()
|
||||
|
||||
createPrimitiveComparisonIntrinsics(irBuiltIns.lessFunByOperandType, KtTokens.LT)
|
||||
createPrimitiveComparisonIntrinsics(irBuiltIns.lessOrEqualFunByOperandType, KtTokens.LTEQ)
|
||||
createPrimitiveComparisonIntrinsics(irBuiltIns.greaterFunByOperandType, KtTokens.GT)
|
||||
createPrimitiveComparisonIntrinsics(irBuiltIns.greaterOrEqualFunByOperandType, KtTokens.GTEQ)
|
||||
|
||||
irMapping[irBuiltIns.enumValueOf] = IrEnumValueOf()
|
||||
irMapping[irBuiltIns.noWhenBranchMatchedException] = IrNoWhenBranchMatchedException()
|
||||
irMapping[irBuiltIns.illegalArgumentException] = IrIllegalArgumentException()
|
||||
irMapping[irBuiltIns.throwNpe] = ThrowNPE()
|
||||
|
||||
irMapping[andand] = AndAnd
|
||||
}
|
||||
|
||||
fun getIntrinsic(descriptor: CallableMemberDescriptor): IntrinsicMethod? {
|
||||
intrinsics.getIntrinsic(descriptor)?.let { return it }
|
||||
if (descriptor is PropertyAccessorDescriptor) {
|
||||
return intrinsics.getIntrinsic(DescriptorUtils.unwrapFakeOverride(descriptor.correspondingProperty))
|
||||
private fun binaryFunForPrimitives(name: String, intrinsic: IntrinsicMethod): List<Pair<Key, IntrinsicMethod>> =
|
||||
PrimitiveType.values().flatMap { type ->
|
||||
methodWithArity(irBuiltIns.primitiveTypeToIrType[type]!!.classOrNull!!, name, 1, intrinsic)
|
||||
}
|
||||
return irMapping[descriptor.original]
|
||||
|
||||
private fun binaryOp(methodName: String, opcode: Int) = binaryFunForPrimitives(methodName, BinaryOp(opcode))
|
||||
|
||||
private fun numberConversionMethods(): List<Pair<Key, IntrinsicMethod>> =
|
||||
PrimitiveType.NUMBER_TYPES.flatMap { type ->
|
||||
numberConversionMethods(irBuiltIns.primitiveTypeToIrType[type]!!.classOrNull!!)
|
||||
} + numberConversionMethods(irBuiltIns.numberClass)
|
||||
|
||||
private fun arrayMethods(): List<Pair<Key, IntrinsicMethod>> =
|
||||
symbols.primitiveArrays.values.flatMap { arrayMethods(it) } + arrayMethods(symbols.array)
|
||||
|
||||
data class Key(val owner: FqName, val receiverParameterTypeName: FqName?, val name: String, val valueParameterTypeNames: List<FqName?>)
|
||||
|
||||
companion object {
|
||||
|
||||
internal val INTRINSICS_CLASS_NAME = "kotlin/jvm/internal/Intrinsics"
|
||||
private val INC = Increment(1)
|
||||
|
||||
private val DEC = Increment(-1)
|
||||
private val EQUALS = Equals(KtTokens.EQEQ)
|
||||
|
||||
private fun IrFunctionSymbol.toKey(): Key? {
|
||||
return Key(
|
||||
owner.parent.safeAs<IrClass>()?.fqNameWhenAvailable ?: owner.parent.safeAs<IrPackageFragment>()?.fqName ?: return null,
|
||||
getParameterFqName(owner.extensionReceiverParameter),
|
||||
owner.name.asString(),
|
||||
owner.valueParameters.map(::getParameterFqName)
|
||||
)
|
||||
}
|
||||
|
||||
private fun getParameterFqName(parameter: IrValueParameter?): FqName? =
|
||||
parameter?.type?.safeAs<IrSimpleType>()?.classifier?.owner?.let {
|
||||
when (it) {
|
||||
is IrClass -> it.fqNameWhenAvailable
|
||||
is IrTypeParameter -> FqName(it.name.asString())
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
private fun methodWithArity(klass: IrClassSymbol, name: String, arity: Int, intrinsic: IntrinsicMethod): List<Pair<Key, IntrinsicMethod>> =
|
||||
klass.owner.functions.filter {
|
||||
it.name.asString() == name && it.valueParameters.size == arity
|
||||
}.map {
|
||||
it.symbol.toKey()!! to intrinsic
|
||||
}.toList()
|
||||
|
||||
private fun numberConversionMethods(numberClass: IrClassSymbol) =
|
||||
OperatorConventions.NUMBER_CONVERSIONS.flatMap { method ->
|
||||
methodWithArity(numberClass, method.asString(), 0, NumberCast)
|
||||
}
|
||||
|
||||
private fun arrayMethods(arrayClass: IrClassSymbol) = listOf(
|
||||
arrayClass.constructors.single { it.owner.valueParameters.size == 2 }.toKey()!! to ArrayConstructor,
|
||||
arrayClass.owner.properties.single { it.name.asString() == "size" }.getter!!.symbol.toKey()!! to ArraySize
|
||||
) +
|
||||
methodWithArity(arrayClass, "set", 2, ArraySet) +
|
||||
methodWithArity(arrayClass, "get", 1, ArrayGet) +
|
||||
methodWithArity(arrayClass, "clone", 0, Clone) +
|
||||
methodWithArity(arrayClass, "iterator", 0, ArrayIterator)
|
||||
|
||||
private fun primitiveComparisonIntrinsics(typeToIrFun: Map<SimpleType, IrSimpleFunctionSymbol>, operator: KtSingleValueToken) =
|
||||
typeToIrFun.map { (type, irFunSymbol) ->
|
||||
irFunSymbol.toKey()!! to PrimitiveComparison(type, operator)
|
||||
}
|
||||
}
|
||||
|
||||
private object OperatorNames {
|
||||
|
||||
+3
-2
@@ -18,11 +18,12 @@ package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil.genThrow
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
|
||||
class IrNoWhenBranchMatchedException : IntrinsicMethod() {
|
||||
override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
object IrNoWhenBranchMatchedException : IntrinsicMethod() {
|
||||
override fun toCallable(expression: IrFunctionAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
return IrIntrinsicFunction.create(expression, signature, context) {
|
||||
genThrow(it, "kotlin/NoWhenBranchMatchedException", null)
|
||||
}
|
||||
|
||||
+3
-2
@@ -6,14 +6,15 @@
|
||||
package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.ir.types.toKotlinType
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
|
||||
class IsArrayOf : IntrinsicMethod() {
|
||||
override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
object IsArrayOf : IntrinsicMethod() {
|
||||
override fun toCallable(expression: IrFunctionAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
val typeMapper = context.state.typeMapper
|
||||
|
||||
val descriptor = expression.descriptor
|
||||
|
||||
+15
-16
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns.COLLECTIONS_PACKAGE_FQ_NAME
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.kotlin.fileClasses.internalNameWithoutInnerClasses
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
@@ -27,32 +28,30 @@ import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
|
||||
class IteratorNext : IntrinsicMethod() {
|
||||
object IteratorNext : IntrinsicMethod() {
|
||||
|
||||
override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
override fun toCallable(expression: IrFunctionAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
val type = AsmUtil.unboxType(signature.returnType)
|
||||
val newSignature = signature.newReturnType(type)
|
||||
return IrIntrinsicFunction.create(expression, newSignature, context, AsmTypes.OBJECT_TYPE) {
|
||||
val primitiveClassName = getKotlinPrimitiveClassName(type)
|
||||
it.invokevirtual(
|
||||
getPrimitiveIteratorType(primitiveClassName).internalName,
|
||||
"next${primitiveClassName.asString()}",
|
||||
"()" + type.descriptor,
|
||||
false
|
||||
getPrimitiveIteratorType(primitiveClassName).internalName,
|
||||
"next${primitiveClassName.asString()}",
|
||||
"()" + type.descriptor,
|
||||
false
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
// Type.CHAR_TYPE -> "Char"
|
||||
private fun getKotlinPrimitiveClassName(type: Type): Name {
|
||||
return JvmPrimitiveType.get(type.className).primitiveType.typeName
|
||||
}
|
||||
// Type.CHAR_TYPE -> "Char"
|
||||
private fun getKotlinPrimitiveClassName(type: Type): Name {
|
||||
return JvmPrimitiveType.get(type.className).primitiveType.typeName
|
||||
}
|
||||
|
||||
// "Char" -> type for kotlin.collections.CharIterator
|
||||
fun getPrimitiveIteratorType(primitiveClassName: Name): Type {
|
||||
val iteratorName = Name.identifier(primitiveClassName.asString() + "Iterator")
|
||||
return Type.getObjectType(COLLECTIONS_PACKAGE_FQ_NAME.child(iteratorName).internalNameWithoutInnerClasses)
|
||||
}
|
||||
// "Char" -> type for kotlin.collections.CharIterator
|
||||
fun getPrimitiveIteratorType(primitiveClassName: Name): Type {
|
||||
val iteratorName = Name.identifier(primitiveClassName.asString() + "Iterator")
|
||||
return Type.getObjectType(COLLECTIONS_PACKAGE_FQ_NAME.child(iteratorName).internalNameWithoutInnerClasses)
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.ir.expressions.IrClassReference
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrGetClass
|
||||
|
||||
class KClassJavaProperty : IntrinsicMethod() {
|
||||
object KClassJavaProperty : IntrinsicMethod() {
|
||||
override fun invoke(expression: IrFunctionAccessExpression, codegen: ExpressionCodegen, data: BlockInfo): PromisedValue? {
|
||||
val extensionReceiver = expression.extensionReceiver
|
||||
if (extensionReceiver !is IrClassReference && extensionReceiver !is IrGetClass)
|
||||
|
||||
+2
-1
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
@@ -32,7 +33,7 @@ class MonitorInstruction private constructor(private val opcode: Int) : Intrinsi
|
||||
}
|
||||
|
||||
/*TODO void return type*/
|
||||
override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
override fun toCallable(expression: IrFunctionAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
return IrIntrinsicFunction.create(expression, signature, context, OBJECT_TYPE) {
|
||||
it.visitInsn(opcode)
|
||||
}
|
||||
|
||||
@@ -9,14 +9,18 @@ import org.jetbrains.kotlin.backend.jvm.codegen.BlockInfo
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.ExpressionCodegen
|
||||
import org.jetbrains.kotlin.codegen.StackValue
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
||||
import org.jetbrains.kotlin.ir.types.toKotlinType
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
|
||||
class NewArray : IntrinsicMethod() {
|
||||
object NewArray : IntrinsicMethod() {
|
||||
|
||||
override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
override fun toCallable(
|
||||
expression: IrFunctionAccessExpression,
|
||||
signature: JvmMethodSignature,
|
||||
context: JvmBackendContext
|
||||
): IrIntrinsicFunction {
|
||||
val ktType = expression.type
|
||||
return object : IrIntrinsicFunction(expression, signature, context) {
|
||||
override fun invoke(v: InstructionAdapter, codegen: ExpressionCodegen, data: BlockInfo): StackValue {
|
||||
|
||||
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.backend.jvm.codegen.coerceToBoolean
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
||||
import org.jetbrains.org.objectweb.asm.Label
|
||||
|
||||
class Not : IntrinsicMethod() {
|
||||
object Not : IntrinsicMethod() {
|
||||
class BooleanNegation(val value: BooleanValue) : BooleanValue(value.mv) {
|
||||
override fun jumpIfFalse(target: Label) = value.jumpIfTrue(target)
|
||||
override fun jumpIfTrue(target: Label) = value.jumpIfFalse(target)
|
||||
|
||||
+3
-2
@@ -18,12 +18,13 @@ package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.codegen.StackValue
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
|
||||
class NumberCast : IntrinsicMethod() {
|
||||
object NumberCast : IntrinsicMethod() {
|
||||
|
||||
override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
override fun toCallable(expression: IrFunctionAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
return IrIntrinsicFunction.create(expression, signature, context) {
|
||||
StackValue.coerce(argsTypes[0], signature.returnType, it)
|
||||
}
|
||||
|
||||
@@ -20,14 +20,14 @@ import org.jetbrains.kotlin.backend.jvm.codegen.BlockInfo
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.ExpressionCodegen
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.codegen.StackValue
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.Type.*
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
import java.lang.IllegalStateException
|
||||
|
||||
class RangeTo : IntrinsicMethod() {
|
||||
object RangeTo : IntrinsicMethod() {
|
||||
private fun rangeTypeToPrimitiveType(rangeType: Type): Type {
|
||||
val fqName = rangeType.internalName
|
||||
val name = fqName.substringAfter("kotlin/ranges/").substringBefore("Range")
|
||||
@@ -43,7 +43,7 @@ class RangeTo : IntrinsicMethod() {
|
||||
}
|
||||
}
|
||||
|
||||
override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
override fun toCallable(expression: IrFunctionAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
val argType = rangeTypeToPrimitiveType(signature.returnType)
|
||||
return object: IrIntrinsicFunction(expression, signature, context, listOf(argType) + signature.valueParameters.map { argType }) {
|
||||
override fun genInvokeInstruction(v: InstructionAdapter) {
|
||||
|
||||
+3
-2
@@ -17,11 +17,12 @@
|
||||
package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
|
||||
class StringGetChar : IntrinsicMethod() {
|
||||
override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
object StringGetChar : IntrinsicMethod() {
|
||||
override fun toCallable(expression: IrFunctionAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
return IrIntrinsicFunction.create(expression, signature, context) {
|
||||
it.invokevirtual("java/lang/String", "charAt", "(I)C", false)
|
||||
}
|
||||
|
||||
@@ -7,13 +7,14 @@ package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
|
||||
class ThrowNPE : IntrinsicMethod() {
|
||||
object ThrowNPE : IntrinsicMethod() {
|
||||
override fun toCallable(
|
||||
expression: IrMemberAccessExpression,
|
||||
expression: IrFunctionAccessExpression,
|
||||
signature: JvmMethodSignature,
|
||||
context: JvmBackendContext
|
||||
): IrIntrinsicFunction {
|
||||
|
||||
@@ -18,11 +18,12 @@ package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
|
||||
class ToString : IntrinsicMethod() {
|
||||
override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
object ToString : IntrinsicMethod() {
|
||||
override fun toCallable(expression: IrFunctionAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
val type = AsmUtil.stringValueOfType(calcReceiverType(expression, context))
|
||||
return IrIntrinsicFunction.create(expression, signature, context, type) {
|
||||
it.invokestatic("java/lang/String", "valueOf", "(${type.descriptor})Ljava/lang/String;", false)
|
||||
|
||||
+3
-2
@@ -19,12 +19,13 @@ package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil.numberFunctionOperandType
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
|
||||
class UnaryMinus : IntrinsicMethod() {
|
||||
object UnaryMinus : IntrinsicMethod() {
|
||||
/*TODO return type*/
|
||||
override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
override fun toCallable(expression: IrFunctionAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
return IrIntrinsicFunction.create(expression, signature, context) {
|
||||
it.neg(numberFunctionOperandType(signature.returnType))
|
||||
}
|
||||
|
||||
+3
-2
@@ -17,11 +17,12 @@
|
||||
package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
|
||||
class UnaryPlus : IntrinsicMethod() {
|
||||
override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
object UnaryPlus : IntrinsicMethod() {
|
||||
override fun toCallable(expression: IrFunctionAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
return IrIntrinsicFunction.create(expression, signature, context) {
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -154,7 +154,7 @@ private class AnnotationLowering(private val context: JvmBackendContext) : FileL
|
||||
}
|
||||
|
||||
private fun IrCall.isGetJava(): Boolean =
|
||||
context.irIntrinsics.getIntrinsic(descriptor) is KClassJavaProperty
|
||||
context.irIntrinsics.getIntrinsic(symbol) is KClassJavaProperty
|
||||
}
|
||||
|
||||
private fun IrClassSymbol.getFunctionByName(name: String, numParams: Int): IrSimpleFunctionSymbol =
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.ir.descriptors
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.PrimitiveType
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
|
||||
@@ -183,6 +184,17 @@ class IrBuiltIns(
|
||||
val primitiveTypesWithComparisons = listOf(char, byte, short, int, long, float, double)
|
||||
val primitiveFloatingPointTypes = listOf(float, double)
|
||||
|
||||
val primitiveTypeToIrType = mapOf(
|
||||
PrimitiveType.BOOLEAN to booleanType,
|
||||
PrimitiveType.CHAR to charType,
|
||||
PrimitiveType.BYTE to byteType,
|
||||
PrimitiveType.SHORT to shortType,
|
||||
PrimitiveType.INT to intType,
|
||||
PrimitiveType.FLOAT to floatType,
|
||||
PrimitiveType.LONG to longType,
|
||||
PrimitiveType.DOUBLE to doubleType
|
||||
)
|
||||
|
||||
val lessFunByOperandType = primitiveTypesWithComparisons.defineComparisonOperatorForEachType(OperatorNames.LESS)
|
||||
val lessOrEqualFunByOperandType = primitiveTypesWithComparisons.defineComparisonOperatorForEachType(OperatorNames.LESS_OR_EQUAL)
|
||||
val greaterOrEqualFunByOperandType = primitiveTypesWithComparisons.defineComparisonOperatorForEachType(OperatorNames.GREATER_OR_EQUAL)
|
||||
|
||||
Reference in New Issue
Block a user