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());
Type receiverType = asmType(receiverJetType);
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());
Type type = propValue.type;
propValue.put(type, v);
@@ -1691,24 +1692,26 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
private StackValue generateElvis(JetBinaryExpression expression) {
final Type exprType = expressionType(expression);
final Type leftType = expressionType(expression.getLeft());
gen(expression.getLeft(), leftType);
if(leftType.getSort() != Type.OBJECT && leftType.getSort() != Type.ARRAY) {
if(leftType != exprType) {
StackValue.onStack(leftType).put(exprType, v);
}
return StackValue.onStack(exprType);
JetType type = bindingContext.get(BindingContext.EXPRESSION_TYPE, expression.getLeft());
assert type != null;
final Type leftType = asmType(type);
if(type.isNullable()) {
gen(expression.getLeft(), leftType);
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);
}
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);
}
@@ -95,16 +95,7 @@ public class JetTypeMapper {
}
public static boolean isPrimitive(Type type) {
return type == Type.INT_TYPE
|| 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;
return type.getSort() != Type.OBJECT && type.getSort() != Type.ARRAY;
}
public static Type getBoxedType(final Type type) {
@@ -303,6 +303,18 @@ public class PrimitiveTypesTest extends CodegenTestCase {
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 {
loadText("fun f(x: Long, zzz: Long = 1): Long\n" +
"{\n" +