Chromium Code Reviews| 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"); |
| } |