Generate is check for inline classes same as for primitives
Should be improved when inline class is based on non-null reference
This commit is contained in:
@@ -4369,20 +4369,20 @@ The "returned" value of try expression with no finally is either the last expres
|
||||
}
|
||||
|
||||
private StackValue generateIsCheck(StackValue expressionToMatch, KtTypeReference typeReference, boolean negated) {
|
||||
KotlinType jetType = bindingContext.get(TYPE, typeReference);
|
||||
KotlinType kotlinType = bindingContext.get(TYPE, typeReference);
|
||||
markStartLineNumber(typeReference);
|
||||
StackValue value = generateIsCheck(expressionToMatch, jetType, false);
|
||||
StackValue value = generateIsCheck(expressionToMatch, kotlinType, false);
|
||||
return negated ? StackValue.not(value) : value;
|
||||
}
|
||||
|
||||
private StackValue generateIsCheck(StackValue expressionToGen, KotlinType kotlinType, boolean leaveExpressionOnStack) {
|
||||
return StackValue.operation(Type.BOOLEAN_TYPE, v -> {
|
||||
expressionToGen.put(OBJECT_TYPE, null, v);
|
||||
expressionToGen.put(OBJECT_TYPE, kotlinType, v);
|
||||
if (leaveExpressionOnStack) {
|
||||
v.dup();
|
||||
}
|
||||
|
||||
Type type = boxType(asmType(kotlinType));
|
||||
Type type = boxType(typeMapper.mapTypeAsDeclaration(kotlinType));
|
||||
if (TypeUtils.isReifiedTypeParameter(kotlinType)) {
|
||||
putReifiedOperationMarkerIfTypeIsReifiedParameter(kotlinType, ReifiedTypeInliner.OperationKind.IS);
|
||||
v.instanceOf(type);
|
||||
|
||||
@@ -399,12 +399,12 @@ public abstract class StackValue {
|
||||
);
|
||||
}
|
||||
|
||||
private static void unboxInlineClass(@NotNull Type type, @NotNull KotlinType kotlinType, @NotNull InstructionAdapter v) {
|
||||
Type owner = KotlinTypeMapper.mapInlineClassTypeAsDeclaration(kotlinType);
|
||||
private static void unboxInlineClass(@NotNull Type type, @NotNull KotlinType targetInlineClassType, @NotNull InstructionAdapter v) {
|
||||
Type owner = KotlinTypeMapper.mapInlineClassTypeAsDeclaration(targetInlineClassType);
|
||||
|
||||
coerce(type, owner, v);
|
||||
|
||||
Type resultType = KotlinTypeMapper.mapUnderlyingTypeOfInlineClassType(kotlinType);
|
||||
Type resultType = KotlinTypeMapper.mapUnderlyingTypeOfInlineClassType(targetInlineClassType);
|
||||
v.invokevirtual(
|
||||
owner.getInternalName(),
|
||||
InlineClassDescriptorResolver.UNBOX_METHOD_NAME.asString(),
|
||||
@@ -440,25 +440,34 @@ public abstract class StackValue {
|
||||
@NotNull InstructionAdapter v
|
||||
) {
|
||||
if (fromKotlinType == null || toKotlinType == null) return false;
|
||||
if (!InlineClassesUtilsKt.isInlineClassType(fromKotlinType)) return false;
|
||||
|
||||
boolean isFromTypeInlineClass = InlineClassesUtilsKt.isInlineClassType(fromKotlinType);
|
||||
boolean isToTypeInlineClass = InlineClassesUtilsKt.isInlineClassType(toKotlinType);
|
||||
|
||||
if (!isFromTypeInlineClass && !isToTypeInlineClass) return false;
|
||||
|
||||
if (fromKotlinType.equals(toKotlinType) && fromType.equals(toType)) return true;
|
||||
|
||||
boolean isFromTypeUnboxed = isUnboxedInlineClass(fromKotlinType, fromType);
|
||||
if (InlineClassesUtilsKt.isInlineClassType(toKotlinType)) {
|
||||
if (isFromTypeInlineClass && isToTypeInlineClass) {
|
||||
boolean isFromTypeUnboxed = isUnboxedInlineClass(fromKotlinType, fromType);
|
||||
boolean isToTypeUnboxed = isUnboxedInlineClass(toKotlinType, toType);
|
||||
if (isFromTypeUnboxed && !isToTypeUnboxed) {
|
||||
boxInlineClass(fromKotlinType, v);
|
||||
}
|
||||
else if (!isFromTypeUnboxed && isToTypeUnboxed) {
|
||||
unboxInlineClass(fromType, fromKotlinType, v);
|
||||
unboxInlineClass(fromType, toKotlinType, v);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (isFromTypeUnboxed) {
|
||||
else if (isFromTypeInlineClass) {
|
||||
if (isUnboxedInlineClass(fromKotlinType, fromType)) {
|
||||
boxInlineClass(fromKotlinType, v);
|
||||
}
|
||||
}
|
||||
else { // isToTypeInlineClass is `true`
|
||||
if (isUnboxedInlineClass(toKotlinType, toType)) {
|
||||
unboxInlineClass(fromType, toKotlinType, v);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1549,14 +1558,14 @@ public abstract class StackValue {
|
||||
private final ExpressionCodegen generator;
|
||||
|
||||
public Expression(Type type, KtExpression expression, ExpressionCodegen generator) {
|
||||
super(type);
|
||||
super(type, generator.kotlinType(expression));
|
||||
this.expression = expression;
|
||||
this.generator = generator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putSelector(@NotNull Type type, @Nullable KotlinType kotlinType, @NotNull InstructionAdapter v) {
|
||||
generator.gen(expression, type);
|
||||
generator.gen(expression, type, kotlinType);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user