'when' should use intrinsics for '=='
#KT-19029 Fixed Target versions 1.1.5 #KT-18818 Fixed Target versions 1.1.5
This commit is contained in:
@@ -152,14 +152,6 @@ public class AsmUtil {
|
||||
return isIntPrimitive(type) || type == Type.LONG_TYPE;
|
||||
}
|
||||
|
||||
public static boolean isNumberPrimitiveOrBoolean(Type type) {
|
||||
return isNumberPrimitive(type) || type.getSort() == Type.BOOLEAN;
|
||||
}
|
||||
|
||||
public static boolean isNumberPrimitive(Type type) {
|
||||
return isIntPrimitive(type) || type == Type.FLOAT_TYPE || type == Type.DOUBLE_TYPE || type == Type.LONG_TYPE;
|
||||
}
|
||||
|
||||
public static boolean isPrimitive(Type type) {
|
||||
return type.getSort() != Type.OBJECT && type.getSort() != Type.ARRAY;
|
||||
}
|
||||
|
||||
@@ -2840,7 +2840,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
}
|
||||
else if (opToken == KtTokens.EQEQ || opToken == KtTokens.EXCLEQ ||
|
||||
opToken == KtTokens.EQEQEQ || opToken == KtTokens.EXCLEQEQEQ) {
|
||||
return generateEquals(expression.getLeft(), expression.getRight(), opToken);
|
||||
return generateEquals(expression.getLeft(), expression.getRight(), opToken, null);
|
||||
}
|
||||
else if (opToken == KtTokens.LT || opToken == KtTokens.LTEQ ||
|
||||
opToken == KtTokens.GT || opToken == KtTokens.GTEQ) {
|
||||
@@ -2885,44 +2885,76 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
return StackValue.or(gen(expression.getLeft()), gen(expression.getRight()));
|
||||
}
|
||||
|
||||
private StackValue generateEquals(@Nullable KtExpression left, @Nullable KtExpression right, @NotNull IElementType opToken) {
|
||||
private StackValue genLazyUnlessProvided(@Nullable StackValue pregenerated, @NotNull KtExpression expr, @NotNull Type type) {
|
||||
return pregenerated != null ? StackValue.coercion(pregenerated, type) : genLazy(expr, type);
|
||||
}
|
||||
|
||||
private StackValue genUnlessProvided(@Nullable StackValue pregenerated, @NotNull KtExpression expr, @NotNull Type type) {
|
||||
if (pregenerated != null) {
|
||||
pregenerated.put(type, v);
|
||||
}
|
||||
else {
|
||||
gen(expr, type);
|
||||
}
|
||||
return StackValue.onStack(type);
|
||||
}
|
||||
|
||||
private StackValue generateEquals(
|
||||
@Nullable KtExpression left,
|
||||
@Nullable KtExpression right,
|
||||
@NotNull IElementType opToken,
|
||||
@Nullable StackValue pregeneratedLeft
|
||||
) {
|
||||
Type leftType = expressionType(left);
|
||||
Type rightType = expressionType(right);
|
||||
|
||||
if (KtPsiUtil.isNullConstant(left)) {
|
||||
return genCmpWithNull(right, opToken);
|
||||
return genCmpWithNull(right, opToken, null);
|
||||
}
|
||||
|
||||
if (KtPsiUtil.isNullConstant(right)) {
|
||||
return genCmpWithNull(left, opToken);
|
||||
return genCmpWithNull(left, opToken, pregeneratedLeft);
|
||||
}
|
||||
|
||||
if (isIntZero(left, leftType) && isIntPrimitive(rightType)) {
|
||||
return genCmpWithZero(right, opToken);
|
||||
return genCmpWithZero(right, opToken, null);
|
||||
}
|
||||
|
||||
if (isIntZero(right, rightType) && isIntPrimitive(leftType)) {
|
||||
return genCmpWithZero(left, opToken);
|
||||
return genCmpWithZero(left, opToken, pregeneratedLeft);
|
||||
}
|
||||
|
||||
if (left instanceof KtSafeQualifiedExpression && isPrimitive(rightType)) {
|
||||
if (pregeneratedLeft == null && left instanceof KtSafeQualifiedExpression && isPrimitive(rightType)) {
|
||||
return genCmpSafeCallToPrimitive((KtSafeQualifiedExpression) left, right, rightType, opToken);
|
||||
}
|
||||
|
||||
if (isPrimitive(leftType) && right instanceof KtSafeQualifiedExpression) {
|
||||
return genCmpPrimitiveToSafeCall(left, leftType, (KtSafeQualifiedExpression) right, opToken);
|
||||
return genCmpPrimitiveToSafeCall(left, leftType, (KtSafeQualifiedExpression) right, opToken, pregeneratedLeft);
|
||||
}
|
||||
|
||||
if (BoxedToPrimitiveEquality.isApplicable(opToken, leftType, rightType)) {
|
||||
return BoxedToPrimitiveEquality.create(opToken, genLazy(left, leftType), leftType, genLazy(right, rightType), rightType,
|
||||
myFrameMap);
|
||||
return BoxedToPrimitiveEquality.create(
|
||||
opToken,
|
||||
genLazyUnlessProvided(pregeneratedLeft, left, leftType), leftType,
|
||||
genLazy(right, rightType), rightType,
|
||||
myFrameMap
|
||||
);
|
||||
}
|
||||
|
||||
if (PrimitiveToBoxedEquality.isApplicable(opToken, leftType, rightType)) {
|
||||
return PrimitiveToBoxedEquality.create(opToken, genLazy(left, leftType), leftType, genLazy(right, rightType), rightType);
|
||||
return PrimitiveToBoxedEquality.create(
|
||||
opToken,
|
||||
genLazyUnlessProvided(pregeneratedLeft, left, leftType), leftType,
|
||||
genLazy(right, rightType), rightType
|
||||
);
|
||||
}
|
||||
|
||||
if (PrimitiveToObjectEquality.isApplicable(opToken, leftType, rightType)) {
|
||||
return PrimitiveToObjectEquality.create(opToken, genLazy(left, leftType), leftType, genLazy(right, rightType), rightType);
|
||||
return PrimitiveToObjectEquality.create(
|
||||
opToken,
|
||||
genLazyUnlessProvided(pregeneratedLeft, left, leftType), leftType,
|
||||
genLazy(right, rightType), rightType
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -2934,23 +2966,29 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
if (opToken == KtTokens.EQEQEQ || opToken == KtTokens.EXCLEQEQEQ) {
|
||||
// TODO: always casting to the type of the left operand in case of primitives looks wrong
|
||||
Type operandType = isPrimitive(leftType) ? leftType : OBJECT_TYPE;
|
||||
return StackValue.cmp(opToken, operandType, genLazy(left, leftType), genLazy(right, rightType));
|
||||
return StackValue.cmp(
|
||||
opToken,
|
||||
operandType,
|
||||
genLazyUnlessProvided(pregeneratedLeft, left, leftType),
|
||||
genLazy(right, rightType)
|
||||
);
|
||||
}
|
||||
|
||||
return genEqualsForExpressionsPreferIEEE754Arithmetic(left, right, opToken, leftType, rightType, null);
|
||||
return genEqualsForExpressionsPreferIEEE754Arithmetic(left, right, opToken, leftType, rightType, pregeneratedLeft);
|
||||
}
|
||||
|
||||
private StackValue genCmpPrimitiveToSafeCall(
|
||||
@NotNull KtExpression left,
|
||||
@NotNull Type leftType,
|
||||
@NotNull KtSafeQualifiedExpression right,
|
||||
@NotNull IElementType opToken
|
||||
@NotNull IElementType opToken,
|
||||
@Nullable StackValue pregeneratedLeft
|
||||
) {
|
||||
Label rightIsNull = new Label();
|
||||
return new PrimitiveToSafeCallEquality(
|
||||
opToken,
|
||||
leftType,
|
||||
genLazy(left, leftType),
|
||||
genLazyUnlessProvided(pregeneratedLeft, left, leftType),
|
||||
generateSafeQualifiedExpression(right, rightIsNull),
|
||||
expressionType(right.getReceiverExpression()),
|
||||
rightIsNull
|
||||
@@ -3011,7 +3049,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
return genEqualsForExpressionsOnStack(
|
||||
opToken,
|
||||
pregeneratedLeft != null ? StackValue.coercion(pregeneratedLeft, leftType) : genLazy(left, leftType),
|
||||
genLazyUnlessProvided(pregeneratedLeft, left, leftType),
|
||||
genLazy(right, rightType)
|
||||
);
|
||||
}
|
||||
@@ -3027,12 +3065,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
) {
|
||||
Type leftType = left754Type.isNullable ? AsmUtil.boxType(left754Type.type) : left754Type.type;
|
||||
|
||||
if (pregeneratedLeft != null) {
|
||||
StackValue.coercion(pregeneratedLeft, leftType).put(leftType, v);
|
||||
}
|
||||
else {
|
||||
gen(left, leftType);
|
||||
}
|
||||
genUnlessProvided(pregeneratedLeft, left, leftType);
|
||||
Type rightType = right754Type.isNullable ? AsmUtil.boxType(right754Type.type) : right754Type.type;
|
||||
gen(right, rightType);
|
||||
|
||||
@@ -3141,12 +3174,18 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
return isIntPrimitive(exprType) && exprValue != null && Integer.valueOf(0).equals(exprValue.getValue());
|
||||
}
|
||||
|
||||
private StackValue genCmpWithZero(KtExpression exp, IElementType opToken) {
|
||||
return StackValue.compareIntWithZero(gen(exp), (KtTokens.EQEQ == opToken || KtTokens.EQEQEQ == opToken) ? IFNE : IFEQ);
|
||||
private StackValue genCmpWithZero(KtExpression exp, IElementType opToken, @Nullable StackValue pregeneratedExpr) {
|
||||
return StackValue.compareIntWithZero(
|
||||
pregeneratedExpr != null ? pregeneratedExpr : gen(exp),
|
||||
(KtTokens.EQEQ == opToken || KtTokens.EQEQEQ == opToken) ? IFNE : IFEQ
|
||||
);
|
||||
}
|
||||
|
||||
private StackValue genCmpWithNull(KtExpression exp, IElementType opToken) {
|
||||
return StackValue.compareWithNull(gen(exp), (KtTokens.EQEQ == opToken || KtTokens.EQEQEQ == opToken) ? IFNONNULL : IFNULL);
|
||||
private StackValue genCmpWithNull(KtExpression exp, IElementType opToken, @Nullable StackValue pregeneratedExpr) {
|
||||
return StackValue.compareWithNull(
|
||||
pregeneratedExpr != null ? pregeneratedExpr : gen(exp),
|
||||
(KtTokens.EQEQ == opToken || KtTokens.EQEQEQ == opToken) ? IFNONNULL : IFNULL
|
||||
);
|
||||
}
|
||||
|
||||
private StackValue generateElvis(@NotNull KtBinaryExpression expression) {
|
||||
@@ -4010,22 +4049,7 @@ The "returned" value of try expression with no finally is either the last expres
|
||||
|
||||
private StackValue generateExpressionMatch(StackValue expressionToMatch, KtExpression subjectExpression, KtExpression patternExpression) {
|
||||
if (expressionToMatch != null) {
|
||||
Type subjectType = expressionToMatch.type;
|
||||
markStartLineNumber(patternExpression);
|
||||
KotlinType condJetType = bindingContext.getType(patternExpression);
|
||||
Type condType;
|
||||
if (isNumberPrimitiveOrBoolean(subjectType)) {
|
||||
assert condJetType != null;
|
||||
condType = asmType(condJetType);
|
||||
if (!isNumberPrimitiveOrBoolean(condType)) {
|
||||
subjectType = boxType(subjectType);
|
||||
}
|
||||
}
|
||||
else {
|
||||
condType = OBJECT_TYPE;
|
||||
}
|
||||
|
||||
return genEqualsForExpressionsPreferIEEE754Arithmetic(subjectExpression, patternExpression, KtTokens.EQEQ, subjectType, condType, expressionToMatch);
|
||||
return generateEquals(subjectExpression, patternExpression, KtTokens.EQEQ, expressionToMatch);
|
||||
}
|
||||
else {
|
||||
return gen(patternExpression);
|
||||
|
||||
Reference in New Issue
Block a user