| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/flow_graph_builder.h" | 5 #include "vm/flow_graph_builder.h" |
| 6 | 6 |
| 7 #include "vm/ast_printer.h" | 7 #include "vm/ast_printer.h" |
| 8 #include "vm/code_descriptors.h" | 8 #include "vm/code_descriptors.h" |
| 9 #include "vm/dart_entry.h" | 9 #include "vm/dart_entry.h" |
| 10 #include "vm/flags.h" | 10 #include "vm/flags.h" |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 197 | 197 |
| 198 // 3. Add a join or select one (or neither) of the arms as exit. | 198 // 3. Add a join or select one (or neither) of the arms as exit. |
| 199 if (true_exit == NULL) { | 199 if (true_exit == NULL) { |
| 200 exit_ = false_exit; // May be NULL. | 200 exit_ = false_exit; // May be NULL. |
| 201 if (false_exit != NULL) temp_index_ = false_fragment.temp_index(); | 201 if (false_exit != NULL) temp_index_ = false_fragment.temp_index(); |
| 202 } else if (false_exit == NULL) { | 202 } else if (false_exit == NULL) { |
| 203 exit_ = true_exit; | 203 exit_ = true_exit; |
| 204 temp_index_ = true_fragment.temp_index(); | 204 temp_index_ = true_fragment.temp_index(); |
| 205 } else { | 205 } else { |
| 206 JoinEntryInstr* join = | 206 JoinEntryInstr* join = |
| 207 new JoinEntryInstr(owner()->AllocateBlockId(), | 207 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); |
| 208 owner()->try_index(), | |
| 209 loop_depth()); | |
| 210 true_exit->Goto(join); | 208 true_exit->Goto(join); |
| 211 false_exit->Goto(join); | 209 false_exit->Goto(join); |
| 212 exit_ = join; | 210 exit_ = join; |
| 213 ASSERT(true_fragment.temp_index() == false_fragment.temp_index()); | 211 ASSERT(true_fragment.temp_index() == false_fragment.temp_index()); |
| 214 temp_index_ = true_fragment.temp_index(); | 212 temp_index_ = true_fragment.temp_index(); |
| 215 } | 213 } |
| 216 } | 214 } |
| 217 | 215 |
| 218 | 216 |
| 219 void EffectGraphVisitor::TieLoop(const TestGraphVisitor& test_fragment, | 217 void EffectGraphVisitor::TieLoop(const TestGraphVisitor& test_fragment, |
| 220 const EffectGraphVisitor& body_fragment) { | 218 const EffectGraphVisitor& body_fragment) { |
| 221 // We have: a test graph fragment with zero, one, or two available exits; | 219 // We have: a test graph fragment with zero, one, or two available exits; |
| 222 // and an effect graph fragment with zero or one available exits. We want | 220 // and an effect graph fragment with zero or one available exits. We want |
| 223 // to append the 'while loop' consisting of the test graph fragment as | 221 // to append the 'while loop' consisting of the test graph fragment as |
| 224 // condition and the effect graph fragment as body. | 222 // condition and the effect graph fragment as body. |
| 225 ASSERT(is_open()); | 223 ASSERT(is_open()); |
| 226 | 224 |
| 227 // 1. Connect the body to the test if it is reachable, and if so record | 225 // 1. Connect the body to the test if it is reachable, and if so record |
| 228 // its exit (if any). | 226 // its exit (if any). |
| 229 BlockEntryInstr* body_entry = test_fragment.CreateTrueSuccessor(); | 227 BlockEntryInstr* body_entry = test_fragment.CreateTrueSuccessor(); |
| 230 Instruction* body_exit = AppendFragment(body_entry, body_fragment); | 228 Instruction* body_exit = AppendFragment(body_entry, body_fragment); |
| 231 | 229 |
| 232 // 2. Connect the test to this graph, including the body if reachable and | 230 // 2. Connect the test to this graph, including the body if reachable and |
| 233 // using a fresh join node if the body is reachable and has an open exit. | 231 // using a fresh join node if the body is reachable and has an open exit. |
| 234 if (body_exit == NULL) { | 232 if (body_exit == NULL) { |
| 235 Append(test_fragment); | 233 Append(test_fragment); |
| 236 } else { | 234 } else { |
| 237 JoinEntryInstr* join = | 235 JoinEntryInstr* join = |
| 238 new JoinEntryInstr(owner()->AllocateBlockId(), | 236 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); |
| 239 owner()->try_index(), | |
| 240 loop_depth() + 1); | |
| 241 join->LinkTo(test_fragment.entry()); | 237 join->LinkTo(test_fragment.entry()); |
| 242 Goto(join); | 238 Goto(join); |
| 243 body_exit->Goto(join); | 239 body_exit->Goto(join); |
| 244 } | 240 } |
| 245 | 241 |
| 246 // 3. Set the exit to the graph to be the false successor of the test, a | 242 // 3. Set the exit to the graph to be the false successor of the test, a |
| 247 // fresh target node | 243 // fresh target node |
| 248 | 244 |
| 249 exit_ = test_fragment.CreateFalseSuccessor(); | 245 exit_ = test_fragment.CreateFalseSuccessor(); |
| 250 } | 246 } |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 342 AddInstruction(new StoreContextInstr(load_saved_context)); | 338 AddInstruction(new StoreContextInstr(load_saved_context)); |
| 343 } | 339 } |
| 344 | 340 |
| 345 | 341 |
| 346 void TestGraphVisitor::ConnectBranchesTo( | 342 void TestGraphVisitor::ConnectBranchesTo( |
| 347 const GrowableArray<TargetEntryInstr**>& branches, | 343 const GrowableArray<TargetEntryInstr**>& branches, |
| 348 JoinEntryInstr* join) const { | 344 JoinEntryInstr* join) const { |
| 349 ASSERT(!branches.is_empty()); | 345 ASSERT(!branches.is_empty()); |
| 350 for (intptr_t i = 0; i < branches.length(); i++) { | 346 for (intptr_t i = 0; i < branches.length(); i++) { |
| 351 TargetEntryInstr* target = | 347 TargetEntryInstr* target = |
| 352 new TargetEntryInstr(owner()->AllocateBlockId(), | 348 new TargetEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); |
| 353 owner()->try_index(), | |
| 354 loop_depth()); | |
| 355 *(branches[i]) = target; | 349 *(branches[i]) = target; |
| 356 target->Goto(join); | 350 target->Goto(join); |
| 357 } | 351 } |
| 358 } | 352 } |
| 359 | 353 |
| 360 | 354 |
| 361 void TestGraphVisitor::IfTrueGoto(JoinEntryInstr* join) const { | 355 void TestGraphVisitor::IfTrueGoto(JoinEntryInstr* join) const { |
| 362 ConnectBranchesTo(true_successor_addresses_, join); | 356 ConnectBranchesTo(true_successor_addresses_, join); |
| 363 } | 357 } |
| 364 | 358 |
| 365 | 359 |
| 366 void TestGraphVisitor::IfFalseGoto(JoinEntryInstr* join) const { | 360 void TestGraphVisitor::IfFalseGoto(JoinEntryInstr* join) const { |
| 367 ConnectBranchesTo(false_successor_addresses_, join); | 361 ConnectBranchesTo(false_successor_addresses_, join); |
| 368 } | 362 } |
| 369 | 363 |
| 370 | 364 |
| 371 BlockEntryInstr* TestGraphVisitor::CreateSuccessorFor( | 365 BlockEntryInstr* TestGraphVisitor::CreateSuccessorFor( |
| 372 const GrowableArray<TargetEntryInstr**>& branches) const { | 366 const GrowableArray<TargetEntryInstr**>& branches) const { |
| 373 ASSERT(!branches.is_empty()); | 367 ASSERT(!branches.is_empty()); |
| 374 | 368 |
| 375 if (branches.length() == 1) { | 369 if (branches.length() == 1) { |
| 376 TargetEntryInstr* target = | 370 TargetEntryInstr* target = |
| 377 new TargetEntryInstr(owner()->AllocateBlockId(), | 371 new TargetEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); |
| 378 owner()->try_index(), | |
| 379 loop_depth()); | |
| 380 *(branches[0]) = target; | 372 *(branches[0]) = target; |
| 381 return target; | 373 return target; |
| 382 } | 374 } |
| 383 | 375 |
| 384 JoinEntryInstr* join = | 376 JoinEntryInstr* join = |
| 385 new JoinEntryInstr(owner()->AllocateBlockId(), | 377 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); |
| 386 owner()->try_index(), | |
| 387 loop_depth()); | |
| 388 ConnectBranchesTo(branches, join); | 378 ConnectBranchesTo(branches, join); |
| 389 return join; | 379 return join; |
| 390 } | 380 } |
| 391 | 381 |
| 392 | 382 |
| 393 BlockEntryInstr* TestGraphVisitor::CreateTrueSuccessor() const { | 383 BlockEntryInstr* TestGraphVisitor::CreateTrueSuccessor() const { |
| 394 return CreateSuccessorFor(true_successor_addresses_); | 384 return CreateSuccessorFor(true_successor_addresses_); |
| 395 } | 385 } |
| 396 | 386 |
| 397 | 387 |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 468 } | 458 } |
| 469 | 459 |
| 470 | 460 |
| 471 // Special handling for AND/OR. | 461 // Special handling for AND/OR. |
| 472 void TestGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { | 462 void TestGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { |
| 473 // Operators "&&" and "||" cannot be overloaded therefore do not call | 463 // Operators "&&" and "||" cannot be overloaded therefore do not call |
| 474 // operator. | 464 // operator. |
| 475 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { | 465 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { |
| 476 TestGraphVisitor for_left(owner(), | 466 TestGraphVisitor for_left(owner(), |
| 477 temp_index(), | 467 temp_index(), |
| 478 loop_depth(), | |
| 479 node->left()->token_pos()); | 468 node->left()->token_pos()); |
| 480 node->left()->Visit(&for_left); | 469 node->left()->Visit(&for_left); |
| 481 | 470 |
| 482 TestGraphVisitor for_right(owner(), | 471 TestGraphVisitor for_right(owner(), |
| 483 temp_index(), | 472 temp_index(), |
| 484 loop_depth(), | |
| 485 node->right()->token_pos()); | 473 node->right()->token_pos()); |
| 486 node->right()->Visit(&for_right); | 474 node->right()->Visit(&for_right); |
| 487 | 475 |
| 488 Append(for_left); | 476 Append(for_left); |
| 489 | 477 |
| 490 if (node->kind() == Token::kAND) { | 478 if (node->kind() == Token::kAND) { |
| 491 AppendFragment(for_left.CreateTrueSuccessor(), for_right); | 479 AppendFragment(for_left.CreateTrueSuccessor(), for_right); |
| 492 true_successor_addresses_.AddArray(for_right.true_successor_addresses_); | 480 true_successor_addresses_.AddArray(for_right.true_successor_addresses_); |
| 493 false_successor_addresses_.AddArray(for_left.false_successor_addresses_); | 481 false_successor_addresses_.AddArray(for_left.false_successor_addresses_); |
| 494 false_successor_addresses_.AddArray(for_right.false_successor_addresses_); | 482 false_successor_addresses_.AddArray(for_right.false_successor_addresses_); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 513 | 501 |
| 514 void EffectGraphVisitor::InlineBailout(const char* reason) { | 502 void EffectGraphVisitor::InlineBailout(const char* reason) { |
| 515 owner()->parsed_function().function().set_is_inlinable(false); | 503 owner()->parsed_function().function().set_is_inlinable(false); |
| 516 if (owner()->InInliningContext()) owner()->Bailout(reason); | 504 if (owner()->InInliningContext()) owner()->Bailout(reason); |
| 517 } | 505 } |
| 518 | 506 |
| 519 | 507 |
| 520 // <Statement> ::= Return { value: <Expression> | 508 // <Statement> ::= Return { value: <Expression> |
| 521 // inlined_finally_list: <InlinedFinally>* } | 509 // inlined_finally_list: <InlinedFinally>* } |
| 522 void EffectGraphVisitor::VisitReturnNode(ReturnNode* node) { | 510 void EffectGraphVisitor::VisitReturnNode(ReturnNode* node) { |
| 523 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); | 511 ValueGraphVisitor for_value(owner(), temp_index()); |
| 524 node->value()->Visit(&for_value); | 512 node->value()->Visit(&for_value); |
| 525 Append(for_value); | 513 Append(for_value); |
| 526 | 514 |
| 527 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { | 515 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { |
| 528 InlineBailout("EffectGraphVisitor::VisitReturnNode (exception)"); | 516 InlineBailout("EffectGraphVisitor::VisitReturnNode (exception)"); |
| 529 EffectGraphVisitor for_effect(owner(), temp_index(), loop_depth()); | 517 EffectGraphVisitor for_effect(owner(), temp_index()); |
| 530 node->InlinedFinallyNodeAt(i)->Visit(&for_effect); | 518 node->InlinedFinallyNodeAt(i)->Visit(&for_effect); |
| 531 Append(for_effect); | 519 Append(for_effect); |
| 532 if (!is_open()) return; | 520 if (!is_open()) return; |
| 533 } | 521 } |
| 534 | 522 |
| 535 Value* return_value = for_value.value(); | 523 Value* return_value = for_value.value(); |
| 536 if (FLAG_enable_type_checks) { | 524 if (FLAG_enable_type_checks) { |
| 537 const Function& function = owner()->parsed_function().function(); | 525 const Function& function = owner()->parsed_function().function(); |
| 538 const bool is_implicit_dynamic_getter = | 526 const bool is_implicit_dynamic_getter = |
| 539 (!function.is_static() && | 527 (!function.is_static() && |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 642 eliminated); | 630 eliminated); |
| 643 } | 631 } |
| 644 return eliminated; | 632 return eliminated; |
| 645 } | 633 } |
| 646 | 634 |
| 647 | 635 |
| 648 // <Expression> :: Assignable { expr: <Expression> | 636 // <Expression> :: Assignable { expr: <Expression> |
| 649 // type: AbstractType | 637 // type: AbstractType |
| 650 // dst_name: String } | 638 // dst_name: String } |
| 651 void EffectGraphVisitor::VisitAssignableNode(AssignableNode* node) { | 639 void EffectGraphVisitor::VisitAssignableNode(AssignableNode* node) { |
| 652 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); | 640 ValueGraphVisitor for_value(owner(), temp_index()); |
| 653 node->expr()->Visit(&for_value); | 641 node->expr()->Visit(&for_value); |
| 654 Append(for_value); | 642 Append(for_value); |
| 655 Definition* checked_value; | 643 Definition* checked_value; |
| 656 if (CanSkipTypeCheck(node->expr()->token_pos(), | 644 if (CanSkipTypeCheck(node->expr()->token_pos(), |
| 657 for_value.value(), | 645 for_value.value(), |
| 658 node->type(), | 646 node->type(), |
| 659 node->dst_name())) { | 647 node->dst_name())) { |
| 660 checked_value = for_value.value()->definition(); // No check needed. | 648 checked_value = for_value.value()->definition(); // No check needed. |
| 661 } else { | 649 } else { |
| 662 checked_value = BuildAssertAssignable(node->expr()->token_pos(), | 650 checked_value = BuildAssertAssignable(node->expr()->token_pos(), |
| 663 for_value.value(), | 651 for_value.value(), |
| 664 node->type(), | 652 node->type(), |
| 665 node->dst_name()); | 653 node->dst_name()); |
| 666 } | 654 } |
| 667 ReturnDefinition(checked_value); | 655 ReturnDefinition(checked_value); |
| 668 } | 656 } |
| 669 | 657 |
| 670 | 658 |
| 671 void ValueGraphVisitor::VisitAssignableNode(AssignableNode* node) { | 659 void ValueGraphVisitor::VisitAssignableNode(AssignableNode* node) { |
| 672 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); | 660 ValueGraphVisitor for_value(owner(), temp_index()); |
| 673 node->expr()->Visit(&for_value); | 661 node->expr()->Visit(&for_value); |
| 674 Append(for_value); | 662 Append(for_value); |
| 675 ReturnValue(BuildAssignableValue(node->expr()->token_pos(), | 663 ReturnValue(BuildAssignableValue(node->expr()->token_pos(), |
| 676 for_value.value(), | 664 for_value.value(), |
| 677 node->type(), | 665 node->type(), |
| 678 node->dst_name())); | 666 node->dst_name())); |
| 679 } | 667 } |
| 680 | 668 |
| 681 | 669 |
| 682 // <Expression> :: BinaryOp { kind: Token::Kind | 670 // <Expression> :: BinaryOp { kind: Token::Kind |
| 683 // left: <Expression> | 671 // left: <Expression> |
| 684 // right: <Expression> } | 672 // right: <Expression> } |
| 685 void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { | 673 void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { |
| 686 // Operators "&&" and "||" cannot be overloaded therefore do not call | 674 // Operators "&&" and "||" cannot be overloaded therefore do not call |
| 687 // operator. | 675 // operator. |
| 688 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { | 676 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { |
| 689 // See ValueGraphVisitor::VisitBinaryOpNode. | 677 // See ValueGraphVisitor::VisitBinaryOpNode. |
| 690 TestGraphVisitor for_left(owner(), | 678 TestGraphVisitor for_left(owner(), |
| 691 temp_index(), | 679 temp_index(), |
| 692 loop_depth(), | |
| 693 node->left()->token_pos()); | 680 node->left()->token_pos()); |
| 694 node->left()->Visit(&for_left); | 681 node->left()->Visit(&for_left); |
| 695 EffectGraphVisitor for_right(owner(), temp_index(), loop_depth()); | 682 EffectGraphVisitor for_right(owner(), temp_index()); |
| 696 node->right()->Visit(&for_right); | 683 node->right()->Visit(&for_right); |
| 697 EffectGraphVisitor empty(owner(), temp_index(), loop_depth()); | 684 EffectGraphVisitor empty(owner(), temp_index()); |
| 698 if (node->kind() == Token::kAND) { | 685 if (node->kind() == Token::kAND) { |
| 699 Join(for_left, for_right, empty); | 686 Join(for_left, for_right, empty); |
| 700 } else { | 687 } else { |
| 701 Join(for_left, empty, for_right); | 688 Join(for_left, empty, for_right); |
| 702 } | 689 } |
| 703 return; | 690 return; |
| 704 } | 691 } |
| 705 ValueGraphVisitor for_left_value(owner(), temp_index(), loop_depth()); | 692 ValueGraphVisitor for_left_value(owner(), temp_index()); |
| 706 node->left()->Visit(&for_left_value); | 693 node->left()->Visit(&for_left_value); |
| 707 Append(for_left_value); | 694 Append(for_left_value); |
| 708 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); | 695 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); |
| 709 | 696 |
| 710 ValueGraphVisitor for_right_value(owner(), temp_index(), loop_depth()); | 697 ValueGraphVisitor for_right_value(owner(), temp_index()); |
| 711 node->right()->Visit(&for_right_value); | 698 node->right()->Visit(&for_right_value); |
| 712 Append(for_right_value); | 699 Append(for_right_value); |
| 713 PushArgumentInstr* push_right = PushArgument(for_right_value.value()); | 700 PushArgumentInstr* push_right = PushArgument(for_right_value.value()); |
| 714 | 701 |
| 715 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 702 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 716 new ZoneGrowableArray<PushArgumentInstr*>(2); | 703 new ZoneGrowableArray<PushArgumentInstr*>(2); |
| 717 arguments->Add(push_left); | 704 arguments->Add(push_left); |
| 718 arguments->Add(push_right); | 705 arguments->Add(push_right); |
| 719 const String& name = String::ZoneHandle(Symbols::New(node->Name())); | 706 const String& name = String::ZoneHandle(Symbols::New(node->Name())); |
| 720 InstanceCallInstr* call = new InstanceCallInstr(node->token_pos(), | 707 InstanceCallInstr* call = new InstanceCallInstr(node->token_pos(), |
| (...skipping 11 matching lines...) Expand all Loading... |
| 732 // Operators "&&" and "||" cannot be overloaded therefore do not call | 719 // Operators "&&" and "||" cannot be overloaded therefore do not call |
| 733 // operator. | 720 // operator. |
| 734 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { | 721 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { |
| 735 // Implement short-circuit logic: do not evaluate right if evaluation | 722 // Implement short-circuit logic: do not evaluate right if evaluation |
| 736 // of left is sufficient. | 723 // of left is sufficient. |
| 737 // AND: left ? right === true : false; | 724 // AND: left ? right === true : false; |
| 738 // OR: left ? true : right === true; | 725 // OR: left ? true : right === true; |
| 739 | 726 |
| 740 TestGraphVisitor for_test(owner(), | 727 TestGraphVisitor for_test(owner(), |
| 741 temp_index(), | 728 temp_index(), |
| 742 loop_depth(), | |
| 743 node->left()->token_pos()); | 729 node->left()->token_pos()); |
| 744 node->left()->Visit(&for_test); | 730 node->left()->Visit(&for_test); |
| 745 | 731 |
| 746 ValueGraphVisitor for_right(owner(), temp_index(), loop_depth()); | 732 ValueGraphVisitor for_right(owner(), temp_index()); |
| 747 node->right()->Visit(&for_right); | 733 node->right()->Visit(&for_right); |
| 748 Value* right_value = for_right.value(); | 734 Value* right_value = for_right.value(); |
| 749 if (FLAG_enable_type_checks) { | 735 if (FLAG_enable_type_checks) { |
| 750 right_value = | 736 right_value = |
| 751 for_right.Bind(new AssertBooleanInstr(node->right()->token_pos(), | 737 for_right.Bind(new AssertBooleanInstr(node->right()->token_pos(), |
| 752 right_value)); | 738 right_value)); |
| 753 } | 739 } |
| 754 Value* constant_true = for_right.Bind(new ConstantInstr(Bool::True())); | 740 Value* constant_true = for_right.Bind(new ConstantInstr(Bool::True())); |
| 755 Value* compare = | 741 Value* compare = |
| 756 for_right.Bind(new StrictCompareInstr(Token::kEQ_STRICT, | 742 for_right.Bind(new StrictCompareInstr(Token::kEQ_STRICT, |
| 757 right_value, | 743 right_value, |
| 758 constant_true)); | 744 constant_true)); |
| 759 for_right.Do(BuildStoreExprTemp(compare)); | 745 for_right.Do(BuildStoreExprTemp(compare)); |
| 760 | 746 |
| 761 if (node->kind() == Token::kAND) { | 747 if (node->kind() == Token::kAND) { |
| 762 ValueGraphVisitor for_false(owner(), temp_index(), loop_depth()); | 748 ValueGraphVisitor for_false(owner(), temp_index()); |
| 763 Value* constant_false = for_false.Bind(new ConstantInstr(Bool::False())); | 749 Value* constant_false = for_false.Bind(new ConstantInstr(Bool::False())); |
| 764 for_false.Do(BuildStoreExprTemp(constant_false)); | 750 for_false.Do(BuildStoreExprTemp(constant_false)); |
| 765 Join(for_test, for_right, for_false); | 751 Join(for_test, for_right, for_false); |
| 766 } else { | 752 } else { |
| 767 ASSERT(node->kind() == Token::kOR); | 753 ASSERT(node->kind() == Token::kOR); |
| 768 ValueGraphVisitor for_true(owner(), temp_index(), loop_depth()); | 754 ValueGraphVisitor for_true(owner(), temp_index()); |
| 769 Value* constant_true = for_true.Bind(new ConstantInstr(Bool::True())); | 755 Value* constant_true = for_true.Bind(new ConstantInstr(Bool::True())); |
| 770 for_true.Do(BuildStoreExprTemp(constant_true)); | 756 for_true.Do(BuildStoreExprTemp(constant_true)); |
| 771 Join(for_test, for_true, for_right); | 757 Join(for_test, for_true, for_right); |
| 772 } | 758 } |
| 773 ReturnDefinition(BuildLoadExprTemp()); | 759 ReturnDefinition(BuildLoadExprTemp()); |
| 774 return; | 760 return; |
| 775 } | 761 } |
| 776 EffectGraphVisitor::VisitBinaryOpNode(node); | 762 EffectGraphVisitor::VisitBinaryOpNode(node); |
| 777 } | 763 } |
| 778 | 764 |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 871 const String& dst_name) { | 857 const String& dst_name) { |
| 872 if (CanSkipTypeCheck(token_pos, value, dst_type, dst_name)) { | 858 if (CanSkipTypeCheck(token_pos, value, dst_type, dst_name)) { |
| 873 return value; | 859 return value; |
| 874 } | 860 } |
| 875 return Bind(BuildAssertAssignable(token_pos, value, dst_type, dst_name)); | 861 return Bind(BuildAssertAssignable(token_pos, value, dst_type, dst_name)); |
| 876 } | 862 } |
| 877 | 863 |
| 878 | 864 |
| 879 void EffectGraphVisitor::BuildTypeTest(ComparisonNode* node) { | 865 void EffectGraphVisitor::BuildTypeTest(ComparisonNode* node) { |
| 880 ASSERT(Token::IsTypeTestOperator(node->kind())); | 866 ASSERT(Token::IsTypeTestOperator(node->kind())); |
| 881 EffectGraphVisitor for_left_value(owner(), temp_index(), loop_depth()); | 867 EffectGraphVisitor for_left_value(owner(), temp_index()); |
| 882 node->left()->Visit(&for_left_value); | 868 node->left()->Visit(&for_left_value); |
| 883 Append(for_left_value); | 869 Append(for_left_value); |
| 884 } | 870 } |
| 885 | 871 |
| 886 | 872 |
| 887 void EffectGraphVisitor::BuildTypeCast(ComparisonNode* node) { | 873 void EffectGraphVisitor::BuildTypeCast(ComparisonNode* node) { |
| 888 ASSERT(Token::IsTypeCastOperator(node->kind())); | 874 ASSERT(Token::IsTypeCastOperator(node->kind())); |
| 889 const AbstractType& type = node->right()->AsTypeNode()->type(); | 875 const AbstractType& type = node->right()->AsTypeNode()->type(); |
| 890 ASSERT(type.IsFinalized()); // The type in a type cast may be malformed. | 876 ASSERT(type.IsFinalized()); // The type in a type cast may be malformed. |
| 891 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); | 877 ValueGraphVisitor for_value(owner(), temp_index()); |
| 892 node->left()->Visit(&for_value); | 878 node->left()->Visit(&for_value); |
| 893 const String& dst_name = String::ZoneHandle( | 879 const String& dst_name = String::ZoneHandle( |
| 894 Symbols::New(Exceptions::kCastErrorDstName)); | 880 Symbols::New(Exceptions::kCastErrorDstName)); |
| 895 if (!CanSkipTypeCheck(node->token_pos(), for_value.value(), type, dst_name)) { | 881 if (!CanSkipTypeCheck(node->token_pos(), for_value.value(), type, dst_name)) { |
| 896 Append(for_value); | 882 Append(for_value); |
| 897 Do(BuildAssertAssignable( | 883 Do(BuildAssertAssignable( |
| 898 node->token_pos(), for_value.value(), type, dst_name)); | 884 node->token_pos(), for_value.value(), type, dst_name)); |
| 899 } | 885 } |
| 900 } | 886 } |
| 901 | 887 |
| 902 | 888 |
| 903 void ValueGraphVisitor::BuildTypeTest(ComparisonNode* node) { | 889 void ValueGraphVisitor::BuildTypeTest(ComparisonNode* node) { |
| 904 ASSERT(Token::IsTypeTestOperator(node->kind())); | 890 ASSERT(Token::IsTypeTestOperator(node->kind())); |
| 905 const AbstractType& type = node->right()->AsTypeNode()->type(); | 891 const AbstractType& type = node->right()->AsTypeNode()->type(); |
| 906 ASSERT(type.IsFinalized() && !type.IsMalformed()); | 892 ASSERT(type.IsFinalized() && !type.IsMalformed()); |
| 907 const bool negate_result = (node->kind() == Token::kISNOT); | 893 const bool negate_result = (node->kind() == Token::kISNOT); |
| 908 // All objects are instances of type T if Object type is a subtype of type T. | 894 // All objects are instances of type T if Object type is a subtype of type T. |
| 909 const Type& object_type = Type::Handle(Type::ObjectType()); | 895 const Type& object_type = Type::Handle(Type::ObjectType()); |
| 910 if (type.IsInstantiated() && object_type.IsSubtypeOf(type, NULL)) { | 896 if (type.IsInstantiated() && object_type.IsSubtypeOf(type, NULL)) { |
| 911 // Must evaluate left side. | 897 // Must evaluate left side. |
| 912 EffectGraphVisitor for_left_value(owner(), temp_index(), loop_depth()); | 898 EffectGraphVisitor for_left_value(owner(), temp_index()); |
| 913 node->left()->Visit(&for_left_value); | 899 node->left()->Visit(&for_left_value); |
| 914 Append(for_left_value); | 900 Append(for_left_value); |
| 915 ReturnDefinition(new ConstantInstr(negate_result ? | 901 ReturnDefinition(new ConstantInstr(negate_result ? |
| 916 Bool::False() : Bool::True())); | 902 Bool::False() : Bool::True())); |
| 917 return; | 903 return; |
| 918 } | 904 } |
| 919 | 905 |
| 920 // Eliminate the test if it can be performed successfully at compile time. | 906 // Eliminate the test if it can be performed successfully at compile time. |
| 921 if ((node->left() != NULL) && | 907 if ((node->left() != NULL) && |
| 922 node->left()->IsLiteralNode() && | 908 node->left()->IsLiteralNode() && |
| (...skipping 13 matching lines...) Expand all Loading... |
| 936 Bool::False() : Bool::True()); | 922 Bool::False() : Bool::True()); |
| 937 } else { | 923 } else { |
| 938 result = new ConstantInstr(negate_result ? | 924 result = new ConstantInstr(negate_result ? |
| 939 Bool::True() : Bool::False()); | 925 Bool::True() : Bool::False()); |
| 940 } | 926 } |
| 941 } | 927 } |
| 942 ReturnDefinition(result); | 928 ReturnDefinition(result); |
| 943 return; | 929 return; |
| 944 } | 930 } |
| 945 | 931 |
| 946 ValueGraphVisitor for_left_value(owner(), temp_index(), loop_depth()); | 932 ValueGraphVisitor for_left_value(owner(), temp_index()); |
| 947 node->left()->Visit(&for_left_value); | 933 node->left()->Visit(&for_left_value); |
| 948 Append(for_left_value); | 934 Append(for_left_value); |
| 949 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); | 935 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); |
| 950 PushArgumentInstr* push_instantiator = NULL; | 936 PushArgumentInstr* push_instantiator = NULL; |
| 951 PushArgumentInstr* push_type_args = NULL; | 937 PushArgumentInstr* push_type_args = NULL; |
| 952 if (type.IsInstantiated()) { | 938 if (type.IsInstantiated()) { |
| 953 push_instantiator = PushArgument(BuildNullValue()); | 939 push_instantiator = PushArgument(BuildNullValue()); |
| 954 push_type_args = PushArgument(BuildNullValue()); | 940 push_type_args = PushArgument(BuildNullValue()); |
| 955 } else { | 941 } else { |
| 956 BuildTypecheckPushArguments(node->token_pos(), | 942 BuildTypecheckPushArguments(node->token_pos(), |
| (...skipping 22 matching lines...) Expand all Loading... |
| 979 Array::ZoneHandle(), | 965 Array::ZoneHandle(), |
| 980 kNumArgsChecked); | 966 kNumArgsChecked); |
| 981 ReturnDefinition(call); | 967 ReturnDefinition(call); |
| 982 } | 968 } |
| 983 | 969 |
| 984 | 970 |
| 985 void ValueGraphVisitor::BuildTypeCast(ComparisonNode* node) { | 971 void ValueGraphVisitor::BuildTypeCast(ComparisonNode* node) { |
| 986 ASSERT(Token::IsTypeCastOperator(node->kind())); | 972 ASSERT(Token::IsTypeCastOperator(node->kind())); |
| 987 const AbstractType& type = node->right()->AsTypeNode()->type(); | 973 const AbstractType& type = node->right()->AsTypeNode()->type(); |
| 988 ASSERT(type.IsFinalized()); // The type in a type cast may be malformed. | 974 ASSERT(type.IsFinalized()); // The type in a type cast may be malformed. |
| 989 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); | 975 ValueGraphVisitor for_value(owner(), temp_index()); |
| 990 node->left()->Visit(&for_value); | 976 node->left()->Visit(&for_value); |
| 991 Append(for_value); | 977 Append(for_value); |
| 992 const String& dst_name = String::ZoneHandle( | 978 const String& dst_name = String::ZoneHandle( |
| 993 Symbols::New(Exceptions::kCastErrorDstName)); | 979 Symbols::New(Exceptions::kCastErrorDstName)); |
| 994 ReturnValue(BuildAssignableValue(node->token_pos(), | 980 ReturnValue(BuildAssignableValue(node->token_pos(), |
| 995 for_value.value(), | 981 for_value.value(), |
| 996 type, | 982 type, |
| 997 dst_name)); | 983 dst_name)); |
| 998 } | 984 } |
| 999 | 985 |
| 1000 | 986 |
| 1001 // <Expression> :: Comparison { kind: Token::Kind | 987 // <Expression> :: Comparison { kind: Token::Kind |
| 1002 // left: <Expression> | 988 // left: <Expression> |
| 1003 // right: <Expression> } | 989 // right: <Expression> } |
| 1004 // TODO(srdjan): Implement new equality. | 990 // TODO(srdjan): Implement new equality. |
| 1005 void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) { | 991 void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) { |
| 1006 if (Token::IsTypeTestOperator(node->kind())) { | 992 if (Token::IsTypeTestOperator(node->kind())) { |
| 1007 BuildTypeTest(node); | 993 BuildTypeTest(node); |
| 1008 return; | 994 return; |
| 1009 } | 995 } |
| 1010 if (Token::IsTypeCastOperator(node->kind())) { | 996 if (Token::IsTypeCastOperator(node->kind())) { |
| 1011 BuildTypeCast(node); | 997 BuildTypeCast(node); |
| 1012 return; | 998 return; |
| 1013 } | 999 } |
| 1014 if ((node->kind() == Token::kEQ_STRICT) || | 1000 if ((node->kind() == Token::kEQ_STRICT) || |
| 1015 (node->kind() == Token::kNE_STRICT)) { | 1001 (node->kind() == Token::kNE_STRICT)) { |
| 1016 ValueGraphVisitor for_left_value(owner(), temp_index(), loop_depth()); | 1002 ValueGraphVisitor for_left_value(owner(), temp_index()); |
| 1017 node->left()->Visit(&for_left_value); | 1003 node->left()->Visit(&for_left_value); |
| 1018 Append(for_left_value); | 1004 Append(for_left_value); |
| 1019 ValueGraphVisitor for_right_value(owner(), temp_index(), loop_depth()); | 1005 ValueGraphVisitor for_right_value(owner(), temp_index()); |
| 1020 node->right()->Visit(&for_right_value); | 1006 node->right()->Visit(&for_right_value); |
| 1021 Append(for_right_value); | 1007 Append(for_right_value); |
| 1022 StrictCompareInstr* comp = new StrictCompareInstr( | 1008 StrictCompareInstr* comp = new StrictCompareInstr( |
| 1023 node->kind(), for_left_value.value(), for_right_value.value()); | 1009 node->kind(), for_left_value.value(), for_right_value.value()); |
| 1024 ReturnDefinition(comp); | 1010 ReturnDefinition(comp); |
| 1025 return; | 1011 return; |
| 1026 } | 1012 } |
| 1027 | 1013 |
| 1028 if ((node->kind() == Token::kEQ) || (node->kind() == Token::kNE)) { | 1014 if ((node->kind() == Token::kEQ) || (node->kind() == Token::kNE)) { |
| 1029 ValueGraphVisitor for_left_value(owner(), temp_index(), loop_depth()); | 1015 ValueGraphVisitor for_left_value(owner(), temp_index()); |
| 1030 node->left()->Visit(&for_left_value); | 1016 node->left()->Visit(&for_left_value); |
| 1031 Append(for_left_value); | 1017 Append(for_left_value); |
| 1032 ValueGraphVisitor for_right_value(owner(), temp_index(), loop_depth()); | 1018 ValueGraphVisitor for_right_value(owner(), temp_index()); |
| 1033 node->right()->Visit(&for_right_value); | 1019 node->right()->Visit(&for_right_value); |
| 1034 Append(for_right_value); | 1020 Append(for_right_value); |
| 1035 if (FLAG_enable_type_checks) { | 1021 if (FLAG_enable_type_checks) { |
| 1036 EqualityCompareInstr* comp = new EqualityCompareInstr( | 1022 EqualityCompareInstr* comp = new EqualityCompareInstr( |
| 1037 node->token_pos(), | 1023 node->token_pos(), |
| 1038 Token::kEQ, | 1024 Token::kEQ, |
| 1039 for_left_value.value(), | 1025 for_left_value.value(), |
| 1040 for_right_value.value()); | 1026 for_right_value.value()); |
| 1041 if (node->kind() == Token::kEQ) { | 1027 if (node->kind() == Token::kEQ) { |
| 1042 ReturnDefinition(comp); | 1028 ReturnDefinition(comp); |
| 1043 } else { | 1029 } else { |
| 1044 Value* eq_result = Bind(comp); | 1030 Value* eq_result = Bind(comp); |
| 1045 eq_result = Bind(new AssertBooleanInstr(node->token_pos(), eq_result)); | 1031 eq_result = Bind(new AssertBooleanInstr(node->token_pos(), eq_result)); |
| 1046 ReturnDefinition(new BooleanNegateInstr(eq_result)); | 1032 ReturnDefinition(new BooleanNegateInstr(eq_result)); |
| 1047 } | 1033 } |
| 1048 } else { | 1034 } else { |
| 1049 EqualityCompareInstr* comp = new EqualityCompareInstr( | 1035 EqualityCompareInstr* comp = new EqualityCompareInstr( |
| 1050 node->token_pos(), | 1036 node->token_pos(), |
| 1051 node->kind(), | 1037 node->kind(), |
| 1052 for_left_value.value(), | 1038 for_left_value.value(), |
| 1053 for_right_value.value()); | 1039 for_right_value.value()); |
| 1054 ReturnDefinition(comp); | 1040 ReturnDefinition(comp); |
| 1055 } | 1041 } |
| 1056 return; | 1042 return; |
| 1057 } | 1043 } |
| 1058 | 1044 |
| 1059 ValueGraphVisitor for_left_value(owner(), temp_index(), loop_depth()); | 1045 ValueGraphVisitor for_left_value(owner(), temp_index()); |
| 1060 node->left()->Visit(&for_left_value); | 1046 node->left()->Visit(&for_left_value); |
| 1061 Append(for_left_value); | 1047 Append(for_left_value); |
| 1062 ValueGraphVisitor for_right_value(owner(), temp_index(), loop_depth()); | 1048 ValueGraphVisitor for_right_value(owner(), temp_index()); |
| 1063 node->right()->Visit(&for_right_value); | 1049 node->right()->Visit(&for_right_value); |
| 1064 Append(for_right_value); | 1050 Append(for_right_value); |
| 1065 RelationalOpInstr* comp = new RelationalOpInstr(node->token_pos(), | 1051 RelationalOpInstr* comp = new RelationalOpInstr(node->token_pos(), |
| 1066 node->kind(), | 1052 node->kind(), |
| 1067 for_left_value.value(), | 1053 for_left_value.value(), |
| 1068 for_right_value.value()); | 1054 for_right_value.value()); |
| 1069 ReturnDefinition(comp); | 1055 ReturnDefinition(comp); |
| 1070 } | 1056 } |
| 1071 | 1057 |
| 1072 | 1058 |
| 1073 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) { | 1059 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) { |
| 1074 // "!" cannot be overloaded, therefore do not call operator. | 1060 // "!" cannot be overloaded, therefore do not call operator. |
| 1075 if (node->kind() == Token::kNOT) { | 1061 if (node->kind() == Token::kNOT) { |
| 1076 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); | 1062 ValueGraphVisitor for_value(owner(), temp_index()); |
| 1077 node->operand()->Visit(&for_value); | 1063 node->operand()->Visit(&for_value); |
| 1078 Append(for_value); | 1064 Append(for_value); |
| 1079 Value* value = for_value.value(); | 1065 Value* value = for_value.value(); |
| 1080 if (FLAG_enable_type_checks) { | 1066 if (FLAG_enable_type_checks) { |
| 1081 value = | 1067 value = |
| 1082 Bind(new AssertBooleanInstr(node->operand()->token_pos(), value)); | 1068 Bind(new AssertBooleanInstr(node->operand()->token_pos(), value)); |
| 1083 } | 1069 } |
| 1084 BooleanNegateInstr* negate = new BooleanNegateInstr(value); | 1070 BooleanNegateInstr* negate = new BooleanNegateInstr(value); |
| 1085 ReturnDefinition(negate); | 1071 ReturnDefinition(negate); |
| 1086 return; | 1072 return; |
| 1087 } | 1073 } |
| 1088 | 1074 |
| 1089 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); | 1075 ValueGraphVisitor for_value(owner(), temp_index()); |
| 1090 node->operand()->Visit(&for_value); | 1076 node->operand()->Visit(&for_value); |
| 1091 Append(for_value); | 1077 Append(for_value); |
| 1092 PushArgumentInstr* push_value = PushArgument(for_value.value()); | 1078 PushArgumentInstr* push_value = PushArgument(for_value.value()); |
| 1093 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1079 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1094 new ZoneGrowableArray<PushArgumentInstr*>(1); | 1080 new ZoneGrowableArray<PushArgumentInstr*>(1); |
| 1095 arguments->Add(push_value); | 1081 arguments->Add(push_value); |
| 1096 InstanceCallInstr* call = | 1082 InstanceCallInstr* call = |
| 1097 new InstanceCallInstr(node->token_pos(), | 1083 new InstanceCallInstr(node->token_pos(), |
| 1098 String::ZoneHandle( | 1084 String::ZoneHandle( |
| 1099 Symbols::New(Token::Str(node->kind()))), | 1085 Symbols::New(Token::Str(node->kind()))), |
| 1100 node->kind(), | 1086 node->kind(), |
| 1101 arguments, | 1087 arguments, |
| 1102 Array::ZoneHandle(), | 1088 Array::ZoneHandle(), |
| 1103 1); | 1089 1); |
| 1104 ReturnDefinition(call); | 1090 ReturnDefinition(call); |
| 1105 } | 1091 } |
| 1106 | 1092 |
| 1107 | 1093 |
| 1108 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { | 1094 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { |
| 1109 TestGraphVisitor for_test(owner(), | 1095 TestGraphVisitor for_test(owner(), |
| 1110 temp_index(), | 1096 temp_index(), |
| 1111 loop_depth(), | |
| 1112 node->condition()->token_pos()); | 1097 node->condition()->token_pos()); |
| 1113 node->condition()->Visit(&for_test); | 1098 node->condition()->Visit(&for_test); |
| 1114 | 1099 |
| 1115 // Translate the subexpressions for their effects. | 1100 // Translate the subexpressions for their effects. |
| 1116 EffectGraphVisitor for_true(owner(), temp_index(), loop_depth()); | 1101 EffectGraphVisitor for_true(owner(), temp_index()); |
| 1117 node->true_expr()->Visit(&for_true); | 1102 node->true_expr()->Visit(&for_true); |
| 1118 EffectGraphVisitor for_false(owner(), temp_index(), loop_depth()); | 1103 EffectGraphVisitor for_false(owner(), temp_index()); |
| 1119 node->false_expr()->Visit(&for_false); | 1104 node->false_expr()->Visit(&for_false); |
| 1120 | 1105 |
| 1121 Join(for_test, for_true, for_false); | 1106 Join(for_test, for_true, for_false); |
| 1122 } | 1107 } |
| 1123 | 1108 |
| 1124 | 1109 |
| 1125 void ValueGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { | 1110 void ValueGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { |
| 1126 TestGraphVisitor for_test(owner(), | 1111 TestGraphVisitor for_test(owner(), |
| 1127 temp_index(), | 1112 temp_index(), |
| 1128 loop_depth(), | |
| 1129 node->condition()->token_pos()); | 1113 node->condition()->token_pos()); |
| 1130 node->condition()->Visit(&for_test); | 1114 node->condition()->Visit(&for_test); |
| 1131 | 1115 |
| 1132 ValueGraphVisitor for_true(owner(), temp_index(), loop_depth()); | 1116 ValueGraphVisitor for_true(owner(), temp_index()); |
| 1133 node->true_expr()->Visit(&for_true); | 1117 node->true_expr()->Visit(&for_true); |
| 1134 ASSERT(for_true.is_open()); | 1118 ASSERT(for_true.is_open()); |
| 1135 for_true.Do(BuildStoreExprTemp(for_true.value())); | 1119 for_true.Do(BuildStoreExprTemp(for_true.value())); |
| 1136 | 1120 |
| 1137 ValueGraphVisitor for_false(owner(), temp_index(), loop_depth()); | 1121 ValueGraphVisitor for_false(owner(), temp_index()); |
| 1138 node->false_expr()->Visit(&for_false); | 1122 node->false_expr()->Visit(&for_false); |
| 1139 ASSERT(for_false.is_open()); | 1123 ASSERT(for_false.is_open()); |
| 1140 for_false.Do(BuildStoreExprTemp(for_false.value())); | 1124 for_false.Do(BuildStoreExprTemp(for_false.value())); |
| 1141 | 1125 |
| 1142 Join(for_test, for_true, for_false); | 1126 Join(for_test, for_true, for_false); |
| 1143 ReturnDefinition(BuildLoadExprTemp()); | 1127 ReturnDefinition(BuildLoadExprTemp()); |
| 1144 } | 1128 } |
| 1145 | 1129 |
| 1146 | 1130 |
| 1147 // <Statement> ::= If { condition: <Expression> | 1131 // <Statement> ::= If { condition: <Expression> |
| 1148 // true_branch: <Sequence> | 1132 // true_branch: <Sequence> |
| 1149 // false_branch: <Sequence> } | 1133 // false_branch: <Sequence> } |
| 1150 void EffectGraphVisitor::VisitIfNode(IfNode* node) { | 1134 void EffectGraphVisitor::VisitIfNode(IfNode* node) { |
| 1151 TestGraphVisitor for_test(owner(), | 1135 TestGraphVisitor for_test(owner(), |
| 1152 temp_index(), | 1136 temp_index(), |
| 1153 loop_depth(), | |
| 1154 node->condition()->token_pos()); | 1137 node->condition()->token_pos()); |
| 1155 node->condition()->Visit(&for_test); | 1138 node->condition()->Visit(&for_test); |
| 1156 | 1139 |
| 1157 EffectGraphVisitor for_true(owner(), temp_index(), loop_depth()); | 1140 EffectGraphVisitor for_true(owner(), temp_index()); |
| 1158 EffectGraphVisitor for_false(owner(), temp_index(), loop_depth()); | 1141 EffectGraphVisitor for_false(owner(), temp_index()); |
| 1159 | 1142 |
| 1160 node->true_branch()->Visit(&for_true); | 1143 node->true_branch()->Visit(&for_true); |
| 1161 // The for_false graph fragment will be empty (default graph fragment) if | 1144 // The for_false graph fragment will be empty (default graph fragment) if |
| 1162 // we do not call Visit. | 1145 // we do not call Visit. |
| 1163 if (node->false_branch() != NULL) node->false_branch()->Visit(&for_false); | 1146 if (node->false_branch() != NULL) node->false_branch()->Visit(&for_false); |
| 1164 Join(for_test, for_true, for_false); | 1147 Join(for_test, for_true, for_false); |
| 1165 } | 1148 } |
| 1166 | 1149 |
| 1167 | 1150 |
| 1168 void EffectGraphVisitor::VisitSwitchNode(SwitchNode* node) { | 1151 void EffectGraphVisitor::VisitSwitchNode(SwitchNode* node) { |
| 1169 EffectGraphVisitor switch_body(owner(), temp_index(), loop_depth()); | 1152 EffectGraphVisitor switch_body(owner(), temp_index()); |
| 1170 node->body()->Visit(&switch_body); | 1153 node->body()->Visit(&switch_body); |
| 1171 Append(switch_body); | 1154 Append(switch_body); |
| 1172 if ((node->label() != NULL) && (node->label()->join_for_break() != NULL)) { | 1155 if ((node->label() != NULL) && (node->label()->join_for_break() != NULL)) { |
| 1173 node->label()->join_for_break()->set_loop_depth(loop_depth()); | |
| 1174 if (is_open()) Goto(node->label()->join_for_break()); | 1156 if (is_open()) Goto(node->label()->join_for_break()); |
| 1175 exit_ = node->label()->join_for_break(); | 1157 exit_ = node->label()->join_for_break(); |
| 1176 } | 1158 } |
| 1177 // No continue label allowed. | 1159 // No continue label allowed. |
| 1178 ASSERT((node->label() == NULL) || | 1160 ASSERT((node->label() == NULL) || |
| 1179 (node->label()->join_for_continue() == NULL)); | 1161 (node->label()->join_for_continue() == NULL)); |
| 1180 } | 1162 } |
| 1181 | 1163 |
| 1182 | 1164 |
| 1183 // A case node contains zero or more case expressions, can contain default | 1165 // A case node contains zero or more case expressions, can contain default |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1197 // g) case-statements-join | 1179 // g) case-statements-join |
| 1198 // h) [ case-statements ] -> exit-join | 1180 // h) [ case-statements ] -> exit-join |
| 1199 // i) exit-target -> exit-join | 1181 // i) exit-target -> exit-join |
| 1200 // j) exit-join | 1182 // j) exit-join |
| 1201 // | 1183 // |
| 1202 // Note: The specification of switch/case is under discussion and may change | 1184 // Note: The specification of switch/case is under discussion and may change |
| 1203 // drastically. | 1185 // drastically. |
| 1204 void EffectGraphVisitor::VisitCaseNode(CaseNode* node) { | 1186 void EffectGraphVisitor::VisitCaseNode(CaseNode* node) { |
| 1205 const intptr_t len = node->case_expressions()->length(); | 1187 const intptr_t len = node->case_expressions()->length(); |
| 1206 // Create case statements instructions. | 1188 // Create case statements instructions. |
| 1207 EffectGraphVisitor for_case_statements(owner(), temp_index(), loop_depth()); | 1189 EffectGraphVisitor for_case_statements(owner(), temp_index()); |
| 1208 // Compute start of statements fragment. | 1190 // Compute start of statements fragment. |
| 1209 JoinEntryInstr* statement_start = NULL; | 1191 JoinEntryInstr* statement_start = NULL; |
| 1210 if ((node->label() != NULL) && node->label()->is_continue_target()) { | 1192 if ((node->label() != NULL) && node->label()->is_continue_target()) { |
| 1211 // Since a labeled jump continue statement occur in a different case node, | 1193 // Since a labeled jump continue statement occur in a different case node, |
| 1212 // allocate JoinNode here and use it as statement start. | 1194 // allocate JoinNode here and use it as statement start. |
| 1213 statement_start = node->label()->join_for_continue(); | 1195 statement_start = node->label()->join_for_continue(); |
| 1214 if (statement_start == NULL) { | 1196 if (statement_start == NULL) { |
| 1215 statement_start = new JoinEntryInstr(owner()->AllocateBlockId(), | 1197 statement_start = new JoinEntryInstr(owner()->AllocateBlockId(), |
| 1216 owner()->try_index(), | 1198 owner()->try_index()); |
| 1217 loop_depth()); | |
| 1218 node->label()->set_join_for_continue(statement_start); | 1199 node->label()->set_join_for_continue(statement_start); |
| 1219 } | 1200 } |
| 1220 } else { | 1201 } else { |
| 1221 statement_start = new JoinEntryInstr(owner()->AllocateBlockId(), | 1202 statement_start = new JoinEntryInstr(owner()->AllocateBlockId(), |
| 1222 owner()->try_index(), | 1203 owner()->try_index()); |
| 1223 loop_depth()); | |
| 1224 } | 1204 } |
| 1225 node->statements()->Visit(&for_case_statements); | 1205 node->statements()->Visit(&for_case_statements); |
| 1226 Instruction* statement_exit = | 1206 Instruction* statement_exit = |
| 1227 AppendFragment(statement_start, for_case_statements); | 1207 AppendFragment(statement_start, for_case_statements); |
| 1228 if (is_open() && (len == 0)) { | 1208 if (is_open() && (len == 0)) { |
| 1229 ASSERT(node->contains_default()); | 1209 ASSERT(node->contains_default()); |
| 1230 // Default only case node. | 1210 // Default only case node. |
| 1231 Goto(statement_start); | 1211 Goto(statement_start); |
| 1232 exit_ = statement_exit; | 1212 exit_ = statement_exit; |
| 1233 return; | 1213 return; |
| 1234 } | 1214 } |
| 1235 | 1215 |
| 1236 // Generate instructions for all case expressions. | 1216 // Generate instructions for all case expressions. |
| 1237 TargetEntryInstr* next_target = NULL; | 1217 TargetEntryInstr* next_target = NULL; |
| 1238 for (intptr_t i = 0; i < len; i++) { | 1218 for (intptr_t i = 0; i < len; i++) { |
| 1239 AstNode* case_expr = node->case_expressions()->NodeAt(i); | 1219 AstNode* case_expr = node->case_expressions()->NodeAt(i); |
| 1240 TestGraphVisitor for_case_expression(owner(), | 1220 TestGraphVisitor for_case_expression(owner(), |
| 1241 temp_index(), | 1221 temp_index(), |
| 1242 loop_depth(), | |
| 1243 case_expr->token_pos()); | 1222 case_expr->token_pos()); |
| 1244 case_expr->Visit(&for_case_expression); | 1223 case_expr->Visit(&for_case_expression); |
| 1245 if (i == 0) { | 1224 if (i == 0) { |
| 1246 // Append only the first one, everything else is connected from it. | 1225 // Append only the first one, everything else is connected from it. |
| 1247 Append(for_case_expression); | 1226 Append(for_case_expression); |
| 1248 } else { | 1227 } else { |
| 1249 ASSERT(next_target != NULL); | 1228 ASSERT(next_target != NULL); |
| 1250 AppendFragment(next_target, for_case_expression); | 1229 AppendFragment(next_target, for_case_expression); |
| 1251 } | 1230 } |
| 1252 for_case_expression.IfTrueGoto(statement_start); | 1231 for_case_expression.IfTrueGoto(statement_start); |
| 1253 next_target = for_case_expression.CreateFalseSuccessor()->AsTargetEntry(); | 1232 next_target = for_case_expression.CreateFalseSuccessor()->AsTargetEntry(); |
| 1254 } | 1233 } |
| 1255 | 1234 |
| 1256 // Once a test fragment has been added, this fragment is closed. | 1235 // Once a test fragment has been added, this fragment is closed. |
| 1257 ASSERT(!is_open()); | 1236 ASSERT(!is_open()); |
| 1258 | 1237 |
| 1259 Instruction* exit_instruction = NULL; | 1238 Instruction* exit_instruction = NULL; |
| 1260 // Handle last (or only) case: false goes to exit or to statement if this | 1239 // Handle last (or only) case: false goes to exit or to statement if this |
| 1261 // node contains default. | 1240 // node contains default. |
| 1262 if (len > 0) { | 1241 if (len > 0) { |
| 1263 ASSERT(next_target != NULL); | 1242 ASSERT(next_target != NULL); |
| 1264 if (node->contains_default()) { | 1243 if (node->contains_default()) { |
| 1265 // True and false go to statement start. | 1244 // True and false go to statement start. |
| 1266 next_target->Goto(statement_start); | 1245 next_target->Goto(statement_start); |
| 1267 exit_instruction = statement_exit; | 1246 exit_instruction = statement_exit; |
| 1268 } else { | 1247 } else { |
| 1269 if (statement_exit != NULL) { | 1248 if (statement_exit != NULL) { |
| 1270 JoinEntryInstr* join = new JoinEntryInstr(owner()->AllocateBlockId(), | 1249 JoinEntryInstr* join = new JoinEntryInstr(owner()->AllocateBlockId(), |
| 1271 owner()->try_index(), | 1250 owner()->try_index()); |
| 1272 loop_depth()); | |
| 1273 statement_exit->Goto(join); | 1251 statement_exit->Goto(join); |
| 1274 next_target->Goto(join); | 1252 next_target->Goto(join); |
| 1275 exit_instruction = join; | 1253 exit_instruction = join; |
| 1276 } else { | 1254 } else { |
| 1277 exit_instruction = next_target; | 1255 exit_instruction = next_target; |
| 1278 } | 1256 } |
| 1279 } | 1257 } |
| 1280 } else { | 1258 } else { |
| 1281 // A CaseNode without case expressions must contain default. | 1259 // A CaseNode without case expressions must contain default. |
| 1282 ASSERT(node->contains_default()); | 1260 ASSERT(node->contains_default()); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1296 // a) loop-join | 1274 // a) loop-join |
| 1297 // b) [ test ] -> (body-entry-target, loop-exit-target) | 1275 // b) [ test ] -> (body-entry-target, loop-exit-target) |
| 1298 // c) body-entry-target | 1276 // c) body-entry-target |
| 1299 // d) [ body ] -> (continue-join) | 1277 // d) [ body ] -> (continue-join) |
| 1300 // e) continue-join -> (loop-join) | 1278 // e) continue-join -> (loop-join) |
| 1301 // f) loop-exit-target | 1279 // f) loop-exit-target |
| 1302 // g) break-join (optional) | 1280 // g) break-join (optional) |
| 1303 void EffectGraphVisitor::VisitWhileNode(WhileNode* node) { | 1281 void EffectGraphVisitor::VisitWhileNode(WhileNode* node) { |
| 1304 TestGraphVisitor for_test(owner(), | 1282 TestGraphVisitor for_test(owner(), |
| 1305 temp_index(), | 1283 temp_index(), |
| 1306 loop_depth() + 1, | |
| 1307 node->condition()->token_pos()); | 1284 node->condition()->token_pos()); |
| 1308 node->condition()->Visit(&for_test); | 1285 node->condition()->Visit(&for_test); |
| 1309 ASSERT(!for_test.is_empty()); // Language spec. | 1286 ASSERT(!for_test.is_empty()); // Language spec. |
| 1310 | 1287 |
| 1311 EffectGraphVisitor for_body(owner(), temp_index(), loop_depth() + 1); | 1288 EffectGraphVisitor for_body(owner(), temp_index()); |
| 1312 for_body.AddInstruction( | 1289 for_body.AddInstruction( |
| 1313 new CheckStackOverflowInstr(node->token_pos())); | 1290 new CheckStackOverflowInstr(node->token_pos())); |
| 1314 node->body()->Visit(&for_body); | 1291 node->body()->Visit(&for_body); |
| 1315 | 1292 |
| 1316 // Labels are set after body traversal. | 1293 // Labels are set after body traversal. |
| 1317 SourceLabel* lbl = node->label(); | 1294 SourceLabel* lbl = node->label(); |
| 1318 ASSERT(lbl != NULL); | 1295 ASSERT(lbl != NULL); |
| 1319 JoinEntryInstr* join = lbl->join_for_continue(); | 1296 JoinEntryInstr* join = lbl->join_for_continue(); |
| 1320 if (join != NULL) { | 1297 if (join != NULL) { |
| 1321 join->set_loop_depth(loop_depth() + 1); | |
| 1322 if (for_body.is_open()) for_body.Goto(join); | 1298 if (for_body.is_open()) for_body.Goto(join); |
| 1323 for_body.exit_ = join; | 1299 for_body.exit_ = join; |
| 1324 } | 1300 } |
| 1325 TieLoop(for_test, for_body); | 1301 TieLoop(for_test, for_body); |
| 1326 join = lbl->join_for_break(); | 1302 join = lbl->join_for_break(); |
| 1327 if (join != NULL) { | 1303 if (join != NULL) { |
| 1328 join->set_loop_depth(loop_depth()); | |
| 1329 Goto(join); | 1304 Goto(join); |
| 1330 exit_ = join; | 1305 exit_ = join; |
| 1331 } | 1306 } |
| 1332 } | 1307 } |
| 1333 | 1308 |
| 1334 | 1309 |
| 1335 // The fragment is composed as follows: | 1310 // The fragment is composed as follows: |
| 1336 // a) body-entry-join | 1311 // a) body-entry-join |
| 1337 // b) [ body ] | 1312 // b) [ body ] |
| 1338 // c) test-entry (continue-join or body-exit-target) | 1313 // c) test-entry (continue-join or body-exit-target) |
| 1339 // d) [ test-entry ] -> (back-target, loop-exit-target) | 1314 // d) [ test-entry ] -> (back-target, loop-exit-target) |
| 1340 // e) back-target -> (body-entry-join) | 1315 // e) back-target -> (body-entry-join) |
| 1341 // f) loop-exit-target | 1316 // f) loop-exit-target |
| 1342 // g) break-join | 1317 // g) break-join |
| 1343 void EffectGraphVisitor::VisitDoWhileNode(DoWhileNode* node) { | 1318 void EffectGraphVisitor::VisitDoWhileNode(DoWhileNode* node) { |
| 1344 // Traverse body first in order to generate continue and break labels. | 1319 // Traverse body first in order to generate continue and break labels. |
| 1345 EffectGraphVisitor for_body(owner(), temp_index(), loop_depth() + 1); | 1320 EffectGraphVisitor for_body(owner(), temp_index()); |
| 1346 for_body.AddInstruction( | 1321 for_body.AddInstruction( |
| 1347 new CheckStackOverflowInstr(node->token_pos())); | 1322 new CheckStackOverflowInstr(node->token_pos())); |
| 1348 node->body()->Visit(&for_body); | 1323 node->body()->Visit(&for_body); |
| 1349 | 1324 |
| 1350 TestGraphVisitor for_test(owner(), | 1325 TestGraphVisitor for_test(owner(), |
| 1351 temp_index(), | 1326 temp_index(), |
| 1352 loop_depth() + 1, | |
| 1353 node->condition()->token_pos()); | 1327 node->condition()->token_pos()); |
| 1354 node->condition()->Visit(&for_test); | 1328 node->condition()->Visit(&for_test); |
| 1355 ASSERT(is_open()); | 1329 ASSERT(is_open()); |
| 1356 | 1330 |
| 1357 // Tie do-while loop (test is after the body). | 1331 // Tie do-while loop (test is after the body). |
| 1358 JoinEntryInstr* body_entry_join = | 1332 JoinEntryInstr* body_entry_join = |
| 1359 new JoinEntryInstr(owner()->AllocateBlockId(), | 1333 new JoinEntryInstr(owner()->AllocateBlockId(), |
| 1360 owner()->try_index(), | 1334 owner()->try_index()); |
| 1361 loop_depth() + 1); | |
| 1362 Goto(body_entry_join); | 1335 Goto(body_entry_join); |
| 1363 Instruction* body_exit = AppendFragment(body_entry_join, for_body); | 1336 Instruction* body_exit = AppendFragment(body_entry_join, for_body); |
| 1364 | 1337 |
| 1365 JoinEntryInstr* join = node->label()->join_for_continue(); | 1338 JoinEntryInstr* join = node->label()->join_for_continue(); |
| 1366 if ((body_exit != NULL) || (join != NULL)) { | 1339 if ((body_exit != NULL) || (join != NULL)) { |
| 1367 if (join == NULL) { | 1340 if (join == NULL) { |
| 1368 join = new JoinEntryInstr(owner()->AllocateBlockId(), | 1341 join = new JoinEntryInstr(owner()->AllocateBlockId(), |
| 1369 owner()->try_index(), | 1342 owner()->try_index()); |
| 1370 loop_depth() + 1); | |
| 1371 } else { | |
| 1372 join->set_loop_depth(loop_depth() + 1); | |
| 1373 } | 1343 } |
| 1374 join->LinkTo(for_test.entry()); | 1344 join->LinkTo(for_test.entry()); |
| 1375 if (body_exit != NULL) { | 1345 if (body_exit != NULL) { |
| 1376 body_exit->Goto(join); | 1346 body_exit->Goto(join); |
| 1377 } | 1347 } |
| 1378 } | 1348 } |
| 1379 | 1349 |
| 1380 for_test.IfTrueGoto(body_entry_join); | 1350 for_test.IfTrueGoto(body_entry_join); |
| 1381 join = node->label()->join_for_break(); | 1351 join = node->label()->join_for_break(); |
| 1382 if (join == NULL) { | 1352 if (join == NULL) { |
| 1383 exit_ = for_test.CreateFalseSuccessor(); | 1353 exit_ = for_test.CreateFalseSuccessor(); |
| 1384 } else { | 1354 } else { |
| 1385 join->set_loop_depth(loop_depth()); | |
| 1386 for_test.IfFalseGoto(join); | 1355 for_test.IfFalseGoto(join); |
| 1387 exit_ = join; | 1356 exit_ = join; |
| 1388 } | 1357 } |
| 1389 } | 1358 } |
| 1390 | 1359 |
| 1391 | 1360 |
| 1392 // A ForNode can contain break and continue jumps. 'break' joins to | 1361 // A ForNode can contain break and continue jumps. 'break' joins to |
| 1393 // ForNode exit, 'continue' joins at increment entry. The fragment is composed | 1362 // ForNode exit, 'continue' joins at increment entry. The fragment is composed |
| 1394 // as follows: | 1363 // as follows: |
| 1395 // a) [ initializer ] | 1364 // a) [ initializer ] |
| 1396 // b) loop-join | 1365 // b) loop-join |
| 1397 // c) [ test ] -> (body-entry-target, loop-exit-target) | 1366 // c) [ test ] -> (body-entry-target, loop-exit-target) |
| 1398 // d) body-entry-target | 1367 // d) body-entry-target |
| 1399 // e) [ body ] | 1368 // e) [ body ] |
| 1400 // f) continue-join (optional) | 1369 // f) continue-join (optional) |
| 1401 // g) [ increment ] -> (loop-join) | 1370 // g) [ increment ] -> (loop-join) |
| 1402 // h) loop-exit-target | 1371 // h) loop-exit-target |
| 1403 // i) break-join | 1372 // i) break-join |
| 1404 void EffectGraphVisitor::VisitForNode(ForNode* node) { | 1373 void EffectGraphVisitor::VisitForNode(ForNode* node) { |
| 1405 EffectGraphVisitor for_initializer(owner(), temp_index(), loop_depth()); | 1374 EffectGraphVisitor for_initializer(owner(), temp_index()); |
| 1406 node->initializer()->Visit(&for_initializer); | 1375 node->initializer()->Visit(&for_initializer); |
| 1407 Append(for_initializer); | 1376 Append(for_initializer); |
| 1408 ASSERT(is_open()); | 1377 ASSERT(is_open()); |
| 1409 | 1378 |
| 1410 // Compose body to set any jump labels. | 1379 // Compose body to set any jump labels. |
| 1411 EffectGraphVisitor for_body(owner(), temp_index(), loop_depth() + 1); | 1380 EffectGraphVisitor for_body(owner(), temp_index()); |
| 1412 for_body.AddInstruction( | 1381 for_body.AddInstruction( |
| 1413 new CheckStackOverflowInstr(node->token_pos())); | 1382 new CheckStackOverflowInstr(node->token_pos())); |
| 1414 node->body()->Visit(&for_body); | 1383 node->body()->Visit(&for_body); |
| 1415 | 1384 |
| 1416 // Join loop body, increment and compute their end instruction. | 1385 // Join loop body, increment and compute their end instruction. |
| 1417 ASSERT(!for_body.is_empty()); | 1386 ASSERT(!for_body.is_empty()); |
| 1418 Instruction* loop_increment_end = NULL; | 1387 Instruction* loop_increment_end = NULL; |
| 1419 EffectGraphVisitor for_increment(owner(), temp_index(), loop_depth() + 1); | 1388 EffectGraphVisitor for_increment(owner(), temp_index()); |
| 1420 node->increment()->Visit(&for_increment); | 1389 node->increment()->Visit(&for_increment); |
| 1421 JoinEntryInstr* join = node->label()->join_for_continue(); | 1390 JoinEntryInstr* join = node->label()->join_for_continue(); |
| 1422 if (join != NULL) { | 1391 if (join != NULL) { |
| 1423 join->set_loop_depth(loop_depth() + 1); | |
| 1424 // Insert the join between the body and increment. | 1392 // Insert the join between the body and increment. |
| 1425 if (for_body.is_open()) for_body.Goto(join); | 1393 if (for_body.is_open()) for_body.Goto(join); |
| 1426 loop_increment_end = AppendFragment(join, for_increment); | 1394 loop_increment_end = AppendFragment(join, for_increment); |
| 1427 ASSERT(loop_increment_end != NULL); | 1395 ASSERT(loop_increment_end != NULL); |
| 1428 } else if (for_body.is_open()) { | 1396 } else if (for_body.is_open()) { |
| 1429 // Do not insert an extra basic block. | 1397 // Do not insert an extra basic block. |
| 1430 for_body.Append(for_increment); | 1398 for_body.Append(for_increment); |
| 1431 loop_increment_end = for_body.exit(); | 1399 loop_increment_end = for_body.exit(); |
| 1432 // 'for_body' contains at least the stack check. | 1400 // 'for_body' contains at least the stack check. |
| 1433 ASSERT(loop_increment_end != NULL); | 1401 ASSERT(loop_increment_end != NULL); |
| 1434 } else { | 1402 } else { |
| 1435 loop_increment_end = NULL; | 1403 loop_increment_end = NULL; |
| 1436 } | 1404 } |
| 1437 | 1405 |
| 1438 // 'loop_increment_end' is NULL only if there is no join for continue and the | 1406 // 'loop_increment_end' is NULL only if there is no join for continue and the |
| 1439 // body is not open, i.e., no backward branch exists. | 1407 // body is not open, i.e., no backward branch exists. |
| 1440 if (loop_increment_end != NULL) { | 1408 if (loop_increment_end != NULL) { |
| 1441 JoinEntryInstr* loop_start = | 1409 JoinEntryInstr* loop_start = |
| 1442 new JoinEntryInstr(owner()->AllocateBlockId(), | 1410 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); |
| 1443 owner()->try_index(), | |
| 1444 loop_depth() + 1); | |
| 1445 Goto(loop_start); | 1411 Goto(loop_start); |
| 1446 loop_increment_end->Goto(loop_start); | 1412 loop_increment_end->Goto(loop_start); |
| 1447 exit_ = loop_start; | 1413 exit_ = loop_start; |
| 1448 } | 1414 } |
| 1449 | 1415 |
| 1450 if (node->condition() == NULL) { | 1416 if (node->condition() == NULL) { |
| 1451 // Endless loop, no test. | 1417 // Endless loop, no test. |
| 1452 JoinEntryInstr* body_entry = | 1418 JoinEntryInstr* body_entry = |
| 1453 new JoinEntryInstr(owner()->AllocateBlockId(), | 1419 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); |
| 1454 owner()->try_index(), | |
| 1455 loop_depth() + 1); | |
| 1456 AppendFragment(body_entry, for_body); | 1420 AppendFragment(body_entry, for_body); |
| 1457 Goto(body_entry); | 1421 Goto(body_entry); |
| 1458 if (node->label()->join_for_break() != NULL) { | 1422 if (node->label()->join_for_break() != NULL) { |
| 1459 node->label()->join_for_break()->set_loop_depth(loop_depth()); | |
| 1460 // Control flow of ForLoop continues into join_for_break. | 1423 // Control flow of ForLoop continues into join_for_break. |
| 1461 exit_ = node->label()->join_for_break(); | 1424 exit_ = node->label()->join_for_break(); |
| 1462 } | 1425 } |
| 1463 } else { | 1426 } else { |
| 1464 TestGraphVisitor for_test(owner(), | 1427 TestGraphVisitor for_test(owner(), |
| 1465 temp_index(), | 1428 temp_index(), |
| 1466 loop_depth() + 1, | |
| 1467 node->condition()->token_pos()); | 1429 node->condition()->token_pos()); |
| 1468 node->condition()->Visit(&for_test); | 1430 node->condition()->Visit(&for_test); |
| 1469 Append(for_test); | 1431 Append(for_test); |
| 1470 | 1432 |
| 1471 BlockEntryInstr* body_entry = for_test.CreateTrueSuccessor(); | 1433 BlockEntryInstr* body_entry = for_test.CreateTrueSuccessor(); |
| 1472 AppendFragment(body_entry, for_body); | 1434 AppendFragment(body_entry, for_body); |
| 1473 | 1435 |
| 1474 if (node->label()->join_for_break() == NULL) { | 1436 if (node->label()->join_for_break() == NULL) { |
| 1475 exit_ = for_test.CreateFalseSuccessor(); | 1437 exit_ = for_test.CreateFalseSuccessor(); |
| 1476 } else { | 1438 } else { |
| 1477 node->label()->join_for_break()->set_loop_depth(loop_depth()); | |
| 1478 for_test.IfFalseGoto(node->label()->join_for_break()); | 1439 for_test.IfFalseGoto(node->label()->join_for_break()); |
| 1479 exit_ = node->label()->join_for_break(); | 1440 exit_ = node->label()->join_for_break(); |
| 1480 } | 1441 } |
| 1481 } | 1442 } |
| 1482 } | 1443 } |
| 1483 | 1444 |
| 1484 | 1445 |
| 1485 void EffectGraphVisitor::VisitJumpNode(JumpNode* node) { | 1446 void EffectGraphVisitor::VisitJumpNode(JumpNode* node) { |
| 1486 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { | 1447 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { |
| 1487 EffectGraphVisitor for_effect(owner(), temp_index(), loop_depth()); | 1448 EffectGraphVisitor for_effect(owner(), temp_index()); |
| 1488 node->InlinedFinallyNodeAt(i)->Visit(&for_effect); | 1449 node->InlinedFinallyNodeAt(i)->Visit(&for_effect); |
| 1489 Append(for_effect); | 1450 Append(for_effect); |
| 1490 if (!is_open()) return; | 1451 if (!is_open()) return; |
| 1491 } | 1452 } |
| 1492 | 1453 |
| 1493 // Unchain the context(s) up to the outer context level of the scope which | 1454 // Unchain the context(s) up to the outer context level of the scope which |
| 1494 // contains the destination label. | 1455 // contains the destination label. |
| 1495 SourceLabel* label = node->label(); | 1456 SourceLabel* label = node->label(); |
| 1496 ASSERT(label->owner() != NULL); | 1457 ASSERT(label->owner() != NULL); |
| 1497 int target_context_level = 0; | 1458 int target_context_level = 0; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1515 intptr_t current_context_level = owner()->context_level(); | 1476 intptr_t current_context_level = owner()->context_level(); |
| 1516 ASSERT(current_context_level >= target_context_level); | 1477 ASSERT(current_context_level >= target_context_level); |
| 1517 while (current_context_level-- > target_context_level) { | 1478 while (current_context_level-- > target_context_level) { |
| 1518 UnchainContext(); | 1479 UnchainContext(); |
| 1519 } | 1480 } |
| 1520 | 1481 |
| 1521 JoinEntryInstr* jump_target = NULL; | 1482 JoinEntryInstr* jump_target = NULL; |
| 1522 if (node->kind() == Token::kBREAK) { | 1483 if (node->kind() == Token::kBREAK) { |
| 1523 if (node->label()->join_for_break() == NULL) { | 1484 if (node->label()->join_for_break() == NULL) { |
| 1524 node->label()->set_join_for_break( | 1485 node->label()->set_join_for_break( |
| 1525 new JoinEntryInstr(owner()->AllocateBlockId(), | 1486 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index())); |
| 1526 owner()->try_index(), | |
| 1527 BlockEntryInstr::kInvalidLoopDepth)); | |
| 1528 } | 1487 } |
| 1529 jump_target = node->label()->join_for_break(); | 1488 jump_target = node->label()->join_for_break(); |
| 1530 } else { | 1489 } else { |
| 1531 if (node->label()->join_for_continue() == NULL) { | 1490 if (node->label()->join_for_continue() == NULL) { |
| 1532 node->label()->set_join_for_continue( | 1491 node->label()->set_join_for_continue( |
| 1533 new JoinEntryInstr(owner()->AllocateBlockId(), | 1492 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index())); |
| 1534 owner()->try_index(), | |
| 1535 BlockEntryInstr::kInvalidLoopDepth)); | |
| 1536 } | 1493 } |
| 1537 jump_target = node->label()->join_for_continue(); | 1494 jump_target = node->label()->join_for_continue(); |
| 1538 } | 1495 } |
| 1539 Goto(jump_target); | 1496 Goto(jump_target); |
| 1540 } | 1497 } |
| 1541 | 1498 |
| 1542 | 1499 |
| 1543 void EffectGraphVisitor::VisitArgumentListNode(ArgumentListNode* node) { | 1500 void EffectGraphVisitor::VisitArgumentListNode(ArgumentListNode* node) { |
| 1544 UNREACHABLE(); | 1501 UNREACHABLE(); |
| 1545 } | 1502 } |
| 1546 | 1503 |
| 1547 | 1504 |
| 1548 void EffectGraphVisitor::VisitArgumentDefinitionTestNode( | 1505 void EffectGraphVisitor::VisitArgumentDefinitionTestNode( |
| 1549 ArgumentDefinitionTestNode* node) { | 1506 ArgumentDefinitionTestNode* node) { |
| 1550 InlineBailout("EffectGraphVisitor::VisitArgumentDefinitionTestNode"); | 1507 InlineBailout("EffectGraphVisitor::VisitArgumentDefinitionTestNode"); |
| 1551 Definition* load = BuildLoadLocal(node->saved_arguments_descriptor()); | 1508 Definition* load = BuildLoadLocal(node->saved_arguments_descriptor()); |
| 1552 Value* arguments_descriptor = Bind(load); | 1509 Value* arguments_descriptor = Bind(load); |
| 1553 ArgumentDefinitionTestInstr* arg_def_test = | 1510 ArgumentDefinitionTestInstr* arg_def_test = |
| 1554 new ArgumentDefinitionTestInstr(node, arguments_descriptor); | 1511 new ArgumentDefinitionTestInstr(node, arguments_descriptor); |
| 1555 ReturnDefinition(arg_def_test); | 1512 ReturnDefinition(arg_def_test); |
| 1556 } | 1513 } |
| 1557 | 1514 |
| 1558 | 1515 |
| 1559 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) { | 1516 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) { |
| 1560 // Translate the array elements and collect their values. | 1517 // Translate the array elements and collect their values. |
| 1561 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1518 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1562 new ZoneGrowableArray<PushArgumentInstr*>(node->length()); | 1519 new ZoneGrowableArray<PushArgumentInstr*>(node->length()); |
| 1563 for (int i = 0; i < node->length(); ++i) { | 1520 for (int i = 0; i < node->length(); ++i) { |
| 1564 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); | 1521 ValueGraphVisitor for_value(owner(), temp_index()); |
| 1565 node->ElementAt(i)->Visit(&for_value); | 1522 node->ElementAt(i)->Visit(&for_value); |
| 1566 Append(for_value); | 1523 Append(for_value); |
| 1567 arguments->Add(PushArgument(for_value.value())); | 1524 arguments->Add(PushArgument(for_value.value())); |
| 1568 } | 1525 } |
| 1569 const AbstractTypeArguments& type_args = | 1526 const AbstractTypeArguments& type_args = |
| 1570 AbstractTypeArguments::ZoneHandle(node->type().arguments()); | 1527 AbstractTypeArguments::ZoneHandle(node->type().arguments()); |
| 1571 Value* element_type = BuildInstantiatedTypeArguments(node->token_pos(), | 1528 Value* element_type = BuildInstantiatedTypeArguments(node->token_pos(), |
| 1572 type_args); | 1529 type_args); |
| 1573 CreateArrayInstr* create = new CreateArrayInstr(node->token_pos(), | 1530 CreateArrayInstr* create = new CreateArrayInstr(node->token_pos(), |
| 1574 arguments, | 1531 arguments, |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1601 // TODO(regis): Why are we not doing this in the parser? | 1558 // TODO(regis): Why are we not doing this in the parser? |
| 1602 const ContextScope& context_scope = ContextScope::ZoneHandle( | 1559 const ContextScope& context_scope = ContextScope::ZoneHandle( |
| 1603 node->scope()->PreserveOuterScope(owner()->context_level())); | 1560 node->scope()->PreserveOuterScope(owner()->context_level())); |
| 1604 ASSERT(!function.HasCode()); | 1561 ASSERT(!function.HasCode()); |
| 1605 ASSERT(function.context_scope() == ContextScope::null()); | 1562 ASSERT(function.context_scope() == ContextScope::null()); |
| 1606 function.set_context_scope(context_scope); | 1563 function.set_context_scope(context_scope); |
| 1607 } | 1564 } |
| 1608 receiver = BuildNullValue(); | 1565 receiver = BuildNullValue(); |
| 1609 } else { | 1566 } else { |
| 1610 ASSERT(function.IsImplicitInstanceClosureFunction()); | 1567 ASSERT(function.IsImplicitInstanceClosureFunction()); |
| 1611 ValueGraphVisitor for_receiver(owner(), temp_index(), loop_depth()); | 1568 ValueGraphVisitor for_receiver(owner(), temp_index()); |
| 1612 node->receiver()->Visit(&for_receiver); | 1569 node->receiver()->Visit(&for_receiver); |
| 1613 Append(for_receiver); | 1570 Append(for_receiver); |
| 1614 receiver = for_receiver.value(); | 1571 receiver = for_receiver.value(); |
| 1615 } | 1572 } |
| 1616 PushArgumentInstr* push_receiver = PushArgument(receiver); | 1573 PushArgumentInstr* push_receiver = PushArgument(receiver); |
| 1617 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1574 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1618 new ZoneGrowableArray<PushArgumentInstr*>(2); | 1575 new ZoneGrowableArray<PushArgumentInstr*>(2); |
| 1619 arguments->Add(push_receiver); | 1576 arguments->Add(push_receiver); |
| 1620 ASSERT(function.context_scope() != ContextScope::null()); | 1577 ASSERT(function.context_scope() != ContextScope::null()); |
| 1621 | 1578 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1635 arguments->Add(push_type_arguments); | 1592 arguments->Add(push_type_arguments); |
| 1636 ReturnDefinition( | 1593 ReturnDefinition( |
| 1637 new CreateClosureInstr(node->function(), arguments, node->token_pos())); | 1594 new CreateClosureInstr(node->function(), arguments, node->token_pos())); |
| 1638 } | 1595 } |
| 1639 | 1596 |
| 1640 | 1597 |
| 1641 void EffectGraphVisitor::TranslateArgumentList( | 1598 void EffectGraphVisitor::TranslateArgumentList( |
| 1642 const ArgumentListNode& node, | 1599 const ArgumentListNode& node, |
| 1643 ZoneGrowableArray<Value*>* values) { | 1600 ZoneGrowableArray<Value*>* values) { |
| 1644 for (intptr_t i = 0; i < node.length(); ++i) { | 1601 for (intptr_t i = 0; i < node.length(); ++i) { |
| 1645 ValueGraphVisitor for_argument(owner(), temp_index(), loop_depth()); | 1602 ValueGraphVisitor for_argument(owner(), temp_index()); |
| 1646 node.NodeAt(i)->Visit(&for_argument); | 1603 node.NodeAt(i)->Visit(&for_argument); |
| 1647 Append(for_argument); | 1604 Append(for_argument); |
| 1648 values->Add(for_argument.value()); | 1605 values->Add(for_argument.value()); |
| 1649 } | 1606 } |
| 1650 } | 1607 } |
| 1651 | 1608 |
| 1652 | 1609 |
| 1653 void EffectGraphVisitor::BuildPushArguments( | 1610 void EffectGraphVisitor::BuildPushArguments( |
| 1654 const ArgumentListNode& node, | 1611 const ArgumentListNode& node, |
| 1655 ZoneGrowableArray<PushArgumentInstr*>* values) { | 1612 ZoneGrowableArray<PushArgumentInstr*>* values) { |
| 1656 for (intptr_t i = 0; i < node.length(); ++i) { | 1613 for (intptr_t i = 0; i < node.length(); ++i) { |
| 1657 ValueGraphVisitor for_argument(owner(), temp_index(), loop_depth()); | 1614 ValueGraphVisitor for_argument(owner(), temp_index()); |
| 1658 node.NodeAt(i)->Visit(&for_argument); | 1615 node.NodeAt(i)->Visit(&for_argument); |
| 1659 Append(for_argument); | 1616 Append(for_argument); |
| 1660 PushArgumentInstr* push_arg = PushArgument(for_argument.value()); | 1617 PushArgumentInstr* push_arg = PushArgument(for_argument.value()); |
| 1661 values->Add(push_arg); | 1618 values->Add(push_arg); |
| 1662 } | 1619 } |
| 1663 } | 1620 } |
| 1664 | 1621 |
| 1665 | 1622 |
| 1666 void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) { | 1623 void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) { |
| 1667 ValueGraphVisitor for_receiver(owner(), temp_index(), loop_depth()); | 1624 ValueGraphVisitor for_receiver(owner(), temp_index()); |
| 1668 node->receiver()->Visit(&for_receiver); | 1625 node->receiver()->Visit(&for_receiver); |
| 1669 Append(for_receiver); | 1626 Append(for_receiver); |
| 1670 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); | 1627 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); |
| 1671 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1628 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1672 new ZoneGrowableArray<PushArgumentInstr*>( | 1629 new ZoneGrowableArray<PushArgumentInstr*>( |
| 1673 node->arguments()->length() + 1); | 1630 node->arguments()->length() + 1); |
| 1674 arguments->Add(push_receiver); | 1631 arguments->Add(push_receiver); |
| 1675 | 1632 |
| 1676 BuildPushArguments(*node->arguments(), arguments); | 1633 BuildPushArguments(*node->arguments(), arguments); |
| 1677 InstanceCallInstr* call = new InstanceCallInstr( | 1634 InstanceCallInstr* call = new InstanceCallInstr( |
| 1678 node->token_pos(), | 1635 node->token_pos(), |
| 1679 node->function_name(), Token::kILLEGAL, arguments, | 1636 node->function_name(), Token::kILLEGAL, arguments, |
| 1680 node->arguments()->names(), 1); | 1637 node->arguments()->names(), 1); |
| 1681 ReturnDefinition(call); | 1638 ReturnDefinition(call); |
| 1682 } | 1639 } |
| 1683 | 1640 |
| 1684 | 1641 |
| 1685 // <Expression> ::= StaticCall { function: Function | 1642 // <Expression> ::= StaticCall { function: Function |
| 1686 // arguments: <ArgumentList> } | 1643 // arguments: <ArgumentList> } |
| 1687 void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) { | 1644 void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) { |
| 1688 if (node->function().name() == Symbols::Identical().raw()) { | 1645 if (node->function().name() == Symbols::Identical().raw()) { |
| 1689 // Attempt to replace top level defined 'identical' from the core | 1646 // Attempt to replace top level defined 'identical' from the core |
| 1690 // library with strict equal early on. | 1647 // library with strict equal early on. |
| 1691 // TODO(hausner): Evaluate if this can happen at AST building time. | 1648 // TODO(hausner): Evaluate if this can happen at AST building time. |
| 1692 const Class& cls = Class::Handle(node->function().Owner()); | 1649 const Class& cls = Class::Handle(node->function().Owner()); |
| 1693 if (cls.IsTopLevel()) { | 1650 if (cls.IsTopLevel()) { |
| 1694 const Library& core_lib = Library::Handle(Library::CoreLibrary()); | 1651 const Library& core_lib = Library::Handle(Library::CoreLibrary()); |
| 1695 if (cls.library() == core_lib.raw()) { | 1652 if (cls.library() == core_lib.raw()) { |
| 1696 ASSERT(node->arguments()->length() == 2); | 1653 ASSERT(node->arguments()->length() == 2); |
| 1697 ValueGraphVisitor for_left_value(owner(), temp_index(), loop_depth()); | 1654 ValueGraphVisitor for_left_value(owner(), temp_index()); |
| 1698 node->arguments()->NodeAt(0)->Visit(&for_left_value); | 1655 node->arguments()->NodeAt(0)->Visit(&for_left_value); |
| 1699 Append(for_left_value); | 1656 Append(for_left_value); |
| 1700 ValueGraphVisitor for_right_value(owner(), temp_index(), loop_depth()); | 1657 ValueGraphVisitor for_right_value(owner(), temp_index()); |
| 1701 node->arguments()->NodeAt(1)->Visit(&for_right_value); | 1658 node->arguments()->NodeAt(1)->Visit(&for_right_value); |
| 1702 Append(for_right_value); | 1659 Append(for_right_value); |
| 1703 StrictCompareInstr* comp = new StrictCompareInstr( | 1660 StrictCompareInstr* comp = new StrictCompareInstr( |
| 1704 Token::kEQ_STRICT, | 1661 Token::kEQ_STRICT, |
| 1705 for_left_value.value(), | 1662 for_left_value.value(), |
| 1706 for_right_value.value()); | 1663 for_right_value.value()); |
| 1707 ReturnDefinition(comp); | 1664 ReturnDefinition(comp); |
| 1708 return; | 1665 return; |
| 1709 } | 1666 } |
| 1710 } | 1667 } |
| 1711 } | 1668 } |
| 1712 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1669 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1713 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); | 1670 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); |
| 1714 BuildPushArguments(*node->arguments(), arguments); | 1671 BuildPushArguments(*node->arguments(), arguments); |
| 1715 StaticCallInstr* call = | 1672 StaticCallInstr* call = |
| 1716 new StaticCallInstr(node->token_pos(), | 1673 new StaticCallInstr(node->token_pos(), |
| 1717 node->function(), | 1674 node->function(), |
| 1718 node->arguments()->names(), | 1675 node->arguments()->names(), |
| 1719 arguments); | 1676 arguments); |
| 1720 ReturnDefinition(call); | 1677 ReturnDefinition(call); |
| 1721 } | 1678 } |
| 1722 | 1679 |
| 1723 | 1680 |
| 1724 ClosureCallInstr* EffectGraphVisitor::BuildClosureCall( | 1681 ClosureCallInstr* EffectGraphVisitor::BuildClosureCall( |
| 1725 ClosureCallNode* node) { | 1682 ClosureCallNode* node) { |
| 1726 ValueGraphVisitor for_closure(owner(), temp_index(), loop_depth()); | 1683 ValueGraphVisitor for_closure(owner(), temp_index()); |
| 1727 node->closure()->Visit(&for_closure); | 1684 node->closure()->Visit(&for_closure); |
| 1728 Append(for_closure); | 1685 Append(for_closure); |
| 1729 PushArgumentInstr* push_closure = PushArgument(for_closure.value()); | 1686 PushArgumentInstr* push_closure = PushArgument(for_closure.value()); |
| 1730 | 1687 |
| 1731 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1688 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1732 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); | 1689 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); |
| 1733 arguments->Add(push_closure); | 1690 arguments->Add(push_closure); |
| 1734 BuildPushArguments(*node->arguments(), arguments); | 1691 BuildPushArguments(*node->arguments(), arguments); |
| 1735 | 1692 |
| 1736 // Save context around the call. | 1693 // Save context around the call. |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1915 Function& outer_function = | 1872 Function& outer_function = |
| 1916 Function::Handle(owner()->parsed_function().function().raw()); | 1873 Function::Handle(owner()->parsed_function().function().raw()); |
| 1917 while (outer_function.IsLocalFunction()) { | 1874 while (outer_function.IsLocalFunction()) { |
| 1918 outer_function = outer_function.parent_function(); | 1875 outer_function = outer_function.parent_function(); |
| 1919 } | 1876 } |
| 1920 if (outer_function.IsFactory()) { | 1877 if (outer_function.IsFactory()) { |
| 1921 return NULL; | 1878 return NULL; |
| 1922 } | 1879 } |
| 1923 | 1880 |
| 1924 ASSERT(owner()->parsed_function().instantiator() != NULL); | 1881 ASSERT(owner()->parsed_function().instantiator() != NULL); |
| 1925 ValueGraphVisitor for_instantiator(owner(), temp_index(), loop_depth()); | 1882 ValueGraphVisitor for_instantiator(owner(), temp_index()); |
| 1926 owner()->parsed_function().instantiator()->Visit(&for_instantiator); | 1883 owner()->parsed_function().instantiator()->Visit(&for_instantiator); |
| 1927 Append(for_instantiator); | 1884 Append(for_instantiator); |
| 1928 return for_instantiator.value(); | 1885 return for_instantiator.value(); |
| 1929 } | 1886 } |
| 1930 | 1887 |
| 1931 | 1888 |
| 1932 // 'expression_temp_var' may not be used inside this method if 'instantiator' | 1889 // 'expression_temp_var' may not be used inside this method if 'instantiator' |
| 1933 // is not NULL. | 1890 // is not NULL. |
| 1934 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments( | 1891 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments( |
| 1935 intptr_t token_pos, Value* instantiator) { | 1892 intptr_t token_pos, Value* instantiator) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1950 } | 1907 } |
| 1951 Function& outer_function = | 1908 Function& outer_function = |
| 1952 Function::Handle(owner()->parsed_function().function().raw()); | 1909 Function::Handle(owner()->parsed_function().function().raw()); |
| 1953 while (outer_function.IsLocalFunction()) { | 1910 while (outer_function.IsLocalFunction()) { |
| 1954 outer_function = outer_function.parent_function(); | 1911 outer_function = outer_function.parent_function(); |
| 1955 } | 1912 } |
| 1956 if (outer_function.IsFactory()) { | 1913 if (outer_function.IsFactory()) { |
| 1957 // No instantiator for factories. | 1914 // No instantiator for factories. |
| 1958 ASSERT(instantiator == NULL); | 1915 ASSERT(instantiator == NULL); |
| 1959 ASSERT(owner()->parsed_function().instantiator() != NULL); | 1916 ASSERT(owner()->parsed_function().instantiator() != NULL); |
| 1960 ValueGraphVisitor for_instantiator(owner(), temp_index(), loop_depth()); | 1917 ValueGraphVisitor for_instantiator(owner(), temp_index()); |
| 1961 owner()->parsed_function().instantiator()->Visit(&for_instantiator); | 1918 owner()->parsed_function().instantiator()->Visit(&for_instantiator); |
| 1962 Append(for_instantiator); | 1919 Append(for_instantiator); |
| 1963 return for_instantiator.value(); | 1920 return for_instantiator.value(); |
| 1964 } | 1921 } |
| 1965 if (instantiator == NULL) { | 1922 if (instantiator == NULL) { |
| 1966 instantiator = BuildInstantiator(); | 1923 instantiator = BuildInstantiator(); |
| 1967 } | 1924 } |
| 1968 // The instantiator is the receiver of the caller, which is not a factory. | 1925 // The instantiator is the receiver of the caller, which is not a factory. |
| 1969 // The receiver cannot be null; extract its AbstractTypeArguments object. | 1926 // The receiver cannot be null; extract its AbstractTypeArguments object. |
| 1970 // Note that in the factory case, the instantiator is the first parameter | 1927 // Note that in the factory case, the instantiator is the first parameter |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2098 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value); | 2055 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value); |
| 2099 BuildConstructorCall(node, push_allocated_value); | 2056 BuildConstructorCall(node, push_allocated_value); |
| 2100 Definition* load_allocated = BuildLoadLocal( | 2057 Definition* load_allocated = BuildLoadLocal( |
| 2101 node->allocated_object_var()); | 2058 node->allocated_object_var()); |
| 2102 allocated_value = Bind(load_allocated); | 2059 allocated_value = Bind(load_allocated); |
| 2103 ReturnValue(allocated_value); | 2060 ReturnValue(allocated_value); |
| 2104 } | 2061 } |
| 2105 | 2062 |
| 2106 | 2063 |
| 2107 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) { | 2064 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) { |
| 2108 ValueGraphVisitor for_receiver(owner(), temp_index(), loop_depth()); | 2065 ValueGraphVisitor for_receiver(owner(), temp_index()); |
| 2109 node->receiver()->Visit(&for_receiver); | 2066 node->receiver()->Visit(&for_receiver); |
| 2110 Append(for_receiver); | 2067 Append(for_receiver); |
| 2111 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); | 2068 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); |
| 2112 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2069 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 2113 new ZoneGrowableArray<PushArgumentInstr*>(1); | 2070 new ZoneGrowableArray<PushArgumentInstr*>(1); |
| 2114 arguments->Add(push_receiver); | 2071 arguments->Add(push_receiver); |
| 2115 const String& name = | 2072 const String& name = |
| 2116 String::ZoneHandle(Field::GetterSymbol(node->field_name())); | 2073 String::ZoneHandle(Field::GetterSymbol(node->field_name())); |
| 2117 InstanceCallInstr* call = new InstanceCallInstr( | 2074 InstanceCallInstr* call = new InstanceCallInstr( |
| 2118 node->token_pos(), name, Token::kGET, | 2075 node->token_pos(), name, Token::kGET, |
| 2119 arguments, Array::ZoneHandle(), 1); | 2076 arguments, Array::ZoneHandle(), 1); |
| 2120 ReturnDefinition(call); | 2077 ReturnDefinition(call); |
| 2121 } | 2078 } |
| 2122 | 2079 |
| 2123 | 2080 |
| 2124 void EffectGraphVisitor::BuildInstanceSetterArguments( | 2081 void EffectGraphVisitor::BuildInstanceSetterArguments( |
| 2125 InstanceSetterNode* node, | 2082 InstanceSetterNode* node, |
| 2126 ZoneGrowableArray<PushArgumentInstr*>* arguments, | 2083 ZoneGrowableArray<PushArgumentInstr*>* arguments, |
| 2127 bool result_is_needed) { | 2084 bool result_is_needed) { |
| 2128 ValueGraphVisitor for_receiver(owner(), temp_index(), loop_depth()); | 2085 ValueGraphVisitor for_receiver(owner(), temp_index()); |
| 2129 node->receiver()->Visit(&for_receiver); | 2086 node->receiver()->Visit(&for_receiver); |
| 2130 Append(for_receiver); | 2087 Append(for_receiver); |
| 2131 arguments->Add(PushArgument(for_receiver.value())); | 2088 arguments->Add(PushArgument(for_receiver.value())); |
| 2132 | 2089 |
| 2133 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); | 2090 ValueGraphVisitor for_value(owner(), temp_index()); |
| 2134 node->value()->Visit(&for_value); | 2091 node->value()->Visit(&for_value); |
| 2135 Append(for_value); | 2092 Append(for_value); |
| 2136 | 2093 |
| 2137 Value* value = NULL; | 2094 Value* value = NULL; |
| 2138 if (result_is_needed) { | 2095 if (result_is_needed) { |
| 2139 value = Bind(BuildStoreExprTemp(for_value.value())); | 2096 value = Bind(BuildStoreExprTemp(for_value.value())); |
| 2140 } else { | 2097 } else { |
| 2141 value = for_value.value(); | 2098 value = for_value.value(); |
| 2142 } | 2099 } |
| 2143 arguments->Add(PushArgument(value)); | 2100 arguments->Add(PushArgument(value)); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2190 // Resolve and call noSuchMethod. | 2147 // Resolve and call noSuchMethod. |
| 2191 ArgumentListNode* arguments = new ArgumentListNode(node->token_pos()); | 2148 ArgumentListNode* arguments = new ArgumentListNode(node->token_pos()); |
| 2192 arguments->Add(node->receiver()); | 2149 arguments->Add(node->receiver()); |
| 2193 StaticCallInstr* call = BuildStaticNoSuchMethodCall(node->cls(), | 2150 StaticCallInstr* call = BuildStaticNoSuchMethodCall(node->cls(), |
| 2194 node->receiver(), | 2151 node->receiver(), |
| 2195 getter_name, | 2152 getter_name, |
| 2196 arguments); | 2153 arguments); |
| 2197 ReturnDefinition(call); | 2154 ReturnDefinition(call); |
| 2198 return; | 2155 return; |
| 2199 } else { | 2156 } else { |
| 2200 ValueGraphVisitor receiver_value(owner(), temp_index(), loop_depth()); | 2157 ValueGraphVisitor receiver_value(owner(), temp_index()); |
| 2201 node->receiver()->Visit(&receiver_value); | 2158 node->receiver()->Visit(&receiver_value); |
| 2202 Append(receiver_value); | 2159 Append(receiver_value); |
| 2203 arguments->Add(PushArgument(receiver_value.value())); | 2160 arguments->Add(PushArgument(receiver_value.value())); |
| 2204 } | 2161 } |
| 2205 } else { | 2162 } else { |
| 2206 getter_function = node->cls().LookupStaticFunction(getter_name); | 2163 getter_function = node->cls().LookupStaticFunction(getter_name); |
| 2207 if (getter_function.IsNull()) { | 2164 if (getter_function.IsNull()) { |
| 2208 // When the parser encounters a reference to a static field materialized | 2165 // When the parser encounters a reference to a static field materialized |
| 2209 // only by a static setter, but no corresponding static getter, it creates | 2166 // only by a static setter, but no corresponding static getter, it creates |
| 2210 // a StaticGetterNode ast node referring to the non-existing static getter | 2167 // a StaticGetterNode ast node referring to the non-existing static getter |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2264 arguments); | 2221 arguments); |
| 2265 } else { | 2222 } else { |
| 2266 // Throw a NoSuchMethodError. | 2223 // Throw a NoSuchMethodError. |
| 2267 call = BuildThrowNoSuchMethodError(node->token_pos(), | 2224 call = BuildThrowNoSuchMethodError(node->token_pos(), |
| 2268 node->cls(), | 2225 node->cls(), |
| 2269 setter_name); | 2226 setter_name); |
| 2270 } | 2227 } |
| 2271 } else { | 2228 } else { |
| 2272 if (is_super_setter) { | 2229 if (is_super_setter) { |
| 2273 // Add receiver of instance getter. | 2230 // Add receiver of instance getter. |
| 2274 ValueGraphVisitor for_receiver(owner(), temp_index(), loop_depth()); | 2231 ValueGraphVisitor for_receiver(owner(), temp_index()); |
| 2275 node->receiver()->Visit(&for_receiver); | 2232 node->receiver()->Visit(&for_receiver); |
| 2276 Append(for_receiver); | 2233 Append(for_receiver); |
| 2277 arguments->Add(PushArgument(for_receiver.value())); | 2234 arguments->Add(PushArgument(for_receiver.value())); |
| 2278 } | 2235 } |
| 2279 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); | 2236 ValueGraphVisitor for_value(owner(), temp_index()); |
| 2280 node->value()->Visit(&for_value); | 2237 node->value()->Visit(&for_value); |
| 2281 Append(for_value); | 2238 Append(for_value); |
| 2282 Value* value = NULL; | 2239 Value* value = NULL; |
| 2283 if (result_is_needed) { | 2240 if (result_is_needed) { |
| 2284 value = Bind(BuildStoreExprTemp(for_value.value())); | 2241 value = Bind(BuildStoreExprTemp(for_value.value())); |
| 2285 } else { | 2242 } else { |
| 2286 value = for_value.value(); | 2243 value = for_value.value(); |
| 2287 } | 2244 } |
| 2288 arguments->Add(PushArgument(value)); | 2245 arguments->Add(PushArgument(value)); |
| 2289 | 2246 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 2320 | 2277 |
| 2321 void EffectGraphVisitor::VisitPrimaryNode(PrimaryNode* node) { | 2278 void EffectGraphVisitor::VisitPrimaryNode(PrimaryNode* node) { |
| 2322 // PrimaryNodes are temporary during parsing. | 2279 // PrimaryNodes are temporary during parsing. |
| 2323 UNREACHABLE(); | 2280 UNREACHABLE(); |
| 2324 } | 2281 } |
| 2325 | 2282 |
| 2326 | 2283 |
| 2327 // <Expression> ::= LoadLocal { local: LocalVariable } | 2284 // <Expression> ::= LoadLocal { local: LocalVariable } |
| 2328 void EffectGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) { | 2285 void EffectGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) { |
| 2329 if (node->HasPseudo()) { | 2286 if (node->HasPseudo()) { |
| 2330 EffectGraphVisitor for_pseudo(owner(), temp_index(), loop_depth()); | 2287 EffectGraphVisitor for_pseudo(owner(), temp_index()); |
| 2331 node->pseudo()->Visit(&for_pseudo); | 2288 node->pseudo()->Visit(&for_pseudo); |
| 2332 Append(for_pseudo); | 2289 Append(for_pseudo); |
| 2333 } | 2290 } |
| 2334 } | 2291 } |
| 2335 | 2292 |
| 2336 | 2293 |
| 2337 void ValueGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) { | 2294 void ValueGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) { |
| 2338 EffectGraphVisitor::VisitLoadLocalNode(node); | 2295 EffectGraphVisitor::VisitLoadLocalNode(node); |
| 2339 Definition* load = BuildLoadLocal(node->local()); | 2296 Definition* load = BuildLoadLocal(node->local()); |
| 2340 ReturnDefinition(load); | 2297 ReturnDefinition(load); |
| 2341 } | 2298 } |
| 2342 | 2299 |
| 2343 | 2300 |
| 2344 // <Expression> ::= StoreLocal { local: LocalVariable | 2301 // <Expression> ::= StoreLocal { local: LocalVariable |
| 2345 // value: <Expression> } | 2302 // value: <Expression> } |
| 2346 void EffectGraphVisitor::HandleStoreLocal(StoreLocalNode* node, | 2303 void EffectGraphVisitor::HandleStoreLocal(StoreLocalNode* node, |
| 2347 bool result_is_needed) { | 2304 bool result_is_needed) { |
| 2348 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); | 2305 ValueGraphVisitor for_value(owner(), temp_index()); |
| 2349 node->value()->Visit(&for_value); | 2306 node->value()->Visit(&for_value); |
| 2350 Append(for_value); | 2307 Append(for_value); |
| 2351 Value* store_value = for_value.value(); | 2308 Value* store_value = for_value.value(); |
| 2352 if (FLAG_enable_type_checks) { | 2309 if (FLAG_enable_type_checks) { |
| 2353 store_value = BuildAssignableValue(node->value()->token_pos(), | 2310 store_value = BuildAssignableValue(node->value()->token_pos(), |
| 2354 store_value, | 2311 store_value, |
| 2355 node->local().type(), | 2312 node->local().type(), |
| 2356 node->local().name()); | 2313 node->local().name()); |
| 2357 } | 2314 } |
| 2358 Definition* store = BuildStoreLocal(node->local(), | 2315 Definition* store = BuildStoreLocal(node->local(), |
| 2359 store_value, | 2316 store_value, |
| 2360 result_is_needed); | 2317 result_is_needed); |
| 2361 ReturnDefinition(store); | 2318 ReturnDefinition(store); |
| 2362 } | 2319 } |
| 2363 | 2320 |
| 2364 | 2321 |
| 2365 void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) { | 2322 void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) { |
| 2366 HandleStoreLocal(node, kResultNotNeeded); | 2323 HandleStoreLocal(node, kResultNotNeeded); |
| 2367 } | 2324 } |
| 2368 | 2325 |
| 2369 | 2326 |
| 2370 void ValueGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) { | 2327 void ValueGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) { |
| 2371 HandleStoreLocal(node, kResultNeeded); | 2328 HandleStoreLocal(node, kResultNeeded); |
| 2372 } | 2329 } |
| 2373 | 2330 |
| 2374 | 2331 |
| 2375 void EffectGraphVisitor::VisitLoadInstanceFieldNode( | 2332 void EffectGraphVisitor::VisitLoadInstanceFieldNode( |
| 2376 LoadInstanceFieldNode* node) { | 2333 LoadInstanceFieldNode* node) { |
| 2377 ValueGraphVisitor for_instance(owner(), temp_index(), loop_depth()); | 2334 ValueGraphVisitor for_instance(owner(), temp_index()); |
| 2378 node->instance()->Visit(&for_instance); | 2335 node->instance()->Visit(&for_instance); |
| 2379 Append(for_instance); | 2336 Append(for_instance); |
| 2380 LoadFieldInstr* load = new LoadFieldInstr( | 2337 LoadFieldInstr* load = new LoadFieldInstr( |
| 2381 for_instance.value(), | 2338 for_instance.value(), |
| 2382 node->field().Offset(), | 2339 node->field().Offset(), |
| 2383 AbstractType::ZoneHandle(node->field().type())); | 2340 AbstractType::ZoneHandle(node->field().type())); |
| 2384 ReturnDefinition(load); | 2341 ReturnDefinition(load); |
| 2385 } | 2342 } |
| 2386 | 2343 |
| 2387 | 2344 |
| 2388 void EffectGraphVisitor::VisitStoreInstanceFieldNode( | 2345 void EffectGraphVisitor::VisitStoreInstanceFieldNode( |
| 2389 StoreInstanceFieldNode* node) { | 2346 StoreInstanceFieldNode* node) { |
| 2390 ValueGraphVisitor for_instance(owner(), temp_index(), loop_depth()); | 2347 ValueGraphVisitor for_instance(owner(), temp_index()); |
| 2391 node->instance()->Visit(&for_instance); | 2348 node->instance()->Visit(&for_instance); |
| 2392 Append(for_instance); | 2349 Append(for_instance); |
| 2393 ValueGraphVisitor for_value(owner(), for_instance.temp_index(), loop_depth()); | 2350 ValueGraphVisitor for_value(owner(), for_instance.temp_index()); |
| 2394 node->value()->Visit(&for_value); | 2351 node->value()->Visit(&for_value); |
| 2395 Append(for_value); | 2352 Append(for_value); |
| 2396 Value* store_value = for_value.value(); | 2353 Value* store_value = for_value.value(); |
| 2397 if (FLAG_enable_type_checks) { | 2354 if (FLAG_enable_type_checks) { |
| 2398 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); | 2355 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); |
| 2399 const String& dst_name = String::ZoneHandle(node->field().name()); | 2356 const String& dst_name = String::ZoneHandle(node->field().name()); |
| 2400 store_value = BuildAssignableValue(node->value()->token_pos(), | 2357 store_value = BuildAssignableValue(node->value()->token_pos(), |
| 2401 store_value, | 2358 store_value, |
| 2402 type, | 2359 type, |
| 2403 dst_name); | 2360 dst_name); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2417 | 2374 |
| 2418 | 2375 |
| 2419 void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) { | 2376 void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) { |
| 2420 LoadStaticFieldInstr* load = new LoadStaticFieldInstr(node->field()); | 2377 LoadStaticFieldInstr* load = new LoadStaticFieldInstr(node->field()); |
| 2421 ReturnDefinition(load); | 2378 ReturnDefinition(load); |
| 2422 } | 2379 } |
| 2423 | 2380 |
| 2424 | 2381 |
| 2425 Definition* EffectGraphVisitor::BuildStoreStaticField( | 2382 Definition* EffectGraphVisitor::BuildStoreStaticField( |
| 2426 StoreStaticFieldNode* node, bool result_is_needed) { | 2383 StoreStaticFieldNode* node, bool result_is_needed) { |
| 2427 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); | 2384 ValueGraphVisitor for_value(owner(), temp_index()); |
| 2428 node->value()->Visit(&for_value); | 2385 node->value()->Visit(&for_value); |
| 2429 Append(for_value); | 2386 Append(for_value); |
| 2430 Value* store_value = NULL; | 2387 Value* store_value = NULL; |
| 2431 if (result_is_needed) { | 2388 if (result_is_needed) { |
| 2432 store_value = Bind(BuildStoreExprTemp(for_value.value())); | 2389 store_value = Bind(BuildStoreExprTemp(for_value.value())); |
| 2433 } else { | 2390 } else { |
| 2434 store_value = for_value.value(); | 2391 store_value = for_value.value(); |
| 2435 } | 2392 } |
| 2436 if (FLAG_enable_type_checks) { | 2393 if (FLAG_enable_type_checks) { |
| 2437 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); | 2394 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2480 BuildStaticNoSuchMethodCall(node->super_class(), | 2437 BuildStaticNoSuchMethodCall(node->super_class(), |
| 2481 node->array(), | 2438 node->array(), |
| 2482 Symbols::IndexToken(), | 2439 Symbols::IndexToken(), |
| 2483 arguments); | 2440 arguments); |
| 2484 ReturnDefinition(call); | 2441 ReturnDefinition(call); |
| 2485 return; | 2442 return; |
| 2486 } | 2443 } |
| 2487 } | 2444 } |
| 2488 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2445 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 2489 new ZoneGrowableArray<PushArgumentInstr*>(2); | 2446 new ZoneGrowableArray<PushArgumentInstr*>(2); |
| 2490 ValueGraphVisitor for_array(owner(), temp_index(), loop_depth()); | 2447 ValueGraphVisitor for_array(owner(), temp_index()); |
| 2491 node->array()->Visit(&for_array); | 2448 node->array()->Visit(&for_array); |
| 2492 Append(for_array); | 2449 Append(for_array); |
| 2493 arguments->Add(PushArgument(for_array.value())); | 2450 arguments->Add(PushArgument(for_array.value())); |
| 2494 | 2451 |
| 2495 ValueGraphVisitor for_index(owner(), temp_index(), loop_depth()); | 2452 ValueGraphVisitor for_index(owner(), temp_index()); |
| 2496 node->index_expr()->Visit(&for_index); | 2453 node->index_expr()->Visit(&for_index); |
| 2497 Append(for_index); | 2454 Append(for_index); |
| 2498 arguments->Add(PushArgument(for_index.value())); | 2455 arguments->Add(PushArgument(for_index.value())); |
| 2499 | 2456 |
| 2500 if (super_function != NULL) { | 2457 if (super_function != NULL) { |
| 2501 // Generate static call to super operator. | 2458 // Generate static call to super operator. |
| 2502 StaticCallInstr* load = new StaticCallInstr(node->token_pos(), | 2459 StaticCallInstr* load = new StaticCallInstr(node->token_pos(), |
| 2503 *super_function, | 2460 *super_function, |
| 2504 Array::ZoneHandle(), | 2461 Array::ZoneHandle(), |
| 2505 arguments); | 2462 arguments); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 2526 // Resolve the store indexed operator in the super class. | 2483 // Resolve the store indexed operator in the super class. |
| 2527 super_function = &Function::ZoneHandle( | 2484 super_function = &Function::ZoneHandle( |
| 2528 Resolver::ResolveDynamicAnyArgs(node->super_class(), | 2485 Resolver::ResolveDynamicAnyArgs(node->super_class(), |
| 2529 Symbols::AssignIndexToken())); | 2486 Symbols::AssignIndexToken())); |
| 2530 if (super_function->IsNull()) { | 2487 if (super_function->IsNull()) { |
| 2531 // Could not resolve super operator. Generate call noSuchMethod() of the | 2488 // Could not resolve super operator. Generate call noSuchMethod() of the |
| 2532 // super class instead. | 2489 // super class instead. |
| 2533 if (result_is_needed) { | 2490 if (result_is_needed) { |
| 2534 // Even though noSuchMethod most likely does not return, | 2491 // Even though noSuchMethod most likely does not return, |
| 2535 // we save the stored value if the result is needed. | 2492 // we save the stored value if the result is needed. |
| 2536 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); | 2493 ValueGraphVisitor for_value(owner(), temp_index()); |
| 2537 node->value()->Visit(&for_value); | 2494 node->value()->Visit(&for_value); |
| 2538 Append(for_value); | 2495 Append(for_value); |
| 2539 Bind(BuildStoreExprTemp(for_value.value())); | 2496 Bind(BuildStoreExprTemp(for_value.value())); |
| 2540 } | 2497 } |
| 2541 ArgumentListNode* arguments = new ArgumentListNode(node->token_pos()); | 2498 ArgumentListNode* arguments = new ArgumentListNode(node->token_pos()); |
| 2542 arguments->Add(node->array()); | 2499 arguments->Add(node->array()); |
| 2543 arguments->Add(node->index_expr()); | 2500 arguments->Add(node->index_expr()); |
| 2544 arguments->Add(node->value()); | 2501 arguments->Add(node->value()); |
| 2545 StaticCallInstr* call = | 2502 StaticCallInstr* call = |
| 2546 BuildStaticNoSuchMethodCall(node->super_class(), | 2503 BuildStaticNoSuchMethodCall(node->super_class(), |
| 2547 node->array(), | 2504 node->array(), |
| 2548 Symbols::AssignIndexToken(), | 2505 Symbols::AssignIndexToken(), |
| 2549 arguments); | 2506 arguments); |
| 2550 if (result_is_needed) { | 2507 if (result_is_needed) { |
| 2551 Do(call); | 2508 Do(call); |
| 2552 return BuildLoadExprTemp(); | 2509 return BuildLoadExprTemp(); |
| 2553 } else { | 2510 } else { |
| 2554 return call; | 2511 return call; |
| 2555 } | 2512 } |
| 2556 } | 2513 } |
| 2557 } | 2514 } |
| 2558 | 2515 |
| 2559 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2516 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 2560 new ZoneGrowableArray<PushArgumentInstr*>(3); | 2517 new ZoneGrowableArray<PushArgumentInstr*>(3); |
| 2561 ValueGraphVisitor for_array(owner(), temp_index(), loop_depth()); | 2518 ValueGraphVisitor for_array(owner(), temp_index()); |
| 2562 node->array()->Visit(&for_array); | 2519 node->array()->Visit(&for_array); |
| 2563 Append(for_array); | 2520 Append(for_array); |
| 2564 arguments->Add(PushArgument(for_array.value())); | 2521 arguments->Add(PushArgument(for_array.value())); |
| 2565 | 2522 |
| 2566 ValueGraphVisitor for_index(owner(), temp_index(), loop_depth()); | 2523 ValueGraphVisitor for_index(owner(), temp_index()); |
| 2567 node->index_expr()->Visit(&for_index); | 2524 node->index_expr()->Visit(&for_index); |
| 2568 Append(for_index); | 2525 Append(for_index); |
| 2569 arguments->Add(PushArgument(for_index.value())); | 2526 arguments->Add(PushArgument(for_index.value())); |
| 2570 | 2527 |
| 2571 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); | 2528 ValueGraphVisitor for_value(owner(), temp_index()); |
| 2572 node->value()->Visit(&for_value); | 2529 node->value()->Visit(&for_value); |
| 2573 Append(for_value); | 2530 Append(for_value); |
| 2574 Value* value = NULL; | 2531 Value* value = NULL; |
| 2575 if (result_is_needed) { | 2532 if (result_is_needed) { |
| 2576 value = Bind(BuildStoreExprTemp(for_value.value())); | 2533 value = Bind(BuildStoreExprTemp(for_value.value())); |
| 2577 } else { | 2534 } else { |
| 2578 value = for_value.value(); | 2535 value = for_value.value(); |
| 2579 } | 2536 } |
| 2580 arguments->Add(PushArgument(value)); | 2537 arguments->Add(PushArgument(value)); |
| 2581 | 2538 |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2747 // variable so that ssa renaming detects the dependency and makes use | 2704 // variable so that ssa renaming detects the dependency and makes use |
| 2748 // of the checked type in type propagation. | 2705 // of the checked type in type propagation. |
| 2749 Do(BuildStoreLocal(parameter, parameter_value, kResultNotNeeded)); | 2706 Do(BuildStoreLocal(parameter, parameter_value, kResultNotNeeded)); |
| 2750 } | 2707 } |
| 2751 pos++; | 2708 pos++; |
| 2752 } | 2709 } |
| 2753 } | 2710 } |
| 2754 | 2711 |
| 2755 intptr_t i = 0; | 2712 intptr_t i = 0; |
| 2756 while (is_open() && (i < node->length())) { | 2713 while (is_open() && (i < node->length())) { |
| 2757 EffectGraphVisitor for_effect(owner(), temp_index(), loop_depth()); | 2714 EffectGraphVisitor for_effect(owner(), temp_index()); |
| 2758 node->NodeAt(i++)->Visit(&for_effect); | 2715 node->NodeAt(i++)->Visit(&for_effect); |
| 2759 Append(for_effect); | 2716 Append(for_effect); |
| 2760 if (!is_open()) { | 2717 if (!is_open()) { |
| 2761 // E.g., because of a JumpNode. | 2718 // E.g., because of a JumpNode. |
| 2762 break; | 2719 break; |
| 2763 } | 2720 } |
| 2764 } | 2721 } |
| 2765 | 2722 |
| 2766 if (is_open()) { | 2723 if (is_open()) { |
| 2767 if (MustSaveRestoreContext(node)) { | 2724 if (MustSaveRestoreContext(node)) { |
| 2768 ASSERT(num_context_variables > 0); | 2725 ASSERT(num_context_variables > 0); |
| 2769 BuildLoadContext(*owner()->parsed_function().saved_context_var()); | 2726 BuildLoadContext(*owner()->parsed_function().saved_context_var()); |
| 2770 } else if (num_context_variables > 0) { | 2727 } else if (num_context_variables > 0) { |
| 2771 UnchainContext(); | 2728 UnchainContext(); |
| 2772 } | 2729 } |
| 2773 } | 2730 } |
| 2774 | 2731 |
| 2775 // No continue on sequence allowed. | 2732 // No continue on sequence allowed. |
| 2776 ASSERT((node->label() == NULL) || | 2733 ASSERT((node->label() == NULL) || |
| 2777 (node->label()->join_for_continue() == NULL)); | 2734 (node->label()->join_for_continue() == NULL)); |
| 2778 // If this node sequence is labeled, a break out of the sequence will have | 2735 // If this node sequence is labeled, a break out of the sequence will have |
| 2779 // taken care of unchaining the context. | 2736 // taken care of unchaining the context. |
| 2780 if ((node->label() != NULL) && | 2737 if ((node->label() != NULL) && |
| 2781 (node->label()->join_for_break() != NULL)) { | 2738 (node->label()->join_for_break() != NULL)) { |
| 2782 node->label()->join_for_break()->set_loop_depth(loop_depth()); | |
| 2783 if (is_open()) Goto(node->label()->join_for_break()); | 2739 if (is_open()) Goto(node->label()->join_for_break()); |
| 2784 exit_ = node->label()->join_for_break(); | 2740 exit_ = node->label()->join_for_break(); |
| 2785 } | 2741 } |
| 2786 | 2742 |
| 2787 // The outermost function sequence cannot contain a label. | 2743 // The outermost function sequence cannot contain a label. |
| 2788 ASSERT((node->label() == NULL) || | 2744 ASSERT((node->label() == NULL) || |
| 2789 (node != owner()->parsed_function().node_sequence())); | 2745 (node != owner()->parsed_function().node_sequence())); |
| 2790 owner()->set_context_level(previous_context_level); | 2746 owner()->set_context_level(previous_context_level); |
| 2791 } | 2747 } |
| 2792 | 2748 |
| 2793 | 2749 |
| 2794 void EffectGraphVisitor::VisitCatchClauseNode(CatchClauseNode* node) { | 2750 void EffectGraphVisitor::VisitCatchClauseNode(CatchClauseNode* node) { |
| 2795 InlineBailout("EffectGraphVisitor::VisitCatchClauseNode (exception)"); | 2751 InlineBailout("EffectGraphVisitor::VisitCatchClauseNode (exception)"); |
| 2796 // NOTE: The implicit variables ':saved_context', ':exception_var' | 2752 // NOTE: The implicit variables ':saved_context', ':exception_var' |
| 2797 // and ':stacktrace_var' can never be captured variables. | 2753 // and ':stacktrace_var' can never be captured variables. |
| 2798 // Restores CTX from local variable ':saved_context'. | 2754 // Restores CTX from local variable ':saved_context'. |
| 2799 AddInstruction( | 2755 AddInstruction( |
| 2800 new CatchEntryInstr(node->exception_var(), node->stacktrace_var())); | 2756 new CatchEntryInstr(node->exception_var(), node->stacktrace_var())); |
| 2801 BuildLoadContext(node->context_var()); | 2757 BuildLoadContext(node->context_var()); |
| 2802 | 2758 |
| 2803 EffectGraphVisitor for_catch(owner(), temp_index(), loop_depth()); | 2759 EffectGraphVisitor for_catch(owner(), temp_index()); |
| 2804 node->VisitChildren(&for_catch); | 2760 node->VisitChildren(&for_catch); |
| 2805 Append(for_catch); | 2761 Append(for_catch); |
| 2806 } | 2762 } |
| 2807 | 2763 |
| 2808 | 2764 |
| 2809 void EffectGraphVisitor::VisitTryCatchNode(TryCatchNode* node) { | 2765 void EffectGraphVisitor::VisitTryCatchNode(TryCatchNode* node) { |
| 2810 InlineBailout("EffectGraphVisitor::VisitTryCatchNode (exception)"); | 2766 InlineBailout("EffectGraphVisitor::VisitTryCatchNode (exception)"); |
| 2811 intptr_t old_try_index = owner()->try_index(); | 2767 intptr_t old_try_index = owner()->try_index(); |
| 2812 intptr_t try_index = owner()->AllocateTryIndex(); | 2768 intptr_t try_index = owner()->AllocateTryIndex(); |
| 2813 owner()->set_try_index(try_index); | 2769 owner()->set_try_index(try_index); |
| 2814 | 2770 |
| 2815 // Preserve CTX into local variable '%saved_context'. | 2771 // Preserve CTX into local variable '%saved_context'. |
| 2816 BuildStoreContext(node->context_var()); | 2772 BuildStoreContext(node->context_var()); |
| 2817 | 2773 |
| 2818 EffectGraphVisitor for_try_block(owner(), temp_index(), loop_depth()); | 2774 EffectGraphVisitor for_try_block(owner(), temp_index()); |
| 2819 node->try_block()->Visit(&for_try_block); | 2775 node->try_block()->Visit(&for_try_block); |
| 2820 | 2776 |
| 2821 if (for_try_block.is_open()) { | 2777 if (for_try_block.is_open()) { |
| 2822 JoinEntryInstr* after_try = | 2778 JoinEntryInstr* after_try = |
| 2823 new JoinEntryInstr(owner()->AllocateBlockId(), | 2779 new JoinEntryInstr(owner()->AllocateBlockId(), old_try_index); |
| 2824 old_try_index, | |
| 2825 loop_depth()); | |
| 2826 for_try_block.Goto(after_try); | 2780 for_try_block.Goto(after_try); |
| 2827 for_try_block.exit_ = after_try; | 2781 for_try_block.exit_ = after_try; |
| 2828 } | 2782 } |
| 2829 | 2783 |
| 2830 JoinEntryInstr* try_entry = | 2784 JoinEntryInstr* try_entry = |
| 2831 new JoinEntryInstr(owner()->AllocateBlockId(), try_index, loop_depth()); | 2785 new JoinEntryInstr(owner()->AllocateBlockId(), try_index); |
| 2832 | 2786 |
| 2833 Goto(try_entry); | 2787 Goto(try_entry); |
| 2834 AppendFragment(try_entry, for_try_block); | 2788 AppendFragment(try_entry, for_try_block); |
| 2835 exit_ = for_try_block.exit_; | 2789 exit_ = for_try_block.exit_; |
| 2836 | 2790 |
| 2837 // We are done generating code for the try block. | 2791 // We are done generating code for the try block. |
| 2838 owner()->set_try_index(old_try_index); | 2792 owner()->set_try_index(old_try_index); |
| 2839 | 2793 |
| 2840 CatchClauseNode* catch_block = node->catch_block(); | 2794 CatchClauseNode* catch_block = node->catch_block(); |
| 2841 if (catch_block != NULL) { | 2795 if (catch_block != NULL) { |
| 2842 // Set the corresponding try index for this catch block so | 2796 // Set the corresponding try index for this catch block so |
| 2843 // that we can set the appropriate handler pc when we generate | 2797 // that we can set the appropriate handler pc when we generate |
| 2844 // code for this catch block. | 2798 // code for this catch block. |
| 2845 catch_block->set_try_index(try_index); | 2799 catch_block->set_try_index(try_index); |
| 2846 EffectGraphVisitor for_catch_block(owner(), temp_index(), loop_depth()); | 2800 EffectGraphVisitor for_catch_block(owner(), temp_index()); |
| 2847 catch_block->Visit(&for_catch_block); | 2801 catch_block->Visit(&for_catch_block); |
| 2848 TargetEntryInstr* catch_entry = | 2802 TargetEntryInstr* catch_entry = |
| 2849 new TargetEntryInstr(owner()->AllocateBlockId(), | 2803 new TargetEntryInstr(owner()->AllocateBlockId(), old_try_index); |
| 2850 old_try_index, | |
| 2851 loop_depth()); | |
| 2852 catch_entry->set_catch_try_index(try_index); | 2804 catch_entry->set_catch_try_index(try_index); |
| 2853 catch_entry->set_catch_handler_types(catch_block->handler_types()); | 2805 catch_entry->set_catch_handler_types(catch_block->handler_types()); |
| 2854 owner()->AddCatchEntry(catch_entry); | 2806 owner()->AddCatchEntry(catch_entry); |
| 2855 ASSERT(!for_catch_block.is_open()); | 2807 ASSERT(!for_catch_block.is_open()); |
| 2856 AppendFragment(catch_entry, for_catch_block); | 2808 AppendFragment(catch_entry, for_catch_block); |
| 2857 if (node->end_catch_label() != NULL) { | 2809 if (node->end_catch_label() != NULL) { |
| 2858 JoinEntryInstr* join = node->end_catch_label()->join_for_continue(); | 2810 JoinEntryInstr* join = node->end_catch_label()->join_for_continue(); |
| 2859 if (join != NULL) { | 2811 if (join != NULL) { |
| 2860 join->set_loop_depth(loop_depth()); | |
| 2861 if (is_open()) Goto(join); | 2812 if (is_open()) Goto(join); |
| 2862 exit_ = join; | 2813 exit_ = join; |
| 2863 } | 2814 } |
| 2864 } | 2815 } |
| 2865 } | 2816 } |
| 2866 | 2817 |
| 2867 // Generate code for the finally block if one exists. | 2818 // Generate code for the finally block if one exists. |
| 2868 if ((node->finally_block() != NULL) && is_open()) { | 2819 if ((node->finally_block() != NULL) && is_open()) { |
| 2869 EffectGraphVisitor for_finally_block(owner(), temp_index(), loop_depth()); | 2820 EffectGraphVisitor for_finally_block(owner(), temp_index()); |
| 2870 node->finally_block()->Visit(&for_finally_block); | 2821 node->finally_block()->Visit(&for_finally_block); |
| 2871 Append(for_finally_block); | 2822 Append(for_finally_block); |
| 2872 } | 2823 } |
| 2873 } | 2824 } |
| 2874 | 2825 |
| 2875 | 2826 |
| 2876 // Looks up dynamic method noSuchMethod in target_class | 2827 // Looks up dynamic method noSuchMethod in target_class |
| 2877 // (including its super class chain) and builds a static call to it. | 2828 // (including its super class chain) and builds a static call to it. |
| 2878 StaticCallInstr* EffectGraphVisitor::BuildStaticNoSuchMethodCall( | 2829 StaticCallInstr* EffectGraphVisitor::BuildStaticNoSuchMethodCall( |
| 2879 const Class& target_class, | 2830 const Class& target_class, |
| 2880 AstNode* receiver, | 2831 AstNode* receiver, |
| 2881 const String& method_name, | 2832 const String& method_name, |
| 2882 ArgumentListNode* method_arguments) { | 2833 ArgumentListNode* method_arguments) { |
| 2883 // Build the graph to allocate an InvocationMirror object by calling | 2834 // Build the graph to allocate an InvocationMirror object by calling |
| 2884 // the static allocation method. | 2835 // the static allocation method. |
| 2885 const Library& corelib = Library::Handle(Library::CoreLibrary()); | 2836 const Library& corelib = Library::Handle(Library::CoreLibrary()); |
| 2886 const Class& mirror_class = Class::Handle( | 2837 const Class& mirror_class = Class::Handle( |
| 2887 corelib.LookupClassAllowPrivate(Symbols::InvocationMirror())); | 2838 corelib.LookupClassAllowPrivate(Symbols::InvocationMirror())); |
| 2888 ASSERT(!mirror_class.IsNull()); | 2839 ASSERT(!mirror_class.IsNull()); |
| 2889 const Function& allocation_function = Function::ZoneHandle( | 2840 const Function& allocation_function = Function::ZoneHandle( |
| 2890 Resolver::ResolveStaticByName( | 2841 Resolver::ResolveStaticByName( |
| 2891 mirror_class, | 2842 mirror_class, |
| 2892 PrivateCoreLibName(Symbols::AllocateInvocationMirror()), | 2843 PrivateCoreLibName(Symbols::AllocateInvocationMirror()), |
| 2893 Resolver::kIsQualified)); | 2844 Resolver::kIsQualified)); |
| 2894 ASSERT(!allocation_function.IsNull()); | 2845 ASSERT(!allocation_function.IsNull()); |
| 2895 | 2846 |
| 2896 // Evaluate the receiver before the arguments. This will be used | 2847 // Evaluate the receiver before the arguments. This will be used |
| 2897 // as an argument to the noSuchMethod call. | 2848 // as an argument to the noSuchMethod call. |
| 2898 ValueGraphVisitor for_receiver(owner(), temp_index(), loop_depth()); | 2849 ValueGraphVisitor for_receiver(owner(), temp_index()); |
| 2899 receiver->Visit(&for_receiver); | 2850 receiver->Visit(&for_receiver); |
| 2900 Append(for_receiver); | 2851 Append(for_receiver); |
| 2901 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); | 2852 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); |
| 2902 | 2853 |
| 2903 // Allocate the arguments and pass them into the construction | 2854 // Allocate the arguments and pass them into the construction |
| 2904 // of the InvocationMirror. | 2855 // of the InvocationMirror. |
| 2905 const intptr_t args_pos = method_arguments->token_pos(); | 2856 const intptr_t args_pos = method_arguments->token_pos(); |
| 2906 ArgumentListNode* arguments = new ArgumentListNode(args_pos); | 2857 ArgumentListNode* arguments = new ArgumentListNode(args_pos); |
| 2907 // The first argument is the original method name. | 2858 // The first argument is the original method name. |
| 2908 arguments->Add(new LiteralNode(args_pos, method_name)); | 2859 arguments->Add(new LiteralNode(args_pos, method_name)); |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2993 func, | 2944 func, |
| 2994 Array::ZoneHandle(), // No names. | 2945 Array::ZoneHandle(), // No names. |
| 2995 arguments); | 2946 arguments); |
| 2996 } | 2947 } |
| 2997 | 2948 |
| 2998 | 2949 |
| 2999 void EffectGraphVisitor::BuildThrowNode(ThrowNode* node) { | 2950 void EffectGraphVisitor::BuildThrowNode(ThrowNode* node) { |
| 3000 // TODO(kmillikin) non-local control flow is not handled correctly | 2951 // TODO(kmillikin) non-local control flow is not handled correctly |
| 3001 // by the inliner. | 2952 // by the inliner. |
| 3002 InlineBailout("EffectGraphVisitor::BuildThrowNode (exception)"); | 2953 InlineBailout("EffectGraphVisitor::BuildThrowNode (exception)"); |
| 3003 ValueGraphVisitor for_exception(owner(), temp_index(), loop_depth()); | 2954 ValueGraphVisitor for_exception(owner(), temp_index()); |
| 3004 node->exception()->Visit(&for_exception); | 2955 node->exception()->Visit(&for_exception); |
| 3005 Append(for_exception); | 2956 Append(for_exception); |
| 3006 PushArgument(for_exception.value()); | 2957 PushArgument(for_exception.value()); |
| 3007 Instruction* instr = NULL; | 2958 Instruction* instr = NULL; |
| 3008 if (node->stacktrace() == NULL) { | 2959 if (node->stacktrace() == NULL) { |
| 3009 instr = new ThrowInstr(node->token_pos()); | 2960 instr = new ThrowInstr(node->token_pos()); |
| 3010 } else { | 2961 } else { |
| 3011 ValueGraphVisitor for_stack_trace(owner(), temp_index(), loop_depth()); | 2962 ValueGraphVisitor for_stack_trace(owner(), temp_index()); |
| 3012 node->stacktrace()->Visit(&for_stack_trace); | 2963 node->stacktrace()->Visit(&for_stack_trace); |
| 3013 Append(for_stack_trace); | 2964 Append(for_stack_trace); |
| 3014 PushArgument(for_stack_trace.value()); | 2965 PushArgument(for_stack_trace.value()); |
| 3015 instr = new ReThrowInstr(node->token_pos()); | 2966 instr = new ReThrowInstr(node->token_pos()); |
| 3016 } | 2967 } |
| 3017 AddInstruction(instr); | 2968 AddInstruction(instr); |
| 3018 } | 2969 } |
| 3019 | 2970 |
| 3020 | 2971 |
| 3021 void EffectGraphVisitor::VisitThrowNode(ThrowNode* node) { | 2972 void EffectGraphVisitor::VisitThrowNode(ThrowNode* node) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 3038 const intptr_t try_index = owner()->try_index(); | 2989 const intptr_t try_index = owner()->try_index(); |
| 3039 if (try_index >= 0) { | 2990 if (try_index >= 0) { |
| 3040 // We are about to generate code for an inlined finally block. Exceptions | 2991 // We are about to generate code for an inlined finally block. Exceptions |
| 3041 // thrown in this block of code should be treated as though they are | 2992 // thrown in this block of code should be treated as though they are |
| 3042 // thrown not from the current try block but the outer try block if any. | 2993 // thrown not from the current try block but the outer try block if any. |
| 3043 owner()->set_try_index((try_index - 1)); | 2994 owner()->set_try_index((try_index - 1)); |
| 3044 } | 2995 } |
| 3045 BuildLoadContext(node->context_var()); | 2996 BuildLoadContext(node->context_var()); |
| 3046 | 2997 |
| 3047 JoinEntryInstr* finally_entry = | 2998 JoinEntryInstr* finally_entry = |
| 3048 new JoinEntryInstr(owner()->AllocateBlockId(), | 2999 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); |
| 3049 owner()->try_index(), | 3000 EffectGraphVisitor for_finally_block(owner(), temp_index()); |
| 3050 loop_depth()); | |
| 3051 EffectGraphVisitor for_finally_block(owner(), temp_index(), loop_depth()); | |
| 3052 node->finally_block()->Visit(&for_finally_block); | 3001 node->finally_block()->Visit(&for_finally_block); |
| 3053 | 3002 |
| 3054 if (try_index >= 0) { | 3003 if (try_index >= 0) { |
| 3055 owner()->set_try_index(try_index); | 3004 owner()->set_try_index(try_index); |
| 3056 } | 3005 } |
| 3057 | 3006 |
| 3058 if (for_finally_block.is_open()) { | 3007 if (for_finally_block.is_open()) { |
| 3059 JoinEntryInstr* after_finally = | 3008 JoinEntryInstr* after_finally = |
| 3060 new JoinEntryInstr(owner()->AllocateBlockId(), | 3009 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); |
| 3061 owner()->try_index(), | |
| 3062 loop_depth()); | |
| 3063 for_finally_block.Goto(after_finally); | 3010 for_finally_block.Goto(after_finally); |
| 3064 for_finally_block.exit_ = after_finally; | 3011 for_finally_block.exit_ = after_finally; |
| 3065 } | 3012 } |
| 3066 | 3013 |
| 3067 Goto(finally_entry); | 3014 Goto(finally_entry); |
| 3068 AppendFragment(finally_entry, for_finally_block); | 3015 AppendFragment(finally_entry, for_finally_block); |
| 3069 exit_ = for_finally_block.exit_; | 3016 exit_ = for_finally_block.exit_; |
| 3070 } | 3017 } |
| 3071 | 3018 |
| 3072 | 3019 |
| 3073 FlowGraph* FlowGraphBuilder::BuildGraph(intptr_t initial_loop_depth) { | 3020 FlowGraph* FlowGraphBuilder::BuildGraph() { |
| 3074 if (FLAG_print_ast) { | 3021 if (FLAG_print_ast) { |
| 3075 // Print the function ast before IL generation. | 3022 // Print the function ast before IL generation. |
| 3076 AstPrinter::PrintFunctionNodes(parsed_function()); | 3023 AstPrinter::PrintFunctionNodes(parsed_function()); |
| 3077 } | 3024 } |
| 3078 // Compilation can be nested, preserve the computation-id. | 3025 // Compilation can be nested, preserve the computation-id. |
| 3079 const Function& function = parsed_function().function(); | 3026 const Function& function = parsed_function().function(); |
| 3080 TargetEntryInstr* normal_entry = | 3027 TargetEntryInstr* normal_entry = |
| 3081 new TargetEntryInstr(AllocateBlockId(), | 3028 new TargetEntryInstr(AllocateBlockId(), |
| 3082 CatchClauseNode::kInvalidTryIndex, | 3029 CatchClauseNode::kInvalidTryIndex); |
| 3083 initial_loop_depth); | |
| 3084 graph_entry_ = new GraphEntryInstr(normal_entry); | 3030 graph_entry_ = new GraphEntryInstr(normal_entry); |
| 3085 EffectGraphVisitor for_effect(this, 0, initial_loop_depth); | 3031 EffectGraphVisitor for_effect(this, 0); |
| 3086 // TODO(kmillikin): We can eliminate stack checks in some cases (e.g., the | 3032 // TODO(kmillikin): We can eliminate stack checks in some cases (e.g., the |
| 3087 // stack check on entry for leaf routines). | 3033 // stack check on entry for leaf routines). |
| 3088 Instruction* check = new CheckStackOverflowInstr(function.token_pos()); | 3034 Instruction* check = new CheckStackOverflowInstr(function.token_pos()); |
| 3089 // If we are inlining don't actually attach the stack check. We must still | 3035 // If we are inlining don't actually attach the stack check. We must still |
| 3090 // create the stack check inorder to allocate a deopt id. | 3036 // create the stack check inorder to allocate a deopt id. |
| 3091 if (!InInliningContext()) for_effect.AddInstruction(check); | 3037 if (!InInliningContext()) for_effect.AddInstruction(check); |
| 3092 parsed_function().node_sequence()->Visit(&for_effect); | 3038 parsed_function().node_sequence()->Visit(&for_effect); |
| 3093 AppendFragment(normal_entry, for_effect); | 3039 AppendFragment(normal_entry, for_effect); |
| 3094 // Check that the graph is properly terminated. | 3040 // Check that the graph is properly terminated. |
| 3095 ASSERT(!for_effect.is_open()); | 3041 ASSERT(!for_effect.is_open()); |
| 3096 FlowGraph* graph = new FlowGraph(*this, graph_entry_, last_used_block_id_); | 3042 FlowGraph* graph = new FlowGraph(*this, graph_entry_, last_used_block_id_); |
| 3097 return graph; | 3043 return graph; |
| 3098 } | 3044 } |
| 3099 | 3045 |
| 3100 | 3046 |
| 3101 void FlowGraphBuilder::Bailout(const char* reason) { | 3047 void FlowGraphBuilder::Bailout(const char* reason) { |
| 3102 const char* kFormat = "FlowGraphBuilder Bailout: %s %s"; | 3048 const char* kFormat = "FlowGraphBuilder Bailout: %s %s"; |
| 3103 const char* function_name = parsed_function_.function().ToCString(); | 3049 const char* function_name = parsed_function_.function().ToCString(); |
| 3104 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; | 3050 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; |
| 3105 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 3051 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
| 3106 OS::SNPrint(chars, len, kFormat, function_name, reason); | 3052 OS::SNPrint(chars, len, kFormat, function_name, reason); |
| 3107 const Error& error = Error::Handle( | 3053 const Error& error = Error::Handle( |
| 3108 LanguageError::New(String::Handle(String::New(chars)))); | 3054 LanguageError::New(String::Handle(String::New(chars)))); |
| 3109 Isolate::Current()->long_jump_base()->Jump(1, error); | 3055 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 3110 } | 3056 } |
| 3111 | 3057 |
| 3112 | 3058 |
| 3113 } // namespace dart | 3059 } // namespace dart |
| OLD | NEW |