From 69436b64fc9823c12c73804c747dbeae1de5dfa7 Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Fri, 27 Jun 2014 12:04:33 +0400 Subject: [PATCH] Specialized code generation for safe qualified expression when it's within elvis or another safe-call. In such cases instead of generating ACONST_NULL, if reciever is null, just fall back to null-handler's label of the outer expression --- .../jet/codegen/ExpressionCodegen.java | 70 ++++++++++++------- 1 file changed, 46 insertions(+), 24 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index be168b2783c..8a0e59968e6 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -2600,36 +2600,52 @@ public class ExpressionCodegen extends JetVisitor implem return genQualified(receiverValue, expression.getSelectorExpression()); } - @Override - public StackValue visitSafeQualifiedExpression(@NotNull JetSafeQualifiedExpression expression, StackValue unused) { - JetExpression receiver = expression.getReceiverExpression(); + private void generateExpressionWithNullFallback(@NotNull JetExpression expression, @NotNull Label ifnull) { + Type type = expressionType(expression); + if (expression instanceof JetSafeQualifiedExpression && !isPrimitive(type)) { + StackValue value = generateSafeQualifiedExpression((JetSafeQualifiedExpression) expression, ifnull); + value.put(type, v); + } + else { + gen(expression, type); + } + } + + private StackValue generateSafeQualifiedExpression(@NotNull JetSafeQualifiedExpression expression, @NotNull Label ifnull) { + JetExpression receiver = JetPsiUtil.deparenthesize(expression.getReceiverExpression()); JetExpression selector = expression.getSelectorExpression(); - Type type = boxType(expressionType(expression)); Type receiverType = expressionType(receiver); - gen(receiver, receiverType); + assert receiver != null : "receiver should be not null: " + expression.getText(); + generateExpressionWithNullFallback(receiver, ifnull); if (isPrimitive(receiverType)) { - StackValue propValue = genQualified(StackValue.onStack(receiverType), selector); - propValue.put(type, v); - - return StackValue.onStack(type); + return genQualified(StackValue.onStack(receiverType), selector); } - Label ifnull = new Label(); - Label end = new Label(); v.dup(); v.ifnull(ifnull); - StackValue propValue = genQualified(StackValue.onStack(receiverType), selector); - propValue.put(type, v); - v.goTo(end); + return genQualified(StackValue.onStack(receiverType), selector); + } - v.mark(ifnull); - v.pop(); - if (!type.equals(Type.VOID_TYPE)) { - v.aconst(null); + @Override + public StackValue visitSafeQualifiedExpression(@NotNull JetSafeQualifiedExpression expression, StackValue unused) { + Label ifnull = new Label(); + Label end = new Label(); + Type type = boxType(expressionType(expression)); + + StackValue value = generateSafeQualifiedExpression(expression, ifnull); + value.put(type, v); + + if (!isPrimitive(expressionType(expression.getReceiverExpression()))) { + v.goTo(end); + v.mark(ifnull); + v.pop(); + if (!type.equals(Type.VOID_TYPE)) { + v.aconst(null); + } + v.mark(end); } - v.mark(end); return StackValue.onStack(type); } @@ -2829,21 +2845,27 @@ public class ExpressionCodegen extends JetVisitor implem } private StackValue generateElvis(JetBinaryExpression expression) { - Type exprType = expressionType(expression); - Type leftType = expressionType(expression.getLeft()); + JetExpression left = JetPsiUtil.deparenthesize(expression.getLeft()); - gen(expression.getLeft(), leftType); + Type exprType = expressionType(expression); + Type leftType = expressionType(left); + + Label ifNull = new Label(); + Label end = new Label(); + + assert left != null : "left expression in elvis should be not null: " + expression.getText(); + generateExpressionWithNullFallback(left, ifNull); if (isPrimitive(leftType)) { return StackValue.onStack(leftType); } v.dup(); - Label ifNull = new Label(); + v.ifnull(ifNull); StackValue.onStack(leftType).put(exprType, v); - Label end = new Label(); v.goTo(end); + v.mark(ifNull); v.pop(); gen(expression.getRight(), exprType);