optimized ?. in non-nullable case

This commit is contained in:
Alex Tkachman
2011-12-03 19:26:21 +02:00
parent d8e6c18cfe
commit 90367ab138
3 changed files with 34 additions and 28 deletions
@@ -1377,7 +1377,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
JetType receiverJetType = bindingContext.get(BindingContext.EXPRESSION_TYPE, expression.getReceiverExpression()); JetType receiverJetType = bindingContext.get(BindingContext.EXPRESSION_TYPE, expression.getReceiverExpression());
Type receiverType = asmType(receiverJetType); Type receiverType = asmType(receiverJetType);
gen(expr, receiverType); gen(expr, receiverType);
if(receiverType.getSort() != Type.OBJECT && receiverType.getSort() != Type.ARRAY) { assert receiverJetType != null;
if(!receiverJetType.isNullable()) {
StackValue propValue = genQualified(StackValue.onStack(receiverType), expression.getSelectorExpression()); StackValue propValue = genQualified(StackValue.onStack(receiverType), expression.getSelectorExpression());
Type type = propValue.type; Type type = propValue.type;
propValue.put(type, v); propValue.put(type, v);
@@ -1691,24 +1692,26 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
private StackValue generateElvis(JetBinaryExpression expression) { private StackValue generateElvis(JetBinaryExpression expression) {
final Type exprType = expressionType(expression); final Type exprType = expressionType(expression);
final Type leftType = expressionType(expression.getLeft()); JetType type = bindingContext.get(BindingContext.EXPRESSION_TYPE, expression.getLeft());
gen(expression.getLeft(), leftType); assert type != null;
if(leftType.getSort() != Type.OBJECT && leftType.getSort() != Type.ARRAY) { final Type leftType = asmType(type);
if(leftType != exprType) { if(type.isNullable()) {
StackValue.onStack(leftType).put(exprType, v); gen(expression.getLeft(), leftType);
} v.dup();
return StackValue.onStack(exprType); Label end = new Label();
Label ifNull = new Label();
v.ifnull(ifNull);
StackValue.onStack(leftType).put(exprType, v);
v.goTo(end);
v.mark(ifNull);
v.pop();
gen(expression.getRight(), exprType);
v.mark(end);
}
else {
gen(expression.getLeft(), leftType);
StackValue.onStack(leftType).put(exprType, v);
} }
v.dup();
Label end = new Label();
Label ifNull = new Label();
v.ifnull(ifNull);
StackValue.onStack(leftType).put(exprType, v);
v.goTo(end);
v.mark(ifNull);
v.pop();
gen(expression.getRight(), exprType);
v.mark(end);
return StackValue.onStack(exprType); return StackValue.onStack(exprType);
} }
@@ -95,16 +95,7 @@ public class JetTypeMapper {
} }
public static boolean isPrimitive(Type type) { public static boolean isPrimitive(Type type) {
return type == Type.INT_TYPE return type.getSort() != Type.OBJECT && type.getSort() != Type.ARRAY;
|| type == Type.SHORT_TYPE
|| type == Type.BYTE_TYPE
|| type == Type.CHAR_TYPE
|| type == Type.SHORT_TYPE
|| type == Type.FLOAT_TYPE
|| type == Type.DOUBLE_TYPE
|| type == Type.LONG_TYPE
|| type == Type.BOOLEAN_TYPE
|| type == Type.VOID_TYPE;
} }
public static Type getBoxedType(final Type type) { public static Type getBoxedType(final Type type) {
@@ -303,6 +303,18 @@ public class PrimitiveTypesTest extends CodegenTestCase {
assertTrue(generateToText().contains("IFNONNULL")); assertTrue(generateToText().contains("IFNONNULL"));
} }
public void testSafeNonnull () throws Exception {
loadText("fun box() = 10?.toString()");
// System.out.println(generateToText());
assertFalse(generateToText().contains("IFNULL"));
}
public void testSafeNullable () throws Exception {
loadText("val a : Int? = 10; fun box() = a?.toString()");
// System.out.println(generateToText());
assertTrue(generateToText().contains("IFNULL"));
}
public void testKt665() throws Exception { public void testKt665() throws Exception {
loadText("fun f(x: Long, zzz: Long = 1): Long\n" + loadText("fun f(x: Long, zzz: Long = 1): Long\n" +
"{\n" + "{\n" +