Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(485)

Unified Diff: runtime/vm/parser.cc

Issue 24203004: Dart VM: Simplify code generation for equality operators. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: rebased Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/parser.h ('k') | runtime/vm/stub_code.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/parser.cc
===================================================================
--- runtime/vm/parser.cc (revision 28079)
+++ runtime/vm/parser.cc (working copy)
@@ -1923,55 +1923,7 @@
op_arguments = BuildNoSuchMethodArguments(
operator_pos, operator_function_name, *op_arguments);
}
- if (super_operator.name() == Symbols::EqualOperator().raw()) {
- // Expand super.== call to match correct == semantics into:
- // 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);
- }
+ super_op = new StaticCallNode(operator_pos, super_operator, op_arguments);
if (negate_result) {
super_op = new UnaryOpNode(operator_pos, Token::kNOT, super_op);
}
@@ -2879,17 +2831,35 @@
intptr_t end_token_pos = 0;
if (CurrentToken() == Token::kLBRACE) {
ConsumeToken();
+ if (String::Handle(func.name()).Equals(Symbols::EqualOperator())) {
+ const Class& owner = Class::Handle(func.Owner());
+ if (!owner.IsObjectClass()) {
+ AddEqualityNullCheck();
+ }
+ }
ParseStatementSequence();
end_token_pos = TokenPos();
ExpectToken(Token::kRBRACE);
} else if (CurrentToken() == Token::kARROW) {
ConsumeToken();
+ if (String::Handle(func.name()).Equals(Symbols::EqualOperator())) {
+ const Class& owner = Class::Handle(func.Owner());
+ if (!owner.IsObjectClass()) {
+ AddEqualityNullCheck();
+ }
+ }
const intptr_t expr_pos = TokenPos();
AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades);
ASSERT(expr != NULL);
current_block_->statements->Add(new ReturnNode(expr_pos, expr));
end_token_pos = TokenPos();
} else if (IsLiteral("native")) {
+ if (String::Handle(func.name()).Equals(Symbols::EqualOperator())) {
+ const Class& owner = Class::Handle(func.Owner());
+ if (!owner.IsObjectClass()) {
+ AddEqualityNullCheck();
+ }
+ }
ParseNativeFunctionBlock(&params, func);
end_token_pos = TokenPos();
ExpectSemicolon();
@@ -2924,6 +2894,31 @@
}
+void Parser::AddEqualityNullCheck() {
+ const intptr_t token_pos = Scanner::kDummyTokenIndex;
+ AstNode* argument =
+ new LoadLocalNode(token_pos,
+ current_block_->scope->parent()->VariableAt(1));
+ LiteralNode* null_operand =
+ new LiteralNode(token_pos, Instance::ZoneHandle());
+ ComparisonNode* check_arg = new ComparisonNode(token_pos,
+ Token::kEQ_STRICT,
+ argument,
+ null_operand);
+ ComparisonNode* result = new ComparisonNode(token_pos,
+ Token::kEQ_STRICT,
+ LoadReceiver(token_pos),
+ null_operand);
+ SequenceNode* arg_is_null = new SequenceNode(token_pos, NULL);
+ arg_is_null->Add(new ReturnNode(token_pos, result));
+ IfNode* if_arg_null = new IfNode(token_pos,
+ check_arg,
+ arg_is_null,
+ NULL);
+ current_block_->statements->Add(if_arg_null);
+}
+
+
void Parser::SkipIf(Token::Kind token) {
if (CurrentToken() == token) {
ConsumeToken();
« no previous file with comments | « runtime/vm/parser.h ('k') | runtime/vm/stub_code.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698