JVM_IR: implement typeOf<T> as a codegen intrinsic
rather than a fake inline function. Also, generate more correct instructions for typeOf. Not sure how that even worked before - `aconst(Boolean)` isn't even valid.
This commit is contained in:
@@ -41,14 +41,11 @@ interface BaseExpressionCodegen {
|
||||
fun markLineNumberAfterInlineIfNeeded(registerLineNumberAfterwards: Boolean)
|
||||
|
||||
fun consumeReifiedOperationMarker(typeParameter: TypeParameterMarker)
|
||||
|
||||
fun putReifiedOperationMarkerIfTypeIsReifiedParameter(type: KotlinTypeMarker, operationKind: OperationKind) {
|
||||
with(typeSystem) {
|
||||
val (typeParameter, second) = extractReificationArgument(type) ?: return
|
||||
if (typeParameter.isReified()) {
|
||||
consumeReifiedOperationMarker(typeParameter)
|
||||
putReifiedOperationMarker(operationKind, second, visitor)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun BaseExpressionCodegen.putReifiedOperationMarkerIfTypeIsReifiedParameter(type: KotlinTypeMarker, operationKind: OperationKind): Boolean {
|
||||
val (typeParameter, second) = typeSystem.extractReificationArgument(type) ?: return false
|
||||
consumeReifiedOperationMarker(typeParameter)
|
||||
putReifiedOperationMarker(operationKind, second, visitor)
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -107,6 +107,7 @@ import java.util.stream.Collectors;
|
||||
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isInt;
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.boxType;
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
|
||||
import static org.jetbrains.kotlin.codegen.BaseExpressionCodegenKt.putReifiedOperationMarkerIfTypeIsReifiedParameter;
|
||||
import static org.jetbrains.kotlin.codegen.CodegenUtilKt.*;
|
||||
import static org.jetbrains.kotlin.codegen.DescriptorAsmUtil.boxType;
|
||||
import static org.jetbrains.kotlin.codegen.DescriptorAsmUtil.*;
|
||||
@@ -3555,7 +3556,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
if (TypeUtils.isTypeParameter(type)) {
|
||||
assert TypeUtils.isReifiedTypeParameter(type) :
|
||||
"Non-reified type parameter under ::class should be rejected by type checker: " + type;
|
||||
putReifiedOperationMarkerIfTypeIsReifiedParameter(type, ReifiedTypeInliner.OperationKind.JAVA_CLASS);
|
||||
putReifiedOperationMarkerIfTypeIsReifiedParameter(this, type, ReifiedTypeInliner.OperationKind.JAVA_CLASS);
|
||||
}
|
||||
|
||||
putJavaLangClassInstance(v, typeMapper.mapType(type), type, typeMapper);
|
||||
@@ -4928,10 +4929,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
public void newArrayInstruction(@NotNull KotlinType arrayType) {
|
||||
if (KotlinBuiltIns.isArray(arrayType)) {
|
||||
KotlinType elementJetType = arrayType.getArguments().get(0).getType();
|
||||
putReifiedOperationMarkerIfTypeIsReifiedParameter(
|
||||
elementJetType,
|
||||
ReifiedTypeInliner.OperationKind.NEW_ARRAY
|
||||
);
|
||||
putReifiedOperationMarkerIfTypeIsReifiedParameter(this, elementJetType, ReifiedTypeInliner.OperationKind.NEW_ARRAY);
|
||||
v.newarray(boxType(typeMapper.mapTypeAsDeclaration(elementJetType)));
|
||||
}
|
||||
else {
|
||||
@@ -5235,7 +5233,7 @@ The "returned" value of try expression with no finally is either the last expres
|
||||
|
||||
boolean safeAs = opToken == KtTokens.AS_SAFE;
|
||||
if (TypeUtils.isReifiedTypeParameter(rightKotlinType)) {
|
||||
putReifiedOperationMarkerIfTypeIsReifiedParameter(rightKotlinType,
|
||||
putReifiedOperationMarkerIfTypeIsReifiedParameter(this, rightKotlinType,
|
||||
safeAs ? ReifiedTypeInliner.OperationKind.SAFE_AS
|
||||
: ReifiedTypeInliner.OperationKind.AS);
|
||||
v.checkcast(boxedRightType);
|
||||
@@ -5292,7 +5290,7 @@ The "returned" value of try expression with no finally is either the last expres
|
||||
|
||||
Type type = boxType(typeMapper.mapTypeAsDeclaration(rhsKotlinType));
|
||||
if (TypeUtils.isReifiedTypeParameter(rhsKotlinType)) {
|
||||
putReifiedOperationMarkerIfTypeIsReifiedParameter(rhsKotlinType, ReifiedTypeInliner.OperationKind.IS);
|
||||
putReifiedOperationMarkerIfTypeIsReifiedParameter(this, rhsKotlinType, ReifiedTypeInliner.OperationKind.IS);
|
||||
v.instanceOf(type);
|
||||
return null;
|
||||
}
|
||||
@@ -5544,11 +5542,4 @@ The "returned" value of try expression with no finally is either the last expres
|
||||
parentCodegen.getReifiedTypeParametersUsages().addUsedReifiedParameter(typeParameterDescriptor.getName().asString());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putReifiedOperationMarkerIfTypeIsReifiedParameter(
|
||||
@NotNull KotlinTypeMarker type, @NotNull ReifiedTypeInliner.OperationKind operationKind
|
||||
) {
|
||||
BaseExpressionCodegen.DefaultImpls.putReifiedOperationMarkerIfTypeIsReifiedParameter(this, type, operationKind);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -393,13 +393,12 @@ fun TypeSystemCommonBackendContext.extractReificationArgument(initialType: Kotli
|
||||
while (type.isArrayOrNullableArray()) {
|
||||
arrayDepth++
|
||||
val argument = type.getArgument(0)
|
||||
type =
|
||||
if (argument.isStarProjection()) nullableAnyType()
|
||||
else argument.getType()
|
||||
if (argument.isStarProjection()) return null
|
||||
type = argument.getType()
|
||||
}
|
||||
|
||||
val typeParameter = type.typeConstructor().getTypeParameterClassifier() ?: return null
|
||||
|
||||
if (!typeParameter.isReified()) return null
|
||||
return Pair(typeParameter, ReificationArgument(typeParameter.getName().asString(), isNullable, arrayDepth))
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ private fun TypeSystemCommonBackendContext.putTypeOfReifiedTypeParameter(
|
||||
v.aconst(null)
|
||||
}
|
||||
|
||||
internal fun <KT : KotlinTypeMarker> TypeSystemCommonBackendContext.generateTypeOf(
|
||||
fun <KT : KotlinTypeMarker> TypeSystemCommonBackendContext.generateTypeOf(
|
||||
v: InstructionAdapter, type: KT, intrinsicsSupport: ReifiedTypeInliner.IntrinsicsSupport<KT>
|
||||
) {
|
||||
val typeParameter = type.typeConstructor().getTypeParameterClassifier()
|
||||
@@ -103,7 +103,7 @@ private fun <KT : KotlinTypeMarker> TypeSystemCommonBackendContext.generateNonRe
|
||||
TypeVariance.OUT -> KVariance.OUT
|
||||
}
|
||||
v.getstatic(K_VARIANCE.internalName, variance.name, K_VARIANCE.descriptor)
|
||||
v.aconst(typeParameter.isReified())
|
||||
v.iconst(if (typeParameter.isReified()) 1 else 0)
|
||||
v.invokestatic(
|
||||
REFLECTION, "typeParameter",
|
||||
Type.getMethodDescriptor(K_TYPE_PARAMETER, OBJECT_TYPE, JAVA_STRING_TYPE, K_VARIANCE, Type.BOOLEAN_TYPE),
|
||||
@@ -119,11 +119,11 @@ private fun <KT : KotlinTypeMarker> TypeSystemCommonBackendContext.generateNonRe
|
||||
if (bounds.size == 1) {
|
||||
generateTypeOf(v, bounds.single(), intrinsicsSupport)
|
||||
} else {
|
||||
v.aconst(bounds.size)
|
||||
v.iconst(bounds.size)
|
||||
v.newarray(K_TYPE)
|
||||
for ((i, bound) in bounds.withIndex()) {
|
||||
v.dup()
|
||||
v.aconst(i)
|
||||
v.iconst(i)
|
||||
generateTypeOf(v, bound, intrinsicsSupport)
|
||||
v.astore(K_TYPE)
|
||||
}
|
||||
|
||||
+1
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
||||
import org.jetbrains.kotlin.codegen.StackValue
|
||||
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner
|
||||
import org.jetbrains.kotlin.codegen.putReifiedOperationMarkerIfTypeIsReifiedParameter
|
||||
import org.jetbrains.kotlin.psi.KtClassLiteralExpression
|
||||
import org.jetbrains.kotlin.resolve.BindingContext.DOUBLE_COLON_LHS
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
|
||||
Reference in New Issue
Block a user