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

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') | no next file » | 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 5196)
+++ runtime/vm/flow_graph_builder.cc (working copy)
@@ -219,9 +219,21 @@
// 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_test(owner(), temp_index());
+ node->left()->Visit(&for_test);
+ if (node->kind() == Token::kAND) {
Kevin Millikin (Google) 2012/03/09 12:29:14 Maybe too cute is to write: EffectGraphVisitor fo
srdjan 2012/03/09 19:47:41 Done.
+ EffectGraphVisitor for_true(owner(), temp_index());
+ node->right()->Visit(&for_true);
+ EffectGraphVisitor for_false(owner(), temp_index());
+ Join(for_test, for_true, for_false);
+ } else {
+ EffectGraphVisitor for_true(owner(), temp_index());
+ EffectGraphVisitor for_false(owner(), temp_index());
+ node->right()->Visit(&for_false);
+ Join(for_test, for_true, for_false);
+ }
+ return;
}
ArgumentGraphVisitor for_left_value(owner(), temp_index());
node->left()->Visit(&for_left_value);
@@ -240,6 +252,64 @@
}
+// 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 : false;
Kevin Millikin (Google) 2012/03/09 12:29:14 right needs a conversion to boolean (e.g., right =
srdjan 2012/03/09 19:47:41 Thanks for catching it. Added tests (separate CL).
+ // OR: left ? true : right;
+ 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);
+
+ if (node->kind() == Token::kAND) {
+ ValueGraphVisitor for_true(owner(), temp_index());
+ node->right()->Visit(&for_true);
+ if (for_true.value()->IsTemp()) {
+ ASSERT(for_true.value()->AsTemp()->index() == temp_index());
+ } else {
+ for_true.AddInstruction(
+ new BindInstr(temp_index(), for_true.value()));
+ }
+
+ ValueGraphVisitor for_false(owner(), temp_index());
+ for_false.AddInstruction(
+ new BindInstr(temp_index(), new ConstantVal(bool_false)));
+
+ Join(for_test, for_true, for_false);
+ ReturnValue(new TempVal(AllocateTempIndex()));
+ } else {
+ ASSERT(node->kind() == Token::kOR);
+ ValueGraphVisitor for_true(owner(), temp_index());
+ for_true.AddInstruction(
+ new BindInstr(temp_index(), new ConstantVal(bool_true)));
+
+ ValueGraphVisitor for_false(owner(), temp_index());
+ node->right()->Visit(&for_false);
+ if (for_false.value()->IsTemp()) {
+ ASSERT(for_false.value()->AsTemp()->index() == temp_index());
+ } else {
+ for_false.AddInstruction(
+ new BindInstr(temp_index(), for_false.value()));
+ }
+
+ Join(for_test, for_true, for_false);
+ 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') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698