Simplify reified operations on type parameters in ExpressionCodegen
Move the "without propagation" logic to ReifiedTypeInliner since it's only used from inline intrinsics.
This commit is contained in:
@@ -4843,33 +4843,13 @@ The "returned" value of try expression with no finally is either the last expres
|
|||||||
|
|
||||||
public void putReifiedOperationMarkerIfTypeIsReifiedParameter(
|
public void putReifiedOperationMarkerIfTypeIsReifiedParameter(
|
||||||
@NotNull KotlinType type, @NotNull ReifiedTypeInliner.OperationKind operationKind
|
@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<TypeParameterDescriptor, ReificationArgument> typeParameterAndReificationArgument = extractReificationArgument(type);
|
Pair<TypeParameterDescriptor, ReificationArgument> typeParameterAndReificationArgument = extractReificationArgument(type);
|
||||||
if (typeParameterAndReificationArgument != null && typeParameterAndReificationArgument.getFirst().isReified()) {
|
if (typeParameterAndReificationArgument == null) return;
|
||||||
TypeParameterDescriptor typeParameterDescriptor = typeParameterAndReificationArgument.getFirst();
|
|
||||||
if (codegen != null) {
|
TypeParameterDescriptor typeParameter = typeParameterAndReificationArgument.getFirst();
|
||||||
codegen.consumeReifiedOperationMarker(typeParameterDescriptor);
|
if (typeParameter.isReified()) {
|
||||||
}
|
consumeReifiedOperationMarker(typeParameter);
|
||||||
ReifiedTypeInliner.putReifiedOperationMarker(operationKind, typeParameterAndReificationArgument.getSecond(), v);
|
ReifiedTypeInliner.putReifiedOperationMarker(operationKind, typeParameterAndReificationArgument.getSecond(), v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.codegen.optimization.common.intConstant
|
|||||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
import org.jetbrains.kotlin.config.isReleaseCoroutines
|
import org.jetbrains.kotlin.config.isReleaseCoroutines
|
||||||
|
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.TypeUtils
|
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
|
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
|
private var maxStackSize = 0
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import org.jetbrains.kotlin.backend.common.isBuiltInIntercepted
|
|||||||
import org.jetbrains.kotlin.backend.common.isBuiltInSuspendCoroutineUninterceptedOrReturn
|
import org.jetbrains.kotlin.backend.common.isBuiltInSuspendCoroutineUninterceptedOrReturn
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
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.createMethodNodeForCoroutineContext
|
||||||
import org.jetbrains.kotlin.codegen.coroutines.createMethodNodeForIntercepted
|
import org.jetbrains.kotlin.codegen.coroutines.createMethodNodeForIntercepted
|
||||||
import org.jetbrains.kotlin.codegen.coroutines.createMethodNodeForSuspendCoroutineUninterceptedOrReturn
|
import org.jetbrains.kotlin.codegen.coroutines.createMethodNodeForSuspendCoroutineUninterceptedOrReturn
|
||||||
@@ -41,9 +40,9 @@ internal fun generateInlineIntrinsic(
|
|||||||
val typeMapper = state.typeMapper
|
val typeMapper = state.typeMapper
|
||||||
return when {
|
return when {
|
||||||
isSpecialEnumMethod(descriptor) ->
|
isSpecialEnumMethod(descriptor) ->
|
||||||
createSpecialEnumMethodBody(descriptor.name.asString(), typeArguments!!.keys.single().defaultType, typeMapper)
|
createSpecialEnumMethodBody(descriptor.name.asString(), typeArguments!!.keys.single(), typeMapper)
|
||||||
TypeOfChecker.isTypeOf(descriptor) ->
|
TypeOfChecker.isTypeOf(descriptor) ->
|
||||||
createTypeOfMethodBody(typeArguments!!.keys.single().defaultType)
|
createTypeOfMethodBody(typeArguments!!.keys.single())
|
||||||
descriptor.isBuiltInIntercepted(languageVersionSettings) ->
|
descriptor.isBuiltInIntercepted(languageVersionSettings) ->
|
||||||
createMethodNodeForIntercepted(descriptor, typeMapper, languageVersionSettings)
|
createMethodNodeForIntercepted(descriptor, typeMapper, languageVersionSettings)
|
||||||
descriptor.isBuiltInCoroutineContext(languageVersionSettings) ->
|
descriptor.isBuiltInCoroutineContext(languageVersionSettings) ->
|
||||||
@@ -70,15 +69,13 @@ private fun isSpecialEnumMethod(descriptor: FunctionDescriptor): Boolean {
|
|||||||
(name == "enumValueOf" && parameters.size == 1 && KotlinBuiltIns.isString(parameters[0].type))
|
(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 isValueOf = "enumValueOf" == name
|
||||||
val invokeType = typeMapper.mapType(type)
|
val invokeType = typeMapper.mapType(typeParameter.defaultType)
|
||||||
val desc = getSpecialEnumFunDescriptor(invokeType, isValueOf)
|
val desc = getSpecialEnumFunDescriptor(invokeType, isValueOf)
|
||||||
val node = MethodNode(Opcodes.API_VERSION, Opcodes.ACC_STATIC, "fake", desc, null, null)
|
val node = MethodNode(Opcodes.API_VERSION, Opcodes.ACC_STATIC, "fake", desc, null, null)
|
||||||
ExpressionCodegen.putReifiedOperationMarkerIfTypeIsReifiedParameterWithoutPropagation(
|
ReifiedTypeInliner.putReifiedOperationMarkerIfNeeded(
|
||||||
type,
|
typeParameter, false, ReifiedTypeInliner.OperationKind.ENUM_REIFIED, InstructionAdapter(node)
|
||||||
ReifiedTypeInliner.OperationKind.ENUM_REIFIED,
|
|
||||||
InstructionAdapter(node)
|
|
||||||
)
|
)
|
||||||
if (isValueOf) {
|
if (isValueOf) {
|
||||||
node.visitInsn(Opcodes.ACONST_NULL)
|
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)
|
if (isValueOf) Type.getMethodDescriptor(type, JAVA_STRING_TYPE)
|
||||||
else Type.getMethodDescriptor(AsmUtil.getArrayType(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 node = MethodNode(Opcodes.API_VERSION, Opcodes.ACC_STATIC, "fake", Type.getMethodDescriptor(K_TYPE), null, null)
|
||||||
val v = InstructionAdapter(node)
|
val v = InstructionAdapter(node)
|
||||||
|
|
||||||
putTypeOfReifiedTypeParameter(v, type)
|
putTypeOfReifiedTypeParameter(v, typeParameter, false)
|
||||||
v.areturn(K_TYPE)
|
v.areturn(K_TYPE)
|
||||||
|
|
||||||
v.visitMaxs(2, 0)
|
v.visitMaxs(2, 0)
|
||||||
@@ -113,8 +110,8 @@ private fun createTypeOfMethodBody(type: KotlinType): MethodNode {
|
|||||||
return node
|
return node
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun putTypeOfReifiedTypeParameter(v: InstructionAdapter, type: KotlinType) {
|
private fun putTypeOfReifiedTypeParameter(v: InstructionAdapter, typeParameter: TypeParameterDescriptor, isNullable: Boolean) {
|
||||||
ExpressionCodegen.putReifiedOperationMarkerIfTypeIsReifiedParameterWithoutPropagation(type, ReifiedTypeInliner.OperationKind.TYPE_OF, v)
|
ReifiedTypeInliner.putReifiedOperationMarkerIfNeeded(typeParameter, isNullable, ReifiedTypeInliner.OperationKind.TYPE_OF, v)
|
||||||
v.aconst(null)
|
v.aconst(null)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,7 +176,7 @@ private fun doGenerateTypeProjection(
|
|||||||
val descriptor = type.constructor.declarationDescriptor
|
val descriptor = type.constructor.declarationDescriptor
|
||||||
val stackSize = if (descriptor is TypeParameterDescriptor) {
|
val stackSize = if (descriptor is TypeParameterDescriptor) {
|
||||||
if (descriptor.isReified) {
|
if (descriptor.isReified) {
|
||||||
putTypeOfReifiedTypeParameter(v, type)
|
putTypeOfReifiedTypeParameter(v, descriptor, type.isMarkedNullable)
|
||||||
2
|
2
|
||||||
} else {
|
} else {
|
||||||
// TODO: support non-reified type parameters in typeOf
|
// TODO: support non-reified type parameters in typeOf
|
||||||
|
|||||||
Reference in New Issue
Block a user