From 90367ab138094b2de791a7ff072c7363868ed90c Mon Sep 17 00:00:00 2001 From: Alex Tkachman Date: Sat, 3 Dec 2011 19:26:21 +0200 Subject: [PATCH] optimized ?. in non-nullable case --- .../jet/codegen/ExpressionCodegen.java | 39 ++++++++++--------- .../jetbrains/jet/codegen/JetTypeMapper.java | 11 +----- .../jet/codegen/PrimitiveTypesTest.java | 12 ++++++ 3 files changed, 34 insertions(+), 28 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 50fc7ea2a96..e77bf07342d 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -1377,7 +1377,8 @@ public class ExpressionCodegen extends JetVisitor { 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 { 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); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java index 16a49a0d746..c51d21d7801 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java @@ -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) { diff --git a/compiler/tests/org/jetbrains/jet/codegen/PrimitiveTypesTest.java b/compiler/tests/org/jetbrains/jet/codegen/PrimitiveTypesTest.java index 42be29b03b2..bb38c2d8e1b 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/PrimitiveTypesTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/PrimitiveTypesTest.java @@ -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" +