diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/GetJavaObjectType.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/GetJavaObjectType.kt new file mode 100644 index 00000000000..2d362d5e238 --- /dev/null +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/GetJavaObjectType.kt @@ -0,0 +1,63 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.backend.jvm.intrinsics + +import org.jetbrains.kotlin.backend.jvm.codegen.* +import org.jetbrains.kotlin.codegen.AsmUtil +import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner +import org.jetbrains.kotlin.ir.expressions.IrClassReference +import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression +import org.jetbrains.kotlin.ir.expressions.IrGetClass +import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol +import org.jetbrains.kotlin.ir.util.dump +import org.jetbrains.kotlin.resolve.jvm.AsmTypes +import org.jetbrains.org.objectweb.asm.Type + +object GetJavaObjectType : IntrinsicMethod() { + + override fun invoke(expression: IrFunctionAccessExpression, codegen: ExpressionCodegen, data: BlockInfo): PromisedValue? = + when (val receiver = expression.extensionReceiver) { + is IrClassReference -> { + val symbol = receiver.symbol + if (symbol is IrTypeParameterSymbol) { + assert(symbol.owner.isReified) { + "Non-reified type parameter under ::class should be rejected by type checker: ${symbol.owner.dump()}" + } + codegen.putReifiedOperationMarkerIfTypeIsReifiedParameter( + receiver.classType, + ReifiedTypeInliner.OperationKind.JAVA_CLASS + ) + } + codegen.mv.aconst(AsmUtil.boxType(codegen.typeMapper.mapTypeAsDeclaration(receiver.classType))) + + with(codegen) { expression.onStack } + } + + is IrGetClass -> { + val argumentValue = receiver.argument.accept(codegen, data) + argumentValue.materialize() + val argumentType = argumentValue.type + when { + argumentType == Type.VOID_TYPE -> + codegen.mv.aconst(AsmTypes.UNIT_TYPE) + + AsmUtil.isPrimitive(argumentType) || + AsmUtil.unboxPrimitiveTypeOrNull(argumentType) != null -> { + AsmUtil.pop(codegen.mv, argumentType) + codegen.mv.aconst(AsmUtil.boxType(argumentType)) + } + + else -> + codegen.mv.invokevirtual("java/lang/Object", "getClass", "()Ljava/lang/Class;", false) + } + + with(codegen) { expression.onStack } + } + + else -> + null + } +} \ No newline at end of file diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/IrIntrinsicMethods.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/IrIntrinsicMethods.kt index 6f4e2d77fd9..0114c03e1b9 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/IrIntrinsicMethods.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/IrIntrinsicMethods.kt @@ -43,6 +43,7 @@ class IrIntrinsicMethods(val irBuiltIns: IrBuiltIns, val symbols: JvmSymbols) { private val intrinsicsMap = ( listOf( Key(kotlinJvm, FqName("T"), "", emptyList()) to JavaClassProperty, + Key(kotlinJvm, KotlinBuiltIns.FQ_NAMES.kClass.toSafe(), "", emptyList()) to GetJavaObjectType, Key( kotlinJvm, KotlinBuiltIns.FQ_NAMES.kClass.toSafe(), diff --git a/compiler/testData/codegen/bytecodeText/intrinsics/javaObjectType.kt b/compiler/testData/codegen/bytecodeText/intrinsics/javaObjectType.kt index e77b25d4fc2..a80fac6a2f4 100644 --- a/compiler/testData/codegen/bytecodeText/intrinsics/javaObjectType.kt +++ b/compiler/testData/codegen/bytecodeText/intrinsics/javaObjectType.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR class A { }