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

Unified Diff: runtime/vm/flow_graph_builder.cc

Issue 9649012: Implement logical AND/OR. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 9 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/flow_graph_builder.h ('k') | runtime/vm/intermediate_language.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/flow_graph_builder.cc
===================================================================
--- runtime/vm/flow_graph_builder.cc (revision 5248)
+++ runtime/vm/flow_graph_builder.cc (working copy)
@@ -219,9 +219,18 @@
// Operators "&&" and "||" cannot be overloaded therefore do not call
// operator.
if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) {
- // Implement short-circuit logic: do not evaluate right if evaluation
- // of left is sufficient.
- Bailout("EffectGraphVisitor::VisitBinaryOpNode AND/OR");
+ // See ValueGraphVisitor::VisitBinaryOpNode.
+ TestGraphVisitor for_left(owner(), temp_index());
+ node->left()->Visit(&for_left);
+ EffectGraphVisitor for_right(owner(), temp_index());
+ node->right()->Visit(&for_right);
+ EffectGraphVisitor empty(owner(), temp_index());
+ if (node->kind() == Token::kAND) {
+ Join(for_left, for_right, empty);
+ } else {
+ Join(for_left, empty, for_right);
+ }
+ return;
}
ArgumentGraphVisitor for_left_value(owner(), temp_index());
node->left()->Visit(&for_left_value);
@@ -240,6 +249,49 @@
}
+// Special handling for AND/OR.
+void ValueGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) {
+ // Operators "&&" and "||" cannot be overloaded therefore do not call
+ // operator.
+ if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) {
+ // Implement short-circuit logic: do not evaluate right if evaluation
+ // of left is sufficient.
+ // AND: left ? right === true : false;
+ // OR: left ? true : right === true;
+ if (FLAG_enable_type_checks) {
+ Bailout("GenerateConditionTypeCheck in kAND/kOR");
+ }
+ const Bool& bool_true = Bool::ZoneHandle(Bool::True());
+ const Bool& bool_false = Bool::ZoneHandle(Bool::False());
+
+ TestGraphVisitor for_test(owner(), temp_index());
+ node->left()->Visit(&for_test);
+
+ ValueGraphVisitor for_right(owner(), temp_index());
+ node->right()->Visit(&for_right);
+ StrictCompareComp* comp = new StrictCompareComp(Token::kEQ_STRICT,
+ for_right.value(), new ConstantVal(bool_true));
+ for_right.AddInstruction(new BindInstr(temp_index(), comp));
+
+ if (node->kind() == Token::kAND) {
+ ValueGraphVisitor for_false(owner(), temp_index());
+ for_false.AddInstruction(
+ new BindInstr(temp_index(), new ConstantVal(bool_false)));
+ Join(for_test, for_right, for_false);
+ } else {
+ ASSERT(node->kind() == Token::kOR);
+ ValueGraphVisitor for_true(owner(), temp_index());
+ for_true.AddInstruction(
+ new BindInstr(temp_index(), new ConstantVal(bool_true)));
+ Join(for_test, for_true, for_right);
+ }
+ ReturnValue(new TempVal(AllocateTempIndex()));
+ return;
+ }
+ EffectGraphVisitor::VisitBinaryOpNode(node);
+}
+
+
void EffectGraphVisitor::VisitStringConcatNode(StringConcatNode* node) {
Bailout("EffectGraphVisitor::VisitStringConcatNode");
}
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | runtime/vm/intermediate_language.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698