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:
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());
|
return genQualified(receiverValue, expression.getSelectorExpression());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private void generateExpressionWithNullFallback(@NotNull JetExpression expression, @NotNull Label ifnull) {
|
||||||
public StackValue visitSafeQualifiedExpression(@NotNull JetSafeQualifiedExpression expression, StackValue unused) {
|
Type type = expressionType(expression);
|
||||||
JetExpression receiver = expression.getReceiverExpression();
|
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();
|
JetExpression selector = expression.getSelectorExpression();
|
||||||
Type type = boxType(expressionType(expression));
|
|
||||||
Type receiverType = expressionType(receiver);
|
Type receiverType = expressionType(receiver);
|
||||||
|
|
||||||
gen(receiver, receiverType);
|
assert receiver != null : "receiver should be not null: " + expression.getText();
|
||||||
|
generateExpressionWithNullFallback(receiver, ifnull);
|
||||||
|
|
||||||
if (isPrimitive(receiverType)) {
|
if (isPrimitive(receiverType)) {
|
||||||
StackValue propValue = genQualified(StackValue.onStack(receiverType), selector);
|
return genQualified(StackValue.onStack(receiverType), selector);
|
||||||
propValue.put(type, v);
|
|
||||||
|
|
||||||
return StackValue.onStack(type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Label ifnull = new Label();
|
|
||||||
Label end = new Label();
|
|
||||||
v.dup();
|
v.dup();
|
||||||
v.ifnull(ifnull);
|
v.ifnull(ifnull);
|
||||||
StackValue propValue = genQualified(StackValue.onStack(receiverType), selector);
|
return genQualified(StackValue.onStack(receiverType), selector);
|
||||||
propValue.put(type, v);
|
}
|
||||||
v.goTo(end);
|
|
||||||
|
|
||||||
v.mark(ifnull);
|
@Override
|
||||||
v.pop();
|
public StackValue visitSafeQualifiedExpression(@NotNull JetSafeQualifiedExpression expression, StackValue unused) {
|
||||||
if (!type.equals(Type.VOID_TYPE)) {
|
Label ifnull = new Label();
|
||||||
v.aconst(null);
|
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);
|
return StackValue.onStack(type);
|
||||||
}
|
}
|
||||||
@@ -2829,21 +2845,27 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
|||||||
}
|
}
|
||||||
|
|
||||||
private StackValue generateElvis(JetBinaryExpression expression) {
|
private StackValue generateElvis(JetBinaryExpression expression) {
|
||||||
Type exprType = expressionType(expression);
|
JetExpression left = JetPsiUtil.deparenthesize(expression.getLeft());
|
||||||
Type leftType = expressionType(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)) {
|
if (isPrimitive(leftType)) {
|
||||||
return StackValue.onStack(leftType);
|
return StackValue.onStack(leftType);
|
||||||
}
|
}
|
||||||
|
|
||||||
v.dup();
|
v.dup();
|
||||||
Label ifNull = new Label();
|
|
||||||
v.ifnull(ifNull);
|
v.ifnull(ifNull);
|
||||||
StackValue.onStack(leftType).put(exprType, v);
|
StackValue.onStack(leftType).put(exprType, v);
|
||||||
Label end = new Label();
|
|
||||||
v.goTo(end);
|
v.goTo(end);
|
||||||
|
|
||||||
v.mark(ifNull);
|
v.mark(ifNull);
|
||||||
v.pop();
|
v.pop();
|
||||||
gen(expression.getRight(), exprType);
|
gen(expression.getRight(), exprType);
|
||||||
|
|||||||
Reference in New Issue
Block a user