Chromium Code Reviews| Index: runtime/vm/parser.cc |
| =================================================================== |
| --- runtime/vm/parser.cc (revision 27236) |
| +++ runtime/vm/parser.cc (working copy) |
| @@ -1904,7 +1904,55 @@ |
| op_arguments = BuildNoSuchMethodArguments( |
| operator_pos, operator_function_name, *op_arguments); |
| } |
| - super_op = new StaticCallNode(operator_pos, super_operator, op_arguments); |
| + if (super_operator.name() == Symbols::EqualOperator().raw()) { |
| + // Expand super.== call to match correct == semantics into: |
|
Kevin Millikin (Google)
2013/09/06 12:41:09
Is it better to expand this as:
let t1 = left, t2
Florian Schneider
2013/09/06 13:56:26
I'll leave it as is for now.
|
| + // Let t1 = left, t2 = right { |
| + // (t1 === null || t2 === null) ? t1 === t2 |
| + // : static_call(super.==, t1, t2) |
| + // } |
| + // Normal == calls are not expanded at the AST level to produce |
| + // more compact code and enable more optimization opportunities. |
| + ASSERT(!is_no_such_method); // == is always found. |
| + EnsureExpressionTemp(); // Needed for ConditionalExprNode. |
| + LetNode* result = new LetNode(operator_pos); |
| + AstNode* left = |
| + new LoadLocalNode(operator_pos, |
| + result->AddInitializer(op_arguments->NodeAt(0))); |
| + AstNode* right = |
| + new LoadLocalNode(operator_pos, |
| + result->AddInitializer(op_arguments->NodeAt(1))); |
| + LiteralNode* null_operand = |
| + new LiteralNode(operator_pos, Instance::ZoneHandle()); |
| + ComparisonNode* is_left_null = new ComparisonNode(operator_pos, |
| + Token::kEQ_STRICT, |
| + left, |
| + null_operand); |
| + ComparisonNode* is_right_null = new ComparisonNode(operator_pos, |
| + Token::kEQ_STRICT, |
| + right, |
| + null_operand); |
| + BinaryOpNode* null_check = new BinaryOpNode(operator_pos, |
| + Token::kOR, |
| + is_left_null, |
| + is_right_null); |
| + ArgumentListNode* new_arguments = new ArgumentListNode(operator_pos); |
| + new_arguments->Add(left); |
| + new_arguments->Add(right); |
| + StaticCallNode* call = new StaticCallNode(operator_pos, |
| + super_operator, |
| + new_arguments); |
| + ComparisonNode* strict_eq = new ComparisonNode(operator_pos, |
| + Token::kEQ_STRICT, |
| + left, |
| + right); |
| + result->AddNode(new ConditionalExprNode(operator_pos, |
| + null_check, |
| + strict_eq, |
| + call)); |
| + super_op = result; |
| + } else { |
| + super_op = new StaticCallNode(operator_pos, super_operator, op_arguments); |
| + } |
| if (negate_result) { |
| super_op = new UnaryOpNode(operator_pos, Token::kNOT, super_op); |
| } |