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

This commit is contained in:
Denis Zharkov
2014-06-27 12:04:33 +04:00
committed by Alexander Udalov
parent 11af678767
commit 69436b64fc
@@ -2600,36 +2600,52 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> 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<StackValue, StackValue> 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);