From af7684082621f1c97d2ad5390faeac90f660f441 Mon Sep 17 00:00:00 2001 From: Michael Bogdanov Date: Tue, 27 Sep 2016 14:08:44 +0300 Subject: [PATCH] Support some new intrinsics --- .../backend/jvm/codegen/ExpressionCodegen.kt | 2 +- .../backend/jvm/intrinsics/IntrinsicMethod.kt | 14 ------ .../jvm/intrinsics/JavaClassProperty.kt | 50 ++++++------------- .../backend/jvm/intrinsics/StringGetChar.kt | 16 +++--- .../backend/jvm/intrinsics/StringPlus.kt | 16 +++--- .../kotlin/backend/jvm/intrinsics/ToString.kt | 12 +---- 6 files changed, 37 insertions(+), 73 deletions(-) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt index 5b251bb4ad2..12803795c3e 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt @@ -456,7 +456,7 @@ class ExpressionCodegen( get() = StackValue.onStack(this.asmType) private fun resolveToCallable(irCall: IrMemberAccessExpression, isSuper: Boolean): Callable { - val intrinsic = intrinsics.getIntrinsic(irCall.descriptor as CallableMemberDescriptor) + val intrinsic = intrinsics.getIntrinsic(irCall.descriptor.original as CallableMemberDescriptor) if (intrinsic != null) { return intrinsic.toCallable(irCall, typeMapper.mapSignatureSkipGeneric(irCall.descriptor as FunctionDescriptor), classCodegen.context) } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/IntrinsicMethod.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/IntrinsicMethod.kt index e8e9c20256c..a83d5cec6a8 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/IntrinsicMethod.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/IntrinsicMethod.kt @@ -19,12 +19,8 @@ package org.jetbrains.kotlin.backend.jvm.intrinsics import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.codegen.Callable import org.jetbrains.kotlin.codegen.CallableMethod -import org.jetbrains.kotlin.codegen.ExpressionCodegen -import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.ir.expressions.IrExpression -import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression -import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature import org.jetbrains.org.objectweb.asm.Type @@ -38,16 +34,6 @@ abstract class IntrinsicMethod { TODO() } - - open fun toCallable( - fd: FunctionDescriptor, - isSuper: Boolean, - resolvedCall: ResolvedCall<*>, - codegen: ExpressionCodegen - ): Callable { - throw UnsupportedOperationException("Not implemented") - } - open fun toCallable(method: CallableMethod): Callable { throw UnsupportedOperationException("Not implemented") } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/JavaClassProperty.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/JavaClassProperty.kt index 3beff306d14..02de5cde708 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/JavaClassProperty.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/JavaClassProperty.kt @@ -16,6 +16,8 @@ package org.jetbrains.kotlin.backend.jvm.intrinsics +import org.jetbrains.kotlin.backend.jvm.JvmBackendContext +import org.jetbrains.kotlin.backend.jvm.codegen.BlockInfo import org.jetbrains.kotlin.codegen.AsmUtil import org.jetbrains.kotlin.codegen.AsmUtil.boxType import org.jetbrains.kotlin.codegen.AsmUtil.isPrimitive @@ -23,53 +25,33 @@ import org.jetbrains.kotlin.codegen.Callable import org.jetbrains.kotlin.codegen.ExpressionCodegen import org.jetbrains.kotlin.codegen.StackValue import org.jetbrains.kotlin.descriptors.FunctionDescriptor +import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.kotlin.resolve.jvm.AsmTypes.getType +import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter object JavaClassProperty : IntrinsicMethod() { - fun generate( - resolvedCall: ResolvedCall<*>?, - codegen: ExpressionCodegen, - returnType: Type, - receiver: StackValue - ): StackValue? = - StackValue.operation(returnType) { - val actualType = generateImpl(it, receiver) - StackValue.coerce(actualType, returnType, it) - } - fun generateImpl(v: InstructionAdapter, receiver: StackValue): Type { - val type = receiver.type - if (isPrimitive(type)) { - if (!StackValue.couldSkipReceiverOnStaticCall(receiver)) { - receiver.put(type, v) - AsmUtil.pop(v, type) - } - v.getstatic(boxType(type).internalName, "TYPE", "Ljava/lang/Class;") - } - else { - receiver.put(type, v) - v.invokevirtual("java/lang/Object", "getClass", "()Ljava/lang/Class;", false) - } + override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction { + return object: IrIntrinsicFunction(expression, signature, context) { - return getType(Class::class.java) - } - - override fun toCallable(fd: FunctionDescriptor, isSuper: Boolean, resolvedCall: ResolvedCall<*>, codegen: ExpressionCodegen): Callable { - val classType = codegen.getState().typeMapper.mapType(resolvedCall.call.dispatchReceiver!!.type) - return object : IntrinsicCallable(getType(Class::class.java), listOf(), classType, null) { - override fun invokeIntrinsic(v: InstructionAdapter) { - if (isPrimitive(classType)) { - v.getstatic(boxType(classType).internalName, "TYPE", "Ljava/lang/Class;") + override fun invoke(v: InstructionAdapter, codegen: org.jetbrains.kotlin.backend.jvm.codegen.ExpressionCodegen, data: BlockInfo): StackValue { + val value = codegen.gen(expression.extensionReceiver!!, data) + val type = value.type + if (isPrimitive(type)) { + AsmUtil.pop(v, type) + v.getstatic(boxType(type).internalName, "TYPE", "Ljava/lang/Class;") } else { v.invokevirtual("java/lang/Object", "getClass", "()Ljava/lang/Class;", false) } - } - override fun isStaticCall() = isPrimitive(classType) + return with(codegen) { + expression.onStack + } + } } } } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/StringGetChar.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/StringGetChar.kt index 0c36f4d008c..4438e29ba14 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/StringGetChar.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/StringGetChar.kt @@ -16,12 +16,14 @@ package org.jetbrains.kotlin.backend.jvm.intrinsics -import org.jetbrains.kotlin.codegen.Callable -import org.jetbrains.kotlin.codegen.CallableMethod +import org.jetbrains.kotlin.backend.jvm.JvmBackendContext +import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression +import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature class StringGetChar : IntrinsicMethod() { - override fun toCallable(method: CallableMethod): Callable = - createIntrinsicCallable(method) { - it.invokevirtual("java/lang/String", "charAt", "(I)C", false) - } -} + override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction { + return IrIntrinsicFunction.create(expression, signature, context) { + it.invokevirtual("java/lang/String", "charAt", "(I)C", false) + } + } +} \ No newline at end of file diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/StringPlus.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/StringPlus.kt index 9dd4ba25e7e..644c1feaee3 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/StringPlus.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/StringPlus.kt @@ -16,13 +16,15 @@ package org.jetbrains.kotlin.backend.jvm.intrinsics -import org.jetbrains.kotlin.codegen.Callable -import org.jetbrains.kotlin.codegen.CallableMethod +import org.jetbrains.kotlin.backend.jvm.JvmBackendContext +import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression +import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature class StringPlus : IntrinsicMethod() { - override fun toCallable(method: CallableMethod): Callable = - createIntrinsicCallable(method) { - it.invokestatic("kotlin/jvm/internal/Intrinsics", "stringPlus", - "(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/String;", false) - } + override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction { + return IrIntrinsicFunction.create(expression, signature, context) { + it.invokestatic("kotlin/jvm/internal/Intrinsics", "stringPlus", + "(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/String;", false) + } + } } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/ToString.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/ToString.kt index 5683f78fa0f..dd82c12d63d 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/ToString.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/ToString.kt @@ -18,21 +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.codegen.Callable -import org.jetbrains.kotlin.codegen.CallableMethod 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 { - return IrIntrinsicFunction.create(expression, signature, context) { - it.neg(AsmUtil.numberFunctionOperandType(signature.returnType)) - } - } - - override fun toCallable(method: CallableMethod): Callable { - val type = AsmUtil.stringValueOfType(method.dispatchReceiverType ?: method.extensionReceiverType) - return createUnaryIntrinsicCallable(method, newThisType = type) { + 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) } }