diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index 5dfc5230e0f..b253893df34 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -4843,33 +4843,13 @@ The "returned" value of try expression with no finally is either the last expres public void putReifiedOperationMarkerIfTypeIsReifiedParameter( @NotNull KotlinType type, @NotNull ReifiedTypeInliner.OperationKind operationKind - ) { - putReifiedOperationMarkerIfTypeIsReifiedParameter(type, operationKind, v, this); - } - - public static void putReifiedOperationMarkerIfTypeIsReifiedParameterWithoutPropagation( - @NotNull KotlinType type, @NotNull ReifiedTypeInliner.OperationKind operationKind, @NotNull InstructionAdapter v - ) { - putReifiedOperationMarkerIfTypeIsReifiedParameterImpl(type, operationKind, v, null); - } - - private static void putReifiedOperationMarkerIfTypeIsReifiedParameter( - @NotNull KotlinType type, @NotNull ReifiedTypeInliner.OperationKind operationKind, @NotNull InstructionAdapter v, - @NotNull ExpressionCodegen codegen - ) { - putReifiedOperationMarkerIfTypeIsReifiedParameterImpl(type, operationKind, v, codegen); - } - - private static void putReifiedOperationMarkerIfTypeIsReifiedParameterImpl( - @NotNull KotlinType type, @NotNull ReifiedTypeInliner.OperationKind operationKind, @NotNull InstructionAdapter v, - @Nullable ExpressionCodegen codegen ) { Pair typeParameterAndReificationArgument = extractReificationArgument(type); - if (typeParameterAndReificationArgument != null && typeParameterAndReificationArgument.getFirst().isReified()) { - TypeParameterDescriptor typeParameterDescriptor = typeParameterAndReificationArgument.getFirst(); - if (codegen != null) { - codegen.consumeReifiedOperationMarker(typeParameterDescriptor); - } + if (typeParameterAndReificationArgument == null) return; + + TypeParameterDescriptor typeParameter = typeParameterAndReificationArgument.getFirst(); + if (typeParameter.isReified()) { + consumeReifiedOperationMarker(typeParameter); ReifiedTypeInliner.putReifiedOperationMarker(operationKind, typeParameterAndReificationArgument.getSecond(), v); } } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/ReifiedTypeInliner.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/ReifiedTypeInliner.kt index 02ef95b3e64..044287b019b 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/ReifiedTypeInliner.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/ReifiedTypeInliner.kt @@ -23,6 +23,7 @@ import org.jetbrains.kotlin.codegen.optimization.common.intConstant import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.config.isReleaseCoroutines +import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.resolve.jvm.AsmTypes import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.TypeUtils @@ -109,6 +110,18 @@ class ReifiedTypeInliner( Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE, AsmTypes.JAVA_STRING_TYPE), false ) } + + fun putReifiedOperationMarkerIfNeeded( + typeParameter: TypeParameterDescriptor, + isNullable: Boolean, + operationKind: OperationKind, + v: InstructionAdapter + ) { + if (typeParameter.isReified) { + val argument = ReificationArgument(typeParameter.name.asString(), isNullable, 0) + putReifiedOperationMarker(operationKind, argument, v) + } + } } private var maxStackSize = 0 diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/inlineIntrinsics.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/inlineIntrinsics.kt index bafd2a8a8f4..7683ee72961 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/inlineIntrinsics.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/inlineIntrinsics.kt @@ -9,7 +9,6 @@ import org.jetbrains.kotlin.backend.common.isBuiltInIntercepted import org.jetbrains.kotlin.backend.common.isBuiltInSuspendCoroutineUninterceptedOrReturn import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.codegen.AsmUtil -import org.jetbrains.kotlin.codegen.ExpressionCodegen import org.jetbrains.kotlin.codegen.coroutines.createMethodNodeForCoroutineContext import org.jetbrains.kotlin.codegen.coroutines.createMethodNodeForIntercepted import org.jetbrains.kotlin.codegen.coroutines.createMethodNodeForSuspendCoroutineUninterceptedOrReturn @@ -41,9 +40,9 @@ internal fun generateInlineIntrinsic( val typeMapper = state.typeMapper return when { isSpecialEnumMethod(descriptor) -> - createSpecialEnumMethodBody(descriptor.name.asString(), typeArguments!!.keys.single().defaultType, typeMapper) + createSpecialEnumMethodBody(descriptor.name.asString(), typeArguments!!.keys.single(), typeMapper) TypeOfChecker.isTypeOf(descriptor) -> - createTypeOfMethodBody(typeArguments!!.keys.single().defaultType) + createTypeOfMethodBody(typeArguments!!.keys.single()) descriptor.isBuiltInIntercepted(languageVersionSettings) -> createMethodNodeForIntercepted(descriptor, typeMapper, languageVersionSettings) descriptor.isBuiltInCoroutineContext(languageVersionSettings) -> @@ -70,15 +69,13 @@ private fun isSpecialEnumMethod(descriptor: FunctionDescriptor): Boolean { (name == "enumValueOf" && parameters.size == 1 && KotlinBuiltIns.isString(parameters[0].type)) } -private fun createSpecialEnumMethodBody(name: String, type: KotlinType, typeMapper: KotlinTypeMapper): MethodNode { +private fun createSpecialEnumMethodBody(name: String, typeParameter: TypeParameterDescriptor, typeMapper: KotlinTypeMapper): MethodNode { val isValueOf = "enumValueOf" == name - val invokeType = typeMapper.mapType(type) + val invokeType = typeMapper.mapType(typeParameter.defaultType) val desc = getSpecialEnumFunDescriptor(invokeType, isValueOf) val node = MethodNode(Opcodes.API_VERSION, Opcodes.ACC_STATIC, "fake", desc, null, null) - ExpressionCodegen.putReifiedOperationMarkerIfTypeIsReifiedParameterWithoutPropagation( - type, - ReifiedTypeInliner.OperationKind.ENUM_REIFIED, - InstructionAdapter(node) + ReifiedTypeInliner.putReifiedOperationMarkerIfNeeded( + typeParameter, false, ReifiedTypeInliner.OperationKind.ENUM_REIFIED, InstructionAdapter(node) ) if (isValueOf) { node.visitInsn(Opcodes.ACONST_NULL) @@ -101,11 +98,11 @@ internal fun getSpecialEnumFunDescriptor(type: Type, isValueOf: Boolean): String if (isValueOf) Type.getMethodDescriptor(type, JAVA_STRING_TYPE) else Type.getMethodDescriptor(AsmUtil.getArrayType(type)) -private fun createTypeOfMethodBody(type: KotlinType): MethodNode { +private fun createTypeOfMethodBody(typeParameter: TypeParameterDescriptor): MethodNode { val node = MethodNode(Opcodes.API_VERSION, Opcodes.ACC_STATIC, "fake", Type.getMethodDescriptor(K_TYPE), null, null) val v = InstructionAdapter(node) - putTypeOfReifiedTypeParameter(v, type) + putTypeOfReifiedTypeParameter(v, typeParameter, false) v.areturn(K_TYPE) v.visitMaxs(2, 0) @@ -113,8 +110,8 @@ private fun createTypeOfMethodBody(type: KotlinType): MethodNode { return node } -private fun putTypeOfReifiedTypeParameter(v: InstructionAdapter, type: KotlinType) { - ExpressionCodegen.putReifiedOperationMarkerIfTypeIsReifiedParameterWithoutPropagation(type, ReifiedTypeInliner.OperationKind.TYPE_OF, v) +private fun putTypeOfReifiedTypeParameter(v: InstructionAdapter, typeParameter: TypeParameterDescriptor, isNullable: Boolean) { + ReifiedTypeInliner.putReifiedOperationMarkerIfNeeded(typeParameter, isNullable, ReifiedTypeInliner.OperationKind.TYPE_OF, v) v.aconst(null) } @@ -179,7 +176,7 @@ private fun doGenerateTypeProjection( val descriptor = type.constructor.declarationDescriptor val stackSize = if (descriptor is TypeParameterDescriptor) { if (descriptor.isReified) { - putTypeOfReifiedTypeParameter(v, type) + putTypeOfReifiedTypeParameter(v, descriptor, type.isMarkedNullable) 2 } else { // TODO: support non-reified type parameters in typeOf