JVM IR: reuse JVM code for reified type parameter mappings instead of copy-paste
This commit is contained in:
@@ -17,8 +17,13 @@
|
||||
package org.jetbrains.kotlin.codegen
|
||||
|
||||
import org.jetbrains.kotlin.codegen.inline.NameGenerator
|
||||
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner.Companion.putReifiedOperationMarker
|
||||
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner.OperationKind
|
||||
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeParametersUsages
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext
|
||||
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
||||
import org.jetbrains.kotlin.types.model.TypeParameterMarker
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
|
||||
interface BaseExpressionCodegen {
|
||||
@@ -29,6 +34,8 @@ interface BaseExpressionCodegen {
|
||||
|
||||
val inlineNameGenerator: NameGenerator
|
||||
|
||||
val typeSystem: TypeSystemCommonBackendContext
|
||||
|
||||
val lastLineNumber: Int
|
||||
|
||||
fun propagateChildReifiedTypeParametersUsages(reifiedTypeParametersUsages: ReifiedTypeParametersUsages)
|
||||
@@ -41,4 +48,17 @@ interface BaseExpressionCodegen {
|
||||
)
|
||||
|
||||
fun markLineNumberAfterInlineIfNeeded()
|
||||
|
||||
fun consumeReifiedOperationMarker(typeParameter: TypeParameterMarker)
|
||||
|
||||
@JvmDefault
|
||||
fun putReifiedOperationMarkerIfTypeIsReifiedParameter(type: KotlinTypeMarker, operationKind: OperationKind) {
|
||||
with(typeSystem) {
|
||||
val (typeParameter, second) = extractReificationArgument(type) ?: return
|
||||
if (typeParameter.isReified()) {
|
||||
consumeReifiedOperationMarker(typeParameter)
|
||||
putReifiedOperationMarker(operationKind, second, visitor)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,6 +80,7 @@ import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor;
|
||||
import org.jetbrains.kotlin.types.*;
|
||||
import org.jetbrains.kotlin.types.checker.ClassicTypeSystemContextImpl;
|
||||
import org.jetbrains.kotlin.types.expressions.DoubleColonLHS;
|
||||
import org.jetbrains.kotlin.types.model.TypeParameterMarker;
|
||||
import org.jetbrains.kotlin.types.typesApproximation.CapturedTypeApproximationKt;
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions;
|
||||
import org.jetbrains.org.objectweb.asm.Label;
|
||||
@@ -123,7 +124,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
private final TailRecursionCodegen tailRecursionCodegen;
|
||||
public final CallGenerator defaultCallGenerator = new CallGenerator.DefaultCallGenerator(this);
|
||||
private final SwitchCodegenProvider switchCodegenProvider;
|
||||
public final TypeSystemCommonBackendContext typeSystem;
|
||||
private final TypeSystemCommonBackendContext typeSystem;
|
||||
|
||||
private final Stack<BlockStackElement> blockStackElements = new Stack<>();
|
||||
|
||||
@@ -2679,7 +2680,8 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
boolean isReified = key.isReified() || InlineUtil.isArrayConstructorWithLambda(resolvedCall.getResultingDescriptor());
|
||||
|
||||
Pair<TypeParameterDescriptor, ReificationArgument> typeParameterAndReificationArgument = extractReificationArgument(type);
|
||||
Pair<TypeParameterMarker, ReificationArgument> typeParameterAndReificationArgument =
|
||||
extractReificationArgument(typeSystem, type);
|
||||
if (typeParameterAndReificationArgument == null) {
|
||||
KotlinType approximatedType = CapturedTypeApproximationKt.approximateCapturedTypes(entry.getValue()).getUpper();
|
||||
// type is not generic
|
||||
@@ -4841,19 +4843,6 @@ The "returned" value of try expression with no finally is either the last expres
|
||||
});
|
||||
}
|
||||
|
||||
public void putReifiedOperationMarkerIfTypeIsReifiedParameter(
|
||||
@NotNull KotlinType type, @NotNull ReifiedTypeInliner.OperationKind operationKind
|
||||
) {
|
||||
Pair<TypeParameterDescriptor, ReificationArgument> typeParameterAndReificationArgument = extractReificationArgument(type);
|
||||
if (typeParameterAndReificationArgument == null) return;
|
||||
|
||||
TypeParameterDescriptor typeParameter = typeParameterAndReificationArgument.getFirst();
|
||||
if (typeParameter.isReified()) {
|
||||
consumeReifiedOperationMarker(typeParameter);
|
||||
ReifiedTypeInliner.putReifiedOperationMarker(operationKind, typeParameterAndReificationArgument.getSecond(), v);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void propagateChildReifiedTypeParametersUsages(@NotNull ReifiedTypeParametersUsages usages) {
|
||||
parentCodegen.getReifiedTypeParametersUsages().propagateChildUsagesWithinContext(
|
||||
@@ -5077,10 +5066,18 @@ The "returned" value of try expression with no finally is either the last expres
|
||||
return v;
|
||||
}
|
||||
|
||||
private void consumeReifiedOperationMarker(@NotNull TypeParameterDescriptor typeParameterDescriptor) {
|
||||
@NotNull
|
||||
@Override
|
||||
public TypeSystemCommonBackendContext getTypeSystem() {
|
||||
return typeSystem;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void consumeReifiedOperationMarker(@NotNull TypeParameterMarker typeParameter) {
|
||||
assert typeParameter instanceof TypeParameterDescriptor : "Type parameter should be a descriptor: " + typeParameter;
|
||||
TypeParameterDescriptor typeParameterDescriptor = (TypeParameterDescriptor) typeParameter;
|
||||
if (typeParameterDescriptor.getContainingDeclaration() != context.getContextDescriptor()) {
|
||||
parentCodegen.getReifiedTypeParametersUsages().
|
||||
addUsedReifiedParameter(typeParameterDescriptor.getName().asString());
|
||||
parentCodegen.getReifiedTypeParametersUsages().addUsedReifiedParameter(typeParameterDescriptor.getName().asString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,8 +51,11 @@ import org.jetbrains.kotlin.serialization.deserialization.descriptors.Deserializ
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedMemberDescriptor.CoroutinesCompatibilityMode
|
||||
import org.jetbrains.kotlin.types.ErrorUtils
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
||||
import org.jetbrains.kotlin.types.model.TypeParameterMarker
|
||||
import org.jetbrains.kotlin.utils.DFS
|
||||
import org.jetbrains.org.objectweb.asm.Label
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes.*
|
||||
@@ -381,18 +384,21 @@ fun InstructionAdapter.generateNewInstanceDupAndPlaceBeforeStackTop(
|
||||
}
|
||||
}
|
||||
|
||||
fun extractReificationArgument(initialType: KotlinType): Pair<TypeParameterDescriptor, ReificationArgument>? {
|
||||
fun TypeSystemCommonBackendContext.extractReificationArgument(initialType: KotlinTypeMarker): Pair<TypeParameterMarker, ReificationArgument>? {
|
||||
var type = initialType
|
||||
var arrayDepth = 0
|
||||
val isNullable = type.isMarkedNullable
|
||||
while (KotlinBuiltIns.isArray(type)) {
|
||||
val isNullable = type.isMarkedNullable()
|
||||
while (type.isArrayOrNullableArray()) {
|
||||
arrayDepth++
|
||||
type = type.arguments[0].type
|
||||
val argument = type.getArgument(0)
|
||||
type =
|
||||
if (argument.isStarProjection()) nullableAnyType()
|
||||
else argument.getType()
|
||||
}
|
||||
|
||||
val parameterDescriptor = TypeUtils.getTypeParameterDescriptorOrNull(type) ?: return null
|
||||
val typeParameter = type.typeConstructor().getTypeParameterClassifier() ?: return null
|
||||
|
||||
return Pair(parameterDescriptor, ReificationArgument(parameterDescriptor.name.asString(), isNullable, arrayDepth))
|
||||
return Pair(typeParameter, ReificationArgument(typeParameter.getName().asString(), isNullable, arrayDepth))
|
||||
}
|
||||
|
||||
fun unwrapInitialSignatureDescriptor(function: FunctionDescriptor): FunctionDescriptor =
|
||||
|
||||
Reference in New Issue
Block a user