| 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 22 matching lines...) Expand all Loading... |
| 33 : parsed_function_(parsed_function), | 33 : parsed_function_(parsed_function), |
| 34 copied_parameter_count_(parsed_function.copied_parameter_count()), | 34 copied_parameter_count_(parsed_function.copied_parameter_count()), |
| 35 // All parameters are copied if any parameter is. | 35 // All parameters are copied if any parameter is. |
| 36 non_copied_parameter_count_((copied_parameter_count_ == 0) | 36 non_copied_parameter_count_((copied_parameter_count_ == 0) |
| 37 ? parsed_function.function().num_fixed_parameters() | 37 ? parsed_function.function().num_fixed_parameters() |
| 38 : 0), | 38 : 0), |
| 39 stack_local_count_(parsed_function.stack_local_count()), | 39 stack_local_count_(parsed_function.stack_local_count()), |
| 40 context_level_(0), | 40 context_level_(0), |
| 41 last_used_try_index_(CatchClauseNode::kInvalidTryIndex), | 41 last_used_try_index_(CatchClauseNode::kInvalidTryIndex), |
| 42 try_index_(CatchClauseNode::kInvalidTryIndex), | 42 try_index_(CatchClauseNode::kInvalidTryIndex), |
| 43 graph_entry_(NULL), | 43 graph_entry_(NULL) { } |
| 44 inlining_context_(kNotInlining), | |
| 45 exits_(NULL) { } | |
| 46 | 44 |
| 47 | 45 |
| 48 void FlowGraphBuilder::AddCatchEntry(TargetEntryInstr* entry) { | 46 void FlowGraphBuilder::AddCatchEntry(TargetEntryInstr* entry) { |
| 49 graph_entry_->AddCatchEntry(entry); | 47 graph_entry_->AddCatchEntry(entry); |
| 50 } | 48 } |
| 51 | 49 |
| 52 | 50 |
| 53 void EffectGraphVisitor::Append(const EffectGraphVisitor& other_fragment) { | 51 void EffectGraphVisitor::Append(const EffectGraphVisitor& other_fragment) { |
| 54 ASSERT(is_open()); | 52 ASSERT(is_open()); |
| 55 if (other_fragment.is_empty()) return; | 53 if (other_fragment.is_empty()) return; |
| (...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 334 } | 332 } |
| 335 ReturnValue(Bind(computation)); | 333 ReturnValue(Bind(computation)); |
| 336 } | 334 } |
| 337 | 335 |
| 338 | 336 |
| 339 void EffectGraphVisitor::Bailout(const char* reason) { | 337 void EffectGraphVisitor::Bailout(const char* reason) { |
| 340 owner()->Bailout(reason); | 338 owner()->Bailout(reason); |
| 341 } | 339 } |
| 342 | 340 |
| 343 | 341 |
| 344 void EffectGraphVisitor::InlineBailout(const char* reason) { | |
| 345 if (owner()->InInliningContext()) owner()->Bailout(reason); | |
| 346 } | |
| 347 | |
| 348 | |
| 349 // <Statement> ::= Return { value: <Expression> | 342 // <Statement> ::= Return { value: <Expression> |
| 350 // inlined_finally_list: <InlinedFinally>* } | 343 // inlined_finally_list: <InlinedFinally>* } |
| 351 void EffectGraphVisitor::VisitReturnNode(ReturnNode* node) { | 344 void EffectGraphVisitor::VisitReturnNode(ReturnNode* node) { |
| 352 ValueGraphVisitor for_value(owner(), temp_index()); | 345 ValueGraphVisitor for_value(owner(), temp_index()); |
| 353 node->value()->Visit(&for_value); | 346 node->value()->Visit(&for_value); |
| 354 Append(for_value); | 347 Append(for_value); |
| 355 | 348 |
| 356 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { | 349 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { |
| 357 InlineBailout("EffectGraphVisitor::VisitReturnNode (finally)"); | |
| 358 EffectGraphVisitor for_effect(owner(), temp_index()); | 350 EffectGraphVisitor for_effect(owner(), temp_index()); |
| 359 node->InlinedFinallyNodeAt(i)->Visit(&for_effect); | 351 node->InlinedFinallyNodeAt(i)->Visit(&for_effect); |
| 360 Append(for_effect); | 352 Append(for_effect); |
| 361 if (!is_open()) return; | 353 if (!is_open()) return; |
| 362 } | 354 } |
| 363 | 355 |
| 364 Value* return_value = for_value.value(); | 356 Value* return_value = for_value.value(); |
| 365 if (FLAG_enable_type_checks) { | 357 if (FLAG_enable_type_checks) { |
| 366 InlineBailout("EffectGraphVisitor::VisitReturnNode (type check)"); | |
| 367 const Function& function = owner()->parsed_function().function(); | 358 const Function& function = owner()->parsed_function().function(); |
| 368 const bool is_implicit_dynamic_getter = | 359 const bool is_implicit_dynamic_getter = |
| 369 (!function.is_static() && | 360 (!function.is_static() && |
| 370 ((function.kind() == RawFunction::kImplicitGetter) || | 361 ((function.kind() == RawFunction::kImplicitGetter) || |
| 371 (function.kind() == RawFunction::kConstImplicitGetter))); | 362 (function.kind() == RawFunction::kConstImplicitGetter))); |
| 372 // Implicit getters do not need a type check at return, unless they compute | 363 // Implicit getters do not need a type check at return, unless they compute |
| 373 // the initial value of a static field. | 364 // the initial value of a static field. |
| 374 // The body of a constructor cannot modify the type of the | 365 // The body of a constructor cannot modify the type of the |
| 375 // constructed instance, which is passed in as an implicit parameter. | 366 // constructed instance, which is passed in as an implicit parameter. |
| 376 // However, factories may create an instance of the wrong type. | 367 // However, factories may create an instance of the wrong type. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 391 ASSERT(current_context_level >= 0); | 382 ASSERT(current_context_level >= 0); |
| 392 if (owner()->parsed_function().saved_context_var() != NULL) { | 383 if (owner()->parsed_function().saved_context_var() != NULL) { |
| 393 // CTX on entry was saved, but not linked as context parent. | 384 // CTX on entry was saved, but not linked as context parent. |
| 394 BuildLoadContext(*owner()->parsed_function().saved_context_var()); | 385 BuildLoadContext(*owner()->parsed_function().saved_context_var()); |
| 395 } else { | 386 } else { |
| 396 while (current_context_level-- > 0) { | 387 while (current_context_level-- > 0) { |
| 397 UnchainContext(); | 388 UnchainContext(); |
| 398 } | 389 } |
| 399 } | 390 } |
| 400 | 391 |
| 401 ReturnInstr* return_instr = new ReturnInstr(node->token_pos(), return_value); | 392 AddInstruction(new ReturnInstr(node->token_pos(), return_value)); |
| 402 AddReturnExit(return_instr); | |
| 403 AddInstruction(return_instr); | |
| 404 CloseFragment(); | 393 CloseFragment(); |
| 405 } | 394 } |
| 406 | 395 |
| 407 | 396 |
| 408 // <Expression> ::= Literal { literal: Instance } | 397 // <Expression> ::= Literal { literal: Instance } |
| 409 void EffectGraphVisitor::VisitLiteralNode(LiteralNode* node) { | 398 void EffectGraphVisitor::VisitLiteralNode(LiteralNode* node) { |
| 410 return; | 399 return; |
| 411 } | 400 } |
| 412 | 401 |
| 413 | 402 |
| 414 void ValueGraphVisitor::VisitLiteralNode(LiteralNode* node) { | 403 void ValueGraphVisitor::VisitLiteralNode(LiteralNode* node) { |
| 415 ReturnComputation(new ConstantComp(node->literal())); | 404 ReturnComputation(new ConstantComp(node->literal())); |
| 416 } | 405 } |
| 417 | 406 |
| 418 | 407 |
| 419 // Type nodes only occur as the right-hand side of instanceof comparisons, | 408 // Type nodes only occur as the right-hand side of instanceof comparisons, |
| 420 // and they are handled specially in that context. | 409 // and they are handled specially in that context. |
| 421 void EffectGraphVisitor::VisitTypeNode(TypeNode* node) { UNREACHABLE(); } | 410 void EffectGraphVisitor::VisitTypeNode(TypeNode* node) { UNREACHABLE(); } |
| 422 | 411 |
| 423 | 412 |
| 424 // Returns true if the type check can be skipped, for example, if the | 413 // Returns true if the type check can be skipped, for example, if the |
| 425 // destination type is Dynamic or if the compile type of the value is a subtype | 414 // destination type is Dynamic or if the compile type of the value is a subtype |
| 426 // of the destination type. | 415 // of the destination type. |
| 427 bool EffectGraphVisitor::CanSkipTypeCheck(intptr_t token_pos, | 416 bool EffectGraphVisitor::CanSkipTypeCheck(intptr_t token_pos, |
| 428 Value* value, | 417 Value* value, |
| 429 const AbstractType& dst_type, | 418 const AbstractType& dst_type, |
| 430 const String& dst_name) { | 419 const String& dst_name) { |
| 431 InlineBailout("EffectGraphVisitor::CanSkipTypeCheck"); | |
| 432 ASSERT(!dst_type.IsNull()); | 420 ASSERT(!dst_type.IsNull()); |
| 433 ASSERT(dst_type.IsFinalized()); | 421 ASSERT(dst_type.IsFinalized()); |
| 434 | 422 |
| 435 // If the destination type is malformed, a dynamic type error must be thrown | 423 // If the destination type is malformed, a dynamic type error must be thrown |
| 436 // at run time. | 424 // at run time. |
| 437 if (dst_type.IsMalformed()) { | 425 if (dst_type.IsMalformed()) { |
| 438 return false; | 426 return false; |
| 439 } | 427 } |
| 440 | 428 |
| 441 // Any type is more specific than the Dynamic type and than the Object type. | 429 // Any type is more specific than the Dynamic type and than the Object type. |
| (...skipping 27 matching lines...) Expand all Loading... |
| 469 eliminated); | 457 eliminated); |
| 470 } | 458 } |
| 471 return eliminated; | 459 return eliminated; |
| 472 } | 460 } |
| 473 | 461 |
| 474 | 462 |
| 475 // <Expression> :: Assignable { expr: <Expression> | 463 // <Expression> :: Assignable { expr: <Expression> |
| 476 // type: AbstractType | 464 // type: AbstractType |
| 477 // dst_name: String } | 465 // dst_name: String } |
| 478 void EffectGraphVisitor::VisitAssignableNode(AssignableNode* node) { | 466 void EffectGraphVisitor::VisitAssignableNode(AssignableNode* node) { |
| 479 InlineBailout("EffectGraphVisitor::VisitAssignableNode"); | |
| 480 UNREACHABLE(); | 467 UNREACHABLE(); |
| 481 } | 468 } |
| 482 | 469 |
| 483 | 470 |
| 484 void ValueGraphVisitor::VisitAssignableNode(AssignableNode* node) { | 471 void ValueGraphVisitor::VisitAssignableNode(AssignableNode* node) { |
| 485 InlineBailout("ValueGraphVisitor::VisitAssignableNode"); | |
| 486 ValueGraphVisitor for_value(owner(), temp_index()); | 472 ValueGraphVisitor for_value(owner(), temp_index()); |
| 487 node->expr()->Visit(&for_value); | 473 node->expr()->Visit(&for_value); |
| 488 Append(for_value); | 474 Append(for_value); |
| 489 ReturnValue(BuildAssignableValue(node->expr()->token_pos(), | 475 ReturnValue(BuildAssignableValue(node->expr()->token_pos(), |
| 490 for_value.value(), | 476 for_value.value(), |
| 491 node->type(), | 477 node->type(), |
| 492 node->dst_name())); | 478 node->dst_name())); |
| 493 } | 479 } |
| 494 | 480 |
| 495 | 481 |
| 496 // <Expression> :: BinaryOp { kind: Token::Kind | 482 // <Expression> :: BinaryOp { kind: Token::Kind |
| 497 // left: <Expression> | 483 // left: <Expression> |
| 498 // right: <Expression> } | 484 // right: <Expression> } |
| 499 void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { | 485 void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { |
| 500 InlineBailout("EffectGraphVisitor::VisitBinaryOpNode"); | |
| 501 // Operators "&&" and "||" cannot be overloaded therefore do not call | 486 // Operators "&&" and "||" cannot be overloaded therefore do not call |
| 502 // operator. | 487 // operator. |
| 503 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { | 488 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { |
| 504 // See ValueGraphVisitor::VisitBinaryOpNode. | 489 // See ValueGraphVisitor::VisitBinaryOpNode. |
| 505 TestGraphVisitor for_left(owner(), | 490 TestGraphVisitor for_left(owner(), |
| 506 temp_index(), | 491 temp_index(), |
| 507 node->left()->token_pos()); | 492 node->left()->token_pos()); |
| 508 node->left()->Visit(&for_left); | 493 node->left()->Visit(&for_left); |
| 509 EffectGraphVisitor for_right(owner(), temp_index()); | 494 EffectGraphVisitor for_right(owner(), temp_index()); |
| 510 node->right()->Visit(&for_right); | 495 node->right()->Visit(&for_right); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 536 node->kind(), | 521 node->kind(), |
| 537 arguments, | 522 arguments, |
| 538 Array::ZoneHandle(), | 523 Array::ZoneHandle(), |
| 539 2); | 524 2); |
| 540 ReturnComputation(call); | 525 ReturnComputation(call); |
| 541 } | 526 } |
| 542 | 527 |
| 543 | 528 |
| 544 // Special handling for AND/OR. | 529 // Special handling for AND/OR. |
| 545 void ValueGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { | 530 void ValueGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { |
| 546 InlineBailout("ValueGraphVisitor::VisitBinaryOpNode"); | |
| 547 // Operators "&&" and "||" cannot be overloaded therefore do not call | 531 // Operators "&&" and "||" cannot be overloaded therefore do not call |
| 548 // operator. | 532 // operator. |
| 549 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { | 533 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { |
| 550 // Implement short-circuit logic: do not evaluate right if evaluation | 534 // Implement short-circuit logic: do not evaluate right if evaluation |
| 551 // of left is sufficient. | 535 // of left is sufficient. |
| 552 // AND: left ? right === true : false; | 536 // AND: left ? right === true : false; |
| 553 // OR: left ? true : right === true; | 537 // OR: left ? true : right === true; |
| 554 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | 538 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); |
| 555 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); | 539 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); |
| 556 | 540 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 597 return; | 581 return; |
| 598 } | 582 } |
| 599 EffectGraphVisitor::VisitBinaryOpNode(node); | 583 EffectGraphVisitor::VisitBinaryOpNode(node); |
| 600 } | 584 } |
| 601 | 585 |
| 602 | 586 |
| 603 void EffectGraphVisitor::BuildTypecheckArguments( | 587 void EffectGraphVisitor::BuildTypecheckArguments( |
| 604 intptr_t token_pos, | 588 intptr_t token_pos, |
| 605 Value** instantiator_result, | 589 Value** instantiator_result, |
| 606 Value** instantiator_type_arguments_result) { | 590 Value** instantiator_type_arguments_result) { |
| 607 InlineBailout("EffectGraphVisitor::VisitBinaryOpNode"); | |
| 608 Value* instantiator = NULL; | 591 Value* instantiator = NULL; |
| 609 Value* instantiator_type_arguments = NULL; | 592 Value* instantiator_type_arguments = NULL; |
| 610 const Class& instantiator_class = Class::Handle( | 593 const Class& instantiator_class = Class::Handle( |
| 611 owner()->parsed_function().function().Owner()); | 594 owner()->parsed_function().function().Owner()); |
| 612 // Since called only when type tested against is not instantiated. | 595 // Since called only when type tested against is not instantiated. |
| 613 ASSERT(instantiator_class.NumTypeParameters() > 0); | 596 ASSERT(instantiator_class.NumTypeParameters() > 0); |
| 614 instantiator = BuildInstantiator(); | 597 instantiator = BuildInstantiator(); |
| 615 if (instantiator == NULL) { | 598 if (instantiator == NULL) { |
| 616 // No instantiator when inside factory. | 599 // No instantiator when inside factory. |
| 617 instantiator = BuildNullValue(); | 600 instantiator = BuildNullValue(); |
| 618 instantiator_type_arguments = | 601 instantiator_type_arguments = |
| 619 BuildInstantiatorTypeArguments(token_pos, NULL); | 602 BuildInstantiatorTypeArguments(token_pos, NULL); |
| 620 } else { | 603 } else { |
| 621 // Preserve instantiator. | 604 // Preserve instantiator. |
| 622 const LocalVariable& expr_temp = | 605 const LocalVariable& expr_temp = |
| 623 *owner()->parsed_function().expression_temp_var(); | 606 *owner()->parsed_function().expression_temp_var(); |
| 624 instantiator = Bind(BuildStoreLocal(expr_temp, instantiator)); | 607 instantiator = Bind(BuildStoreLocal(expr_temp, instantiator)); |
| 625 Value* loaded = Bind(BuildLoadLocal(expr_temp)); | 608 Value* loaded = Bind(BuildLoadLocal(expr_temp)); |
| 626 instantiator_type_arguments = | 609 instantiator_type_arguments = |
| 627 BuildInstantiatorTypeArguments(token_pos, loaded); | 610 BuildInstantiatorTypeArguments(token_pos, loaded); |
| 628 } | 611 } |
| 629 *instantiator_result = instantiator; | 612 *instantiator_result = instantiator; |
| 630 *instantiator_type_arguments_result = instantiator_type_arguments; | 613 *instantiator_type_arguments_result = instantiator_type_arguments; |
| 631 } | 614 } |
| 632 | 615 |
| 633 | 616 |
| 634 Value* EffectGraphVisitor::BuildNullValue() { | 617 Value* EffectGraphVisitor::BuildNullValue() { |
| 635 InlineBailout("EffectGraphVisitor::BuildNullValue"); | |
| 636 return Bind(new ConstantComp(Object::ZoneHandle())); | 618 return Bind(new ConstantComp(Object::ZoneHandle())); |
| 637 } | 619 } |
| 638 | 620 |
| 639 | 621 |
| 640 // Used for testing incoming arguments. | 622 // Used for testing incoming arguments. |
| 641 AssertAssignableComp* EffectGraphVisitor::BuildAssertAssignable( | 623 AssertAssignableComp* EffectGraphVisitor::BuildAssertAssignable( |
| 642 intptr_t token_pos, | 624 intptr_t token_pos, |
| 643 Value* value, | 625 Value* value, |
| 644 const AbstractType& dst_type, | 626 const AbstractType& dst_type, |
| 645 const String& dst_name) { | 627 const String& dst_name) { |
| 646 InlineBailout("EffectGraphVisitor::BuildAssertAssignable"); | |
| 647 // Build the type check computation. | 628 // Build the type check computation. |
| 648 Value* instantiator = NULL; | 629 Value* instantiator = NULL; |
| 649 Value* instantiator_type_arguments = NULL; | 630 Value* instantiator_type_arguments = NULL; |
| 650 if (dst_type.IsInstantiated()) { | 631 if (dst_type.IsInstantiated()) { |
| 651 instantiator = BuildNullValue(); | 632 instantiator = BuildNullValue(); |
| 652 instantiator_type_arguments = BuildNullValue(); | 633 instantiator_type_arguments = BuildNullValue(); |
| 653 } else { | 634 } else { |
| 654 BuildTypecheckArguments(token_pos, | 635 BuildTypecheckArguments(token_pos, |
| 655 &instantiator, | 636 &instantiator, |
| 656 &instantiator_type_arguments); | 637 &instantiator_type_arguments); |
| 657 } | 638 } |
| 658 return new AssertAssignableComp(token_pos, | 639 return new AssertAssignableComp(token_pos, |
| 659 value, | 640 value, |
| 660 instantiator, | 641 instantiator, |
| 661 instantiator_type_arguments, | 642 instantiator_type_arguments, |
| 662 dst_type, | 643 dst_type, |
| 663 dst_name); | 644 dst_name); |
| 664 } | 645 } |
| 665 | 646 |
| 666 | 647 |
| 667 // Used for type casts and to test assignments. | 648 // Used for type casts and to test assignments. |
| 668 Value* EffectGraphVisitor::BuildAssignableValue(intptr_t token_pos, | 649 Value* EffectGraphVisitor::BuildAssignableValue(intptr_t token_pos, |
| 669 Value* value, | 650 Value* value, |
| 670 const AbstractType& dst_type, | 651 const AbstractType& dst_type, |
| 671 const String& dst_name) { | 652 const String& dst_name) { |
| 672 InlineBailout("EffectGraphVisitor::BuildAssignableValue"); | |
| 673 if (CanSkipTypeCheck(token_pos, value, dst_type, dst_name)) { | 653 if (CanSkipTypeCheck(token_pos, value, dst_type, dst_name)) { |
| 674 return value; | 654 return value; |
| 675 } | 655 } |
| 676 return Bind(BuildAssertAssignable(token_pos, value, dst_type, dst_name)); | 656 return Bind(BuildAssertAssignable(token_pos, value, dst_type, dst_name)); |
| 677 } | 657 } |
| 678 | 658 |
| 679 | 659 |
| 680 void EffectGraphVisitor::BuildTypeTest(ComparisonNode* node) { | 660 void EffectGraphVisitor::BuildTypeTest(ComparisonNode* node) { |
| 681 InlineBailout("EffectGraphVisitor::BuildTypeTest"); | |
| 682 ASSERT(Token::IsTypeTestOperator(node->kind())); | 661 ASSERT(Token::IsTypeTestOperator(node->kind())); |
| 683 EffectGraphVisitor for_left_value(owner(), temp_index()); | 662 EffectGraphVisitor for_left_value(owner(), temp_index()); |
| 684 node->left()->Visit(&for_left_value); | 663 node->left()->Visit(&for_left_value); |
| 685 Append(for_left_value); | 664 Append(for_left_value); |
| 686 } | 665 } |
| 687 | 666 |
| 688 | 667 |
| 689 void EffectGraphVisitor::BuildTypeCast(ComparisonNode* node) { | 668 void EffectGraphVisitor::BuildTypeCast(ComparisonNode* node) { |
| 690 InlineBailout("EffectGraphVisitor::BuildTypeCast"); | |
| 691 ASSERT(Token::IsTypeCastOperator(node->kind())); | 669 ASSERT(Token::IsTypeCastOperator(node->kind())); |
| 692 const AbstractType& type = node->right()->AsTypeNode()->type(); | 670 const AbstractType& type = node->right()->AsTypeNode()->type(); |
| 693 ASSERT(type.IsFinalized()); // The type in a type cast may be malformed. | 671 ASSERT(type.IsFinalized()); // The type in a type cast may be malformed. |
| 694 ValueGraphVisitor for_value(owner(), temp_index()); | 672 ValueGraphVisitor for_value(owner(), temp_index()); |
| 695 node->left()->Visit(&for_value); | 673 node->left()->Visit(&for_value); |
| 696 Append(for_value); | 674 Append(for_value); |
| 697 const String& dst_name = String::ZoneHandle( | 675 const String& dst_name = String::ZoneHandle( |
| 698 Symbols::New(Exceptions::kCastExceptionDstName)); | 676 Symbols::New(Exceptions::kCastExceptionDstName)); |
| 699 if (!CanSkipTypeCheck(node->token_pos(), for_value.value(), type, dst_name)) { | 677 if (!CanSkipTypeCheck(node->token_pos(), for_value.value(), type, dst_name)) { |
| 700 Do(BuildAssertAssignable( | 678 Do(BuildAssertAssignable( |
| 701 node->token_pos(), for_value.value(), type, dst_name)); | 679 node->token_pos(), for_value.value(), type, dst_name)); |
| 702 } | 680 } |
| 703 } | 681 } |
| 704 | 682 |
| 705 | 683 |
| 706 void ValueGraphVisitor::BuildTypeTest(ComparisonNode* node) { | 684 void ValueGraphVisitor::BuildTypeTest(ComparisonNode* node) { |
| 707 InlineBailout("ValueGraphVisitor::BuildTypeTest"); | |
| 708 ASSERT(Token::IsTypeTestOperator(node->kind())); | 685 ASSERT(Token::IsTypeTestOperator(node->kind())); |
| 709 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | 686 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); |
| 710 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); | 687 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); |
| 711 const AbstractType& type = node->right()->AsTypeNode()->type(); | 688 const AbstractType& type = node->right()->AsTypeNode()->type(); |
| 712 ASSERT(type.IsFinalized() && !type.IsMalformed()); | 689 ASSERT(type.IsFinalized() && !type.IsMalformed()); |
| 713 const bool negate_result = (node->kind() == Token::kISNOT); | 690 const bool negate_result = (node->kind() == Token::kISNOT); |
| 714 // All objects are instances of type T if Object type is a subtype of type T. | 691 // All objects are instances of type T if Object type is a subtype of type T. |
| 715 const Type& object_type = Type::Handle(Type::ObjectType()); | 692 const Type& object_type = Type::Handle(Type::ObjectType()); |
| 716 if (type.IsInstantiated() && object_type.IsSubtypeOf(type, NULL)) { | 693 if (type.IsInstantiated() && object_type.IsSubtypeOf(type, NULL)) { |
| 717 // Must evaluate left side. | 694 // Must evaluate left side. |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 764 for_left_value.value(), | 741 for_left_value.value(), |
| 765 instantiator, | 742 instantiator, |
| 766 instantiator_type_arguments, | 743 instantiator_type_arguments, |
| 767 node->right()->AsTypeNode()->type(), | 744 node->right()->AsTypeNode()->type(), |
| 768 (node->kind() == Token::kISNOT)); | 745 (node->kind() == Token::kISNOT)); |
| 769 ReturnComputation(instance_of); | 746 ReturnComputation(instance_of); |
| 770 } | 747 } |
| 771 | 748 |
| 772 | 749 |
| 773 void ValueGraphVisitor::BuildTypeCast(ComparisonNode* node) { | 750 void ValueGraphVisitor::BuildTypeCast(ComparisonNode* node) { |
| 774 InlineBailout("ValueGraphVisitor::BuildTypeCast"); | |
| 775 ASSERT(Token::IsTypeCastOperator(node->kind())); | 751 ASSERT(Token::IsTypeCastOperator(node->kind())); |
| 776 const AbstractType& type = node->right()->AsTypeNode()->type(); | 752 const AbstractType& type = node->right()->AsTypeNode()->type(); |
| 777 ASSERT(type.IsFinalized()); // The type in a type cast may be malformed. | 753 ASSERT(type.IsFinalized()); // The type in a type cast may be malformed. |
| 778 ValueGraphVisitor for_value(owner(), temp_index()); | 754 ValueGraphVisitor for_value(owner(), temp_index()); |
| 779 node->left()->Visit(&for_value); | 755 node->left()->Visit(&for_value); |
| 780 Append(for_value); | 756 Append(for_value); |
| 781 const String& dst_name = String::ZoneHandle( | 757 const String& dst_name = String::ZoneHandle( |
| 782 Symbols::New(Exceptions::kCastExceptionDstName)); | 758 Symbols::New(Exceptions::kCastExceptionDstName)); |
| 783 ReturnValue(BuildAssignableValue(node->token_pos(), | 759 ReturnValue(BuildAssignableValue(node->token_pos(), |
| 784 for_value.value(), | 760 for_value.value(), |
| 785 type, | 761 type, |
| 786 dst_name)); | 762 dst_name)); |
| 787 } | 763 } |
| 788 | 764 |
| 789 | 765 |
| 790 // <Expression> :: Comparison { kind: Token::Kind | 766 // <Expression> :: Comparison { kind: Token::Kind |
| 791 // left: <Expression> | 767 // left: <Expression> |
| 792 // right: <Expression> } | 768 // right: <Expression> } |
| 793 // TODO(srdjan): Implement new equality. | 769 // TODO(srdjan): Implement new equality. |
| 794 void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) { | 770 void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) { |
| 795 InlineBailout("EffectGraphVisitor::VisitComparisonNode"); | |
| 796 if (Token::IsTypeTestOperator(node->kind())) { | 771 if (Token::IsTypeTestOperator(node->kind())) { |
| 797 BuildTypeTest(node); | 772 BuildTypeTest(node); |
| 798 return; | 773 return; |
| 799 } | 774 } |
| 800 if (Token::IsTypeCastOperator(node->kind())) { | 775 if (Token::IsTypeCastOperator(node->kind())) { |
| 801 BuildTypeCast(node); | 776 BuildTypeCast(node); |
| 802 return; | 777 return; |
| 803 } | 778 } |
| 804 if ((node->kind() == Token::kEQ_STRICT) || | 779 if ((node->kind() == Token::kEQ_STRICT) || |
| 805 (node->kind() == Token::kNE_STRICT)) { | 780 (node->kind() == Token::kNE_STRICT)) { |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 854 Append(for_right_value); | 829 Append(for_right_value); |
| 855 RelationalOpComp* comp = new RelationalOpComp(node->token_pos(), | 830 RelationalOpComp* comp = new RelationalOpComp(node->token_pos(), |
| 856 node->kind(), | 831 node->kind(), |
| 857 for_left_value.value(), | 832 for_left_value.value(), |
| 858 for_right_value.value()); | 833 for_right_value.value()); |
| 859 ReturnComputation(comp); | 834 ReturnComputation(comp); |
| 860 } | 835 } |
| 861 | 836 |
| 862 | 837 |
| 863 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) { | 838 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) { |
| 864 InlineBailout("EffectGraphVisitor::VisitUnaryOpNode"); | |
| 865 // "!" cannot be overloaded, therefore do not call operator. | 839 // "!" cannot be overloaded, therefore do not call operator. |
| 866 if (node->kind() == Token::kNOT) { | 840 if (node->kind() == Token::kNOT) { |
| 867 ValueGraphVisitor for_value(owner(), temp_index()); | 841 ValueGraphVisitor for_value(owner(), temp_index()); |
| 868 node->operand()->Visit(&for_value); | 842 node->operand()->Visit(&for_value); |
| 869 Append(for_value); | 843 Append(for_value); |
| 870 Value* value = for_value.value(); | 844 Value* value = for_value.value(); |
| 871 if (FLAG_enable_type_checks) { | 845 if (FLAG_enable_type_checks) { |
| 872 value = | 846 value = |
| 873 Bind(new AssertBooleanComp(node->operand()->token_pos(), value)); | 847 Bind(new AssertBooleanComp(node->operand()->token_pos(), value)); |
| 874 } | 848 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 890 name = Symbols::New(Token::Str(node->kind())); | 864 name = Symbols::New(Token::Str(node->kind())); |
| 891 } | 865 } |
| 892 InstanceCallComp* call = new InstanceCallComp( | 866 InstanceCallComp* call = new InstanceCallComp( |
| 893 node->token_pos(), name, node->kind(), | 867 node->token_pos(), name, node->kind(), |
| 894 arguments, Array::ZoneHandle(), 1); | 868 arguments, Array::ZoneHandle(), 1); |
| 895 ReturnComputation(call); | 869 ReturnComputation(call); |
| 896 } | 870 } |
| 897 | 871 |
| 898 | 872 |
| 899 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { | 873 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { |
| 900 InlineBailout("EffectGraphVisitor::VisitConditionalExprNode"); | |
| 901 TestGraphVisitor for_test(owner(), | 874 TestGraphVisitor for_test(owner(), |
| 902 temp_index(), | 875 temp_index(), |
| 903 node->condition()->token_pos()); | 876 node->condition()->token_pos()); |
| 904 node->condition()->Visit(&for_test); | 877 node->condition()->Visit(&for_test); |
| 905 | 878 |
| 906 // Translate the subexpressions for their effects. | 879 // Translate the subexpressions for their effects. |
| 907 EffectGraphVisitor for_true(owner(), temp_index()); | 880 EffectGraphVisitor for_true(owner(), temp_index()); |
| 908 node->true_expr()->Visit(&for_true); | 881 node->true_expr()->Visit(&for_true); |
| 909 EffectGraphVisitor for_false(owner(), temp_index()); | 882 EffectGraphVisitor for_false(owner(), temp_index()); |
| 910 node->false_expr()->Visit(&for_false); | 883 node->false_expr()->Visit(&for_false); |
| 911 | 884 |
| 912 Join(for_test, for_true, for_false); | 885 Join(for_test, for_true, for_false); |
| 913 } | 886 } |
| 914 | 887 |
| 915 | 888 |
| 916 void ValueGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { | 889 void ValueGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { |
| 917 InlineBailout("ValueGraphVisitor::VisitConditionalExprNode"); | |
| 918 TestGraphVisitor for_test(owner(), | 890 TestGraphVisitor for_test(owner(), |
| 919 temp_index(), | 891 temp_index(), |
| 920 node->condition()->token_pos()); | 892 node->condition()->token_pos()); |
| 921 node->condition()->Visit(&for_test); | 893 node->condition()->Visit(&for_test); |
| 922 | 894 |
| 923 ValueGraphVisitor for_true(owner(), temp_index()); | 895 ValueGraphVisitor for_true(owner(), temp_index()); |
| 924 node->true_expr()->Visit(&for_true); | 896 node->true_expr()->Visit(&for_true); |
| 925 ASSERT(for_true.is_open()); | 897 ASSERT(for_true.is_open()); |
| 926 for_true.Do(BuildStoreLocal( | 898 for_true.Do(BuildStoreLocal( |
| 927 *owner()->parsed_function().expression_temp_var(), for_true.value())); | 899 *owner()->parsed_function().expression_temp_var(), for_true.value())); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 952 | 924 |
| 953 node->true_branch()->Visit(&for_true); | 925 node->true_branch()->Visit(&for_true); |
| 954 // The for_false graph fragment will be empty (default graph fragment) if | 926 // The for_false graph fragment will be empty (default graph fragment) if |
| 955 // we do not call Visit. | 927 // we do not call Visit. |
| 956 if (node->false_branch() != NULL) node->false_branch()->Visit(&for_false); | 928 if (node->false_branch() != NULL) node->false_branch()->Visit(&for_false); |
| 957 Join(for_test, for_true, for_false); | 929 Join(for_test, for_true, for_false); |
| 958 } | 930 } |
| 959 | 931 |
| 960 | 932 |
| 961 void EffectGraphVisitor::VisitSwitchNode(SwitchNode* node) { | 933 void EffectGraphVisitor::VisitSwitchNode(SwitchNode* node) { |
| 962 InlineBailout("EffectGraphVisitor::VisitSwitchNode"); | |
| 963 EffectGraphVisitor switch_body(owner(), temp_index()); | 934 EffectGraphVisitor switch_body(owner(), temp_index()); |
| 964 node->body()->Visit(&switch_body); | 935 node->body()->Visit(&switch_body); |
| 965 Append(switch_body); | 936 Append(switch_body); |
| 966 if ((node->label() != NULL) && (node->label()->join_for_break() != NULL)) { | 937 if ((node->label() != NULL) && (node->label()->join_for_break() != NULL)) { |
| 967 if (is_open()) Goto(node->label()->join_for_break()); | 938 if (is_open()) Goto(node->label()->join_for_break()); |
| 968 exit_ = node->label()->join_for_break(); | 939 exit_ = node->label()->join_for_break(); |
| 969 } | 940 } |
| 970 // No continue label allowed. | 941 // No continue label allowed. |
| 971 ASSERT((node->label() == NULL) || | 942 ASSERT((node->label() == NULL) || |
| 972 (node->label()->join_for_continue() == NULL)); | 943 (node->label()->join_for_continue() == NULL)); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 988 // e) true-target-0 -> case-statements-join | 959 // e) true-target-0 -> case-statements-join |
| 989 // f) true-target-1 -> case-statements-join | 960 // f) true-target-1 -> case-statements-join |
| 990 // g) case-statements-join | 961 // g) case-statements-join |
| 991 // h) [ case-statements ] -> exit-join | 962 // h) [ case-statements ] -> exit-join |
| 992 // i) exit-target -> exit-join | 963 // i) exit-target -> exit-join |
| 993 // j) exit-join | 964 // j) exit-join |
| 994 // | 965 // |
| 995 // Note: The specification of switch/case is under discussion and may change | 966 // Note: The specification of switch/case is under discussion and may change |
| 996 // drastically. | 967 // drastically. |
| 997 void EffectGraphVisitor::VisitCaseNode(CaseNode* node) { | 968 void EffectGraphVisitor::VisitCaseNode(CaseNode* node) { |
| 998 InlineBailout("EffectGraphVisitor::VisitCaseNode"); | |
| 999 const intptr_t len = node->case_expressions()->length(); | 969 const intptr_t len = node->case_expressions()->length(); |
| 1000 // Create case statements instructions. | 970 // Create case statements instructions. |
| 1001 EffectGraphVisitor for_case_statements(owner(), temp_index()); | 971 EffectGraphVisitor for_case_statements(owner(), temp_index()); |
| 1002 // Compute start of statements fragment. | 972 // Compute start of statements fragment. |
| 1003 JoinEntryInstr* statement_start = NULL; | 973 JoinEntryInstr* statement_start = NULL; |
| 1004 if ((node->label() != NULL) && node->label()->is_continue_target()) { | 974 if ((node->label() != NULL) && node->label()->is_continue_target()) { |
| 1005 // Since a labeled jump continue statement occur in a different case node, | 975 // Since a labeled jump continue statement occur in a different case node, |
| 1006 // allocate JoinNode here and use it as statement start. | 976 // allocate JoinNode here and use it as statement start. |
| 1007 statement_start = node->label()->join_for_continue(); | 977 statement_start = node->label()->join_for_continue(); |
| 1008 if (statement_start == NULL) { | 978 if (statement_start == NULL) { |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1088 // body: <Sequence> } | 1058 // body: <Sequence> } |
| 1089 // The fragment is composed as follows: | 1059 // The fragment is composed as follows: |
| 1090 // a) loop-join | 1060 // a) loop-join |
| 1091 // b) [ test ] -> (body-entry-target, loop-exit-target) | 1061 // b) [ test ] -> (body-entry-target, loop-exit-target) |
| 1092 // c) body-entry-target | 1062 // c) body-entry-target |
| 1093 // d) [ body ] -> (continue-join) | 1063 // d) [ body ] -> (continue-join) |
| 1094 // e) continue-join -> (loop-join) | 1064 // e) continue-join -> (loop-join) |
| 1095 // f) loop-exit-target | 1065 // f) loop-exit-target |
| 1096 // g) break-join (optional) | 1066 // g) break-join (optional) |
| 1097 void EffectGraphVisitor::VisitWhileNode(WhileNode* node) { | 1067 void EffectGraphVisitor::VisitWhileNode(WhileNode* node) { |
| 1098 InlineBailout("EffectGraphVisitor::VisitWhileNode"); | |
| 1099 TestGraphVisitor for_test(owner(), | 1068 TestGraphVisitor for_test(owner(), |
| 1100 temp_index(), | 1069 temp_index(), |
| 1101 node->condition()->token_pos()); | 1070 node->condition()->token_pos()); |
| 1102 node->condition()->Visit(&for_test); | 1071 node->condition()->Visit(&for_test); |
| 1103 ASSERT(!for_test.is_empty()); // Language spec. | 1072 ASSERT(!for_test.is_empty()); // Language spec. |
| 1104 | 1073 |
| 1105 EffectGraphVisitor for_body(owner(), temp_index()); | 1074 EffectGraphVisitor for_body(owner(), temp_index()); |
| 1106 for_body.Do( | 1075 for_body.Do( |
| 1107 new CheckStackOverflowComp(node->token_pos())); | 1076 new CheckStackOverflowComp(node->token_pos())); |
| 1108 node->body()->Visit(&for_body); | 1077 node->body()->Visit(&for_body); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1126 | 1095 |
| 1127 // The fragment is composed as follows: | 1096 // The fragment is composed as follows: |
| 1128 // a) body-entry-join | 1097 // a) body-entry-join |
| 1129 // b) [ body ] | 1098 // b) [ body ] |
| 1130 // c) test-entry (continue-join or body-exit-target) | 1099 // c) test-entry (continue-join or body-exit-target) |
| 1131 // d) [ test-entry ] -> (back-target, loop-exit-target) | 1100 // d) [ test-entry ] -> (back-target, loop-exit-target) |
| 1132 // e) back-target -> (body-entry-join) | 1101 // e) back-target -> (body-entry-join) |
| 1133 // f) loop-exit-target | 1102 // f) loop-exit-target |
| 1134 // g) break-join | 1103 // g) break-join |
| 1135 void EffectGraphVisitor::VisitDoWhileNode(DoWhileNode* node) { | 1104 void EffectGraphVisitor::VisitDoWhileNode(DoWhileNode* node) { |
| 1136 InlineBailout("EffectGraphVisitor::VisitDoWhileNode"); | |
| 1137 // Traverse body first in order to generate continue and break labels. | 1105 // Traverse body first in order to generate continue and break labels. |
| 1138 EffectGraphVisitor for_body(owner(), temp_index()); | 1106 EffectGraphVisitor for_body(owner(), temp_index()); |
| 1139 for_body.Do( | 1107 for_body.Do( |
| 1140 new CheckStackOverflowComp(node->token_pos())); | 1108 new CheckStackOverflowComp(node->token_pos())); |
| 1141 node->body()->Visit(&for_body); | 1109 node->body()->Visit(&for_body); |
| 1142 | 1110 |
| 1143 TestGraphVisitor for_test(owner(), | 1111 TestGraphVisitor for_test(owner(), |
| 1144 temp_index(), | 1112 temp_index(), |
| 1145 node->condition()->token_pos()); | 1113 node->condition()->token_pos()); |
| 1146 node->condition()->Visit(&for_test); | 1114 node->condition()->Visit(&for_test); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1182 // a) [ initializer ] | 1150 // a) [ initializer ] |
| 1183 // b) loop-join | 1151 // b) loop-join |
| 1184 // c) [ test ] -> (body-entry-target, loop-exit-target) | 1152 // c) [ test ] -> (body-entry-target, loop-exit-target) |
| 1185 // d) body-entry-target | 1153 // d) body-entry-target |
| 1186 // e) [ body ] | 1154 // e) [ body ] |
| 1187 // f) continue-join (optional) | 1155 // f) continue-join (optional) |
| 1188 // g) [ increment ] -> (loop-join) | 1156 // g) [ increment ] -> (loop-join) |
| 1189 // h) loop-exit-target | 1157 // h) loop-exit-target |
| 1190 // i) break-join | 1158 // i) break-join |
| 1191 void EffectGraphVisitor::VisitForNode(ForNode* node) { | 1159 void EffectGraphVisitor::VisitForNode(ForNode* node) { |
| 1192 InlineBailout("EffectGraphVisitor::VisitForNode"); | |
| 1193 EffectGraphVisitor for_initializer(owner(), temp_index()); | 1160 EffectGraphVisitor for_initializer(owner(), temp_index()); |
| 1194 node->initializer()->Visit(&for_initializer); | 1161 node->initializer()->Visit(&for_initializer); |
| 1195 Append(for_initializer); | 1162 Append(for_initializer); |
| 1196 ASSERT(is_open()); | 1163 ASSERT(is_open()); |
| 1197 | 1164 |
| 1198 // Compose body to set any jump labels. | 1165 // Compose body to set any jump labels. |
| 1199 EffectGraphVisitor for_body(owner(), temp_index()); | 1166 EffectGraphVisitor for_body(owner(), temp_index()); |
| 1200 for_body.Do( | 1167 for_body.Do( |
| 1201 new CheckStackOverflowComp(node->token_pos())); | 1168 new CheckStackOverflowComp(node->token_pos())); |
| 1202 node->body()->Visit(&for_body); | 1169 node->body()->Visit(&for_body); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1255 exit_ = loop_exit; | 1222 exit_ = loop_exit; |
| 1256 } else { | 1223 } else { |
| 1257 loop_exit->Goto(node->label()->join_for_break()); | 1224 loop_exit->Goto(node->label()->join_for_break()); |
| 1258 exit_ = node->label()->join_for_break(); | 1225 exit_ = node->label()->join_for_break(); |
| 1259 } | 1226 } |
| 1260 } | 1227 } |
| 1261 } | 1228 } |
| 1262 | 1229 |
| 1263 | 1230 |
| 1264 void EffectGraphVisitor::VisitJumpNode(JumpNode* node) { | 1231 void EffectGraphVisitor::VisitJumpNode(JumpNode* node) { |
| 1265 InlineBailout("EffectGraphVisitor::VisitJumpNode"); | |
| 1266 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { | 1232 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { |
| 1267 EffectGraphVisitor for_effect(owner(), temp_index()); | 1233 EffectGraphVisitor for_effect(owner(), temp_index()); |
| 1268 node->InlinedFinallyNodeAt(i)->Visit(&for_effect); | 1234 node->InlinedFinallyNodeAt(i)->Visit(&for_effect); |
| 1269 Append(for_effect); | 1235 Append(for_effect); |
| 1270 if (!is_open()) return; | 1236 if (!is_open()) return; |
| 1271 } | 1237 } |
| 1272 | 1238 |
| 1273 // Unchain the context(s) up to the outer context level of the scope which | 1239 // Unchain the context(s) up to the outer context level of the scope which |
| 1274 // contains the destination label. | 1240 // contains the destination label. |
| 1275 SourceLabel* label = node->label(); | 1241 SourceLabel* label = node->label(); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1310 node->label()->set_join_for_continue( | 1276 node->label()->set_join_for_continue( |
| 1311 new JoinEntryInstr(owner()->try_index())); | 1277 new JoinEntryInstr(owner()->try_index())); |
| 1312 } | 1278 } |
| 1313 jump_target = node->label()->join_for_continue(); | 1279 jump_target = node->label()->join_for_continue(); |
| 1314 } | 1280 } |
| 1315 Goto(jump_target); | 1281 Goto(jump_target); |
| 1316 } | 1282 } |
| 1317 | 1283 |
| 1318 | 1284 |
| 1319 void EffectGraphVisitor::VisitArgumentListNode(ArgumentListNode* node) { | 1285 void EffectGraphVisitor::VisitArgumentListNode(ArgumentListNode* node) { |
| 1320 InlineBailout("EffectGraphVisitor::VisitArgumentListNode"); | |
| 1321 UNREACHABLE(); | 1286 UNREACHABLE(); |
| 1322 } | 1287 } |
| 1323 | 1288 |
| 1324 | 1289 |
| 1325 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) { | 1290 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) { |
| 1326 InlineBailout("EffectGraphVisitor::VisitArrayNode"); | |
| 1327 // Translate the array elements and collect their values. | 1291 // Translate the array elements and collect their values. |
| 1328 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1292 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1329 new ZoneGrowableArray<PushArgumentInstr*>(node->length()); | 1293 new ZoneGrowableArray<PushArgumentInstr*>(node->length()); |
| 1330 for (int i = 0; i < node->length(); ++i) { | 1294 for (int i = 0; i < node->length(); ++i) { |
| 1331 ValueGraphVisitor for_value(owner(), temp_index()); | 1295 ValueGraphVisitor for_value(owner(), temp_index()); |
| 1332 node->ElementAt(i)->Visit(&for_value); | 1296 node->ElementAt(i)->Visit(&for_value); |
| 1333 Append(for_value); | 1297 Append(for_value); |
| 1334 arguments->Add(PushArgument(for_value.value())); | 1298 arguments->Add(PushArgument(for_value.value())); |
| 1335 } | 1299 } |
| 1336 const AbstractTypeArguments& type_args = | 1300 const AbstractTypeArguments& type_args = |
| 1337 AbstractTypeArguments::ZoneHandle(node->type().arguments()); | 1301 AbstractTypeArguments::ZoneHandle(node->type().arguments()); |
| 1338 Value* element_type = BuildInstantiatedTypeArguments(node->token_pos(), | 1302 Value* element_type = BuildInstantiatedTypeArguments(node->token_pos(), |
| 1339 type_args); | 1303 type_args); |
| 1340 CreateArrayComp* create = new CreateArrayComp(node->token_pos(), | 1304 CreateArrayComp* create = new CreateArrayComp(node->token_pos(), |
| 1341 arguments, | 1305 arguments, |
| 1342 node->type(), | 1306 node->type(), |
| 1343 element_type); | 1307 element_type); |
| 1344 ReturnComputation(create); | 1308 ReturnComputation(create); |
| 1345 } | 1309 } |
| 1346 | 1310 |
| 1347 | 1311 |
| 1348 void EffectGraphVisitor::VisitClosureNode(ClosureNode* node) { | 1312 void EffectGraphVisitor::VisitClosureNode(ClosureNode* node) { |
| 1349 InlineBailout("EffectGraphVisitor::VisitClosureNode"); | |
| 1350 const Function& function = node->function(); | 1313 const Function& function = node->function(); |
| 1351 | 1314 |
| 1352 Value* receiver = NULL; | 1315 Value* receiver = NULL; |
| 1353 if (function.IsNonImplicitClosureFunction()) { | 1316 if (function.IsNonImplicitClosureFunction()) { |
| 1354 // The context scope may have already been set by the non-optimizing | 1317 // The context scope may have already been set by the non-optimizing |
| 1355 // compiler. If it was not, set it here. | 1318 // compiler. If it was not, set it here. |
| 1356 if (function.context_scope() == ContextScope::null()) { | 1319 if (function.context_scope() == ContextScope::null()) { |
| 1357 const ContextScope& context_scope = ContextScope::ZoneHandle( | 1320 const ContextScope& context_scope = ContextScope::ZoneHandle( |
| 1358 node->scope()->PreserveOuterScope(owner()->context_level())); | 1321 node->scope()->PreserveOuterScope(owner()->context_level())); |
| 1359 ASSERT(!function.HasCode()); | 1322 ASSERT(!function.HasCode()); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1389 } | 1352 } |
| 1390 PushArgumentInstr* push_type_arguments = PushArgument(type_arguments); | 1353 PushArgumentInstr* push_type_arguments = PushArgument(type_arguments); |
| 1391 arguments->Add(push_type_arguments); | 1354 arguments->Add(push_type_arguments); |
| 1392 ReturnComputation(new CreateClosureComp(node, arguments)); | 1355 ReturnComputation(new CreateClosureComp(node, arguments)); |
| 1393 } | 1356 } |
| 1394 | 1357 |
| 1395 | 1358 |
| 1396 void EffectGraphVisitor::TranslateArgumentList( | 1359 void EffectGraphVisitor::TranslateArgumentList( |
| 1397 const ArgumentListNode& node, | 1360 const ArgumentListNode& node, |
| 1398 ZoneGrowableArray<Value*>* values) { | 1361 ZoneGrowableArray<Value*>* values) { |
| 1399 InlineBailout("EffectGraphVisitor::TranslateArgumentList"); | |
| 1400 for (intptr_t i = 0; i < node.length(); ++i) { | 1362 for (intptr_t i = 0; i < node.length(); ++i) { |
| 1401 ValueGraphVisitor for_argument(owner(), temp_index()); | 1363 ValueGraphVisitor for_argument(owner(), temp_index()); |
| 1402 node.NodeAt(i)->Visit(&for_argument); | 1364 node.NodeAt(i)->Visit(&for_argument); |
| 1403 Append(for_argument); | 1365 Append(for_argument); |
| 1404 values->Add(for_argument.value()); | 1366 values->Add(for_argument.value()); |
| 1405 } | 1367 } |
| 1406 } | 1368 } |
| 1407 | 1369 |
| 1408 | 1370 |
| 1409 void EffectGraphVisitor::BuildPushArguments( | 1371 void EffectGraphVisitor::BuildPushArguments( |
| 1410 const ArgumentListNode& node, | 1372 const ArgumentListNode& node, |
| 1411 ZoneGrowableArray<PushArgumentInstr*>* values) { | 1373 ZoneGrowableArray<PushArgumentInstr*>* values) { |
| 1412 InlineBailout("EffectGraphVisitor::BuildPushArguments"); | |
| 1413 for (intptr_t i = 0; i < node.length(); ++i) { | 1374 for (intptr_t i = 0; i < node.length(); ++i) { |
| 1414 ValueGraphVisitor for_argument(owner(), temp_index()); | 1375 ValueGraphVisitor for_argument(owner(), temp_index()); |
| 1415 node.NodeAt(i)->Visit(&for_argument); | 1376 node.NodeAt(i)->Visit(&for_argument); |
| 1416 Append(for_argument); | 1377 Append(for_argument); |
| 1417 PushArgumentInstr* push_arg = PushArgument(for_argument.value()); | 1378 PushArgumentInstr* push_arg = PushArgument(for_argument.value()); |
| 1418 values->Add(push_arg); | 1379 values->Add(push_arg); |
| 1419 } | 1380 } |
| 1420 } | 1381 } |
| 1421 | 1382 |
| 1422 | 1383 |
| 1423 void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) { | 1384 void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) { |
| 1424 InlineBailout("EffectGraphVisitor::VisitInstanceCallNode"); | |
| 1425 ValueGraphVisitor for_receiver(owner(), temp_index()); | 1385 ValueGraphVisitor for_receiver(owner(), temp_index()); |
| 1426 node->receiver()->Visit(&for_receiver); | 1386 node->receiver()->Visit(&for_receiver); |
| 1427 Append(for_receiver); | 1387 Append(for_receiver); |
| 1428 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); | 1388 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); |
| 1429 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1389 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1430 new ZoneGrowableArray<PushArgumentInstr*>( | 1390 new ZoneGrowableArray<PushArgumentInstr*>( |
| 1431 node->arguments()->length() + 1); | 1391 node->arguments()->length() + 1); |
| 1432 arguments->Add(push_receiver); | 1392 arguments->Add(push_receiver); |
| 1433 | 1393 |
| 1434 BuildPushArguments(*node->arguments(), arguments); | 1394 BuildPushArguments(*node->arguments(), arguments); |
| 1435 InstanceCallComp* call = new InstanceCallComp( | 1395 InstanceCallComp* call = new InstanceCallComp( |
| 1436 node->token_pos(), | 1396 node->token_pos(), |
| 1437 node->function_name(), Token::kILLEGAL, arguments, | 1397 node->function_name(), Token::kILLEGAL, arguments, |
| 1438 node->arguments()->names(), 1); | 1398 node->arguments()->names(), 1); |
| 1439 ReturnComputation(call); | 1399 ReturnComputation(call); |
| 1440 } | 1400 } |
| 1441 | 1401 |
| 1442 | 1402 |
| 1443 // <Expression> ::= StaticCall { function: Function | 1403 // <Expression> ::= StaticCall { function: Function |
| 1444 // arguments: <ArgumentList> } | 1404 // arguments: <ArgumentList> } |
| 1445 void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) { | 1405 void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) { |
| 1446 InlineBailout("EffectGraphVisitor::VisitStaticCallNode"); | |
| 1447 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1406 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1448 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); | 1407 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); |
| 1449 BuildPushArguments(*node->arguments(), arguments); | 1408 BuildPushArguments(*node->arguments(), arguments); |
| 1450 StaticCallComp* call = | 1409 StaticCallComp* call = |
| 1451 new StaticCallComp(node->token_pos(), | 1410 new StaticCallComp(node->token_pos(), |
| 1452 node->function(), | 1411 node->function(), |
| 1453 node->arguments()->names(), | 1412 node->arguments()->names(), |
| 1454 arguments); | 1413 arguments); |
| 1455 ReturnComputation(call); | 1414 ReturnComputation(call); |
| 1456 } | 1415 } |
| 1457 | 1416 |
| 1458 | 1417 |
| 1459 ClosureCallComp* EffectGraphVisitor::BuildClosureCall( | 1418 ClosureCallComp* EffectGraphVisitor::BuildClosureCall( |
| 1460 ClosureCallNode* node) { | 1419 ClosureCallNode* node) { |
| 1461 InlineBailout("EffectGraphVisitor::BuildClosureCall"); | |
| 1462 ValueGraphVisitor for_closure(owner(), temp_index()); | 1420 ValueGraphVisitor for_closure(owner(), temp_index()); |
| 1463 node->closure()->Visit(&for_closure); | 1421 node->closure()->Visit(&for_closure); |
| 1464 Append(for_closure); | 1422 Append(for_closure); |
| 1465 PushArgumentInstr* push_closure = PushArgument(for_closure.value()); | 1423 PushArgumentInstr* push_closure = PushArgument(for_closure.value()); |
| 1466 | 1424 |
| 1467 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1425 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1468 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); | 1426 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); |
| 1469 arguments->Add(push_closure); | 1427 arguments->Add(push_closure); |
| 1470 BuildPushArguments(*node->arguments(), arguments); | 1428 BuildPushArguments(*node->arguments(), arguments); |
| 1471 | 1429 |
| 1472 // Save context around the call. | 1430 // Save context around the call. |
| 1473 BuildStoreContext(*owner()->parsed_function().expression_temp_var()); | 1431 BuildStoreContext(*owner()->parsed_function().expression_temp_var()); |
| 1474 return new ClosureCallComp(node, arguments); | 1432 return new ClosureCallComp(node, arguments); |
| 1475 } | 1433 } |
| 1476 | 1434 |
| 1477 | 1435 |
| 1478 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { | 1436 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { |
| 1479 InlineBailout("EffectGraphVisitor::VisitClosureCallNode"); | |
| 1480 Do(BuildClosureCall(node)); | 1437 Do(BuildClosureCall(node)); |
| 1481 // Restore context from saved location. | 1438 // Restore context from saved location. |
| 1482 BuildLoadContext(*owner()->parsed_function().expression_temp_var()); | 1439 BuildLoadContext(*owner()->parsed_function().expression_temp_var()); |
| 1483 } | 1440 } |
| 1484 | 1441 |
| 1485 | 1442 |
| 1486 void ValueGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { | 1443 void ValueGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { |
| 1487 InlineBailout("ValueGraphVisitor::VisitClosureCallNode"); | |
| 1488 Value* result = Bind(BuildClosureCall(node)); | 1444 Value* result = Bind(BuildClosureCall(node)); |
| 1489 // Restore context from temp. | 1445 // Restore context from temp. |
| 1490 BuildLoadContext(*owner()->parsed_function().expression_temp_var()); | 1446 BuildLoadContext(*owner()->parsed_function().expression_temp_var()); |
| 1491 ReturnValue(result); | 1447 ReturnValue(result); |
| 1492 } | 1448 } |
| 1493 | 1449 |
| 1494 | 1450 |
| 1495 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) { | 1451 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) { |
| 1496 InlineBailout("EffectGraphVisitor::VisitCloneContextNode"); | |
| 1497 Value* context = Bind(new CurrentContextComp()); | 1452 Value* context = Bind(new CurrentContextComp()); |
| 1498 Value* clone = Bind(new CloneContextComp(node->token_pos(), context)); | 1453 Value* clone = Bind(new CloneContextComp(node->token_pos(), context)); |
| 1499 ReturnComputation(new StoreContextComp(clone)); | 1454 ReturnComputation(new StoreContextComp(clone)); |
| 1500 } | 1455 } |
| 1501 | 1456 |
| 1502 | 1457 |
| 1503 Value* EffectGraphVisitor::BuildObjectAllocation( | 1458 Value* EffectGraphVisitor::BuildObjectAllocation( |
| 1504 ConstructorCallNode* node) { | 1459 ConstructorCallNode* node) { |
| 1505 InlineBailout("EffectGraphVisitor::BuildObjectAllocation"); | |
| 1506 const Class& cls = Class::ZoneHandle(node->constructor().Owner()); | 1460 const Class& cls = Class::ZoneHandle(node->constructor().Owner()); |
| 1507 const bool requires_type_arguments = cls.HasTypeArguments(); | 1461 const bool requires_type_arguments = cls.HasTypeArguments(); |
| 1508 | 1462 |
| 1509 // In checked mode, if the type arguments are uninstantiated, they may need to | 1463 // In checked mode, if the type arguments are uninstantiated, they may need to |
| 1510 // be checked against declared bounds at run time. | 1464 // be checked against declared bounds at run time. |
| 1511 Computation* allocate_comp = NULL; | 1465 Computation* allocate_comp = NULL; |
| 1512 if (FLAG_enable_type_checks && | 1466 if (FLAG_enable_type_checks && |
| 1513 requires_type_arguments && | 1467 requires_type_arguments && |
| 1514 !node->type_arguments().IsNull() && | 1468 !node->type_arguments().IsNull() && |
| 1515 !node->type_arguments().IsInstantiated() && | 1469 !node->type_arguments().IsInstantiated() && |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1538 | 1492 |
| 1539 allocate_comp = new AllocateObjectComp(node, allocate_arguments); | 1493 allocate_comp = new AllocateObjectComp(node, allocate_arguments); |
| 1540 } | 1494 } |
| 1541 return Bind(allocate_comp); | 1495 return Bind(allocate_comp); |
| 1542 } | 1496 } |
| 1543 | 1497 |
| 1544 | 1498 |
| 1545 void EffectGraphVisitor::BuildConstructorCall( | 1499 void EffectGraphVisitor::BuildConstructorCall( |
| 1546 ConstructorCallNode* node, | 1500 ConstructorCallNode* node, |
| 1547 PushArgumentInstr* push_alloc_value) { | 1501 PushArgumentInstr* push_alloc_value) { |
| 1548 InlineBailout("EffectGraphVisitor::BuildConstructorCall"); | |
| 1549 Value* ctor_arg = Bind( | 1502 Value* ctor_arg = Bind( |
| 1550 new ConstantComp(Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll)))); | 1503 new ConstantComp(Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll)))); |
| 1551 PushArgumentInstr* push_ctor_arg = PushArgument(ctor_arg); | 1504 PushArgumentInstr* push_ctor_arg = PushArgument(ctor_arg); |
| 1552 | 1505 |
| 1553 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1506 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1554 new ZoneGrowableArray<PushArgumentInstr*>(2); | 1507 new ZoneGrowableArray<PushArgumentInstr*>(2); |
| 1555 arguments->Add(push_alloc_value); | 1508 arguments->Add(push_alloc_value); |
| 1556 arguments->Add(push_ctor_arg); | 1509 arguments->Add(push_ctor_arg); |
| 1557 | 1510 |
| 1558 BuildPushArguments(*node->arguments(), arguments); | 1511 BuildPushArguments(*node->arguments(), arguments); |
| 1559 Do(new StaticCallComp(node->token_pos(), | 1512 Do(new StaticCallComp(node->token_pos(), |
| 1560 node->constructor(), | 1513 node->constructor(), |
| 1561 node->arguments()->names(), | 1514 node->arguments()->names(), |
| 1562 arguments)); | 1515 arguments)); |
| 1563 } | 1516 } |
| 1564 | 1517 |
| 1565 | 1518 |
| 1566 void EffectGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { | 1519 void EffectGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { |
| 1567 InlineBailout("EffectGraphVisitor::VisitConstructorCallNode"); | |
| 1568 if (node->constructor().IsFactory()) { | 1520 if (node->constructor().IsFactory()) { |
| 1569 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1521 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1570 new ZoneGrowableArray<PushArgumentInstr*>(); | 1522 new ZoneGrowableArray<PushArgumentInstr*>(); |
| 1571 PushArgumentInstr* push_type_arguments = PushArgument( | 1523 PushArgumentInstr* push_type_arguments = PushArgument( |
| 1572 BuildInstantiatedTypeArguments(node->token_pos(), | 1524 BuildInstantiatedTypeArguments(node->token_pos(), |
| 1573 node->type_arguments())); | 1525 node->type_arguments())); |
| 1574 arguments->Add(push_type_arguments); | 1526 arguments->Add(push_type_arguments); |
| 1575 ASSERT(arguments->length() == 1); | 1527 ASSERT(arguments->length() == 1); |
| 1576 BuildPushArguments(*node->arguments(), arguments); | 1528 BuildPushArguments(*node->arguments(), arguments); |
| 1577 StaticCallComp* call = | 1529 StaticCallComp* call = |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1588 // t_n+2... <- constructor arguments start here | 1540 // t_n+2... <- constructor arguments start here |
| 1589 // StaticCall(constructor, t_n+1, t_n+2, ...) | 1541 // StaticCall(constructor, t_n+1, t_n+2, ...) |
| 1590 // No need to preserve allocated value (simpler than in ValueGraphVisitor). | 1542 // No need to preserve allocated value (simpler than in ValueGraphVisitor). |
| 1591 Value* allocated_value = BuildObjectAllocation(node); | 1543 Value* allocated_value = BuildObjectAllocation(node); |
| 1592 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value); | 1544 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value); |
| 1593 BuildConstructorCall(node, push_allocated_value); | 1545 BuildConstructorCall(node, push_allocated_value); |
| 1594 } | 1546 } |
| 1595 | 1547 |
| 1596 | 1548 |
| 1597 Value* EffectGraphVisitor::BuildInstantiator() { | 1549 Value* EffectGraphVisitor::BuildInstantiator() { |
| 1598 InlineBailout("EffectGraphVisitor::BuildInstantiator"); | |
| 1599 const Class& instantiator_class = Class::Handle( | 1550 const Class& instantiator_class = Class::Handle( |
| 1600 owner()->parsed_function().function().Owner()); | 1551 owner()->parsed_function().function().Owner()); |
| 1601 if (instantiator_class.NumTypeParameters() == 0) { | 1552 if (instantiator_class.NumTypeParameters() == 0) { |
| 1602 return NULL; | 1553 return NULL; |
| 1603 } | 1554 } |
| 1604 Function& outer_function = | 1555 Function& outer_function = |
| 1605 Function::Handle(owner()->parsed_function().function().raw()); | 1556 Function::Handle(owner()->parsed_function().function().raw()); |
| 1606 while (outer_function.IsLocalFunction()) { | 1557 while (outer_function.IsLocalFunction()) { |
| 1607 outer_function = outer_function.parent_function(); | 1558 outer_function = outer_function.parent_function(); |
| 1608 } | 1559 } |
| 1609 if (outer_function.IsFactory()) { | 1560 if (outer_function.IsFactory()) { |
| 1610 return NULL; | 1561 return NULL; |
| 1611 } | 1562 } |
| 1612 | 1563 |
| 1613 ASSERT(owner()->parsed_function().instantiator() != NULL); | 1564 ASSERT(owner()->parsed_function().instantiator() != NULL); |
| 1614 ValueGraphVisitor for_instantiator(owner(), temp_index()); | 1565 ValueGraphVisitor for_instantiator(owner(), temp_index()); |
| 1615 owner()->parsed_function().instantiator()->Visit(&for_instantiator); | 1566 owner()->parsed_function().instantiator()->Visit(&for_instantiator); |
| 1616 Append(for_instantiator); | 1567 Append(for_instantiator); |
| 1617 return for_instantiator.value(); | 1568 return for_instantiator.value(); |
| 1618 } | 1569 } |
| 1619 | 1570 |
| 1620 | 1571 |
| 1621 // 'expression_temp_var' may not be used inside this method if 'instantiator' | 1572 // 'expression_temp_var' may not be used inside this method if 'instantiator' |
| 1622 // is not NULL. | 1573 // is not NULL. |
| 1623 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments( | 1574 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments( |
| 1624 intptr_t token_pos, Value* instantiator) { | 1575 intptr_t token_pos, Value* instantiator) { |
| 1625 InlineBailout("EffectGraphVisitor::BuildInstantiatorTypeArguments"); | |
| 1626 const Class& instantiator_class = Class::Handle( | 1576 const Class& instantiator_class = Class::Handle( |
| 1627 owner()->parsed_function().function().Owner()); | 1577 owner()->parsed_function().function().Owner()); |
| 1628 if (instantiator_class.NumTypeParameters() == 0) { | 1578 if (instantiator_class.NumTypeParameters() == 0) { |
| 1629 // The type arguments are compile time constants. | 1579 // The type arguments are compile time constants. |
| 1630 AbstractTypeArguments& type_arguments = AbstractTypeArguments::ZoneHandle(); | 1580 AbstractTypeArguments& type_arguments = AbstractTypeArguments::ZoneHandle(); |
| 1631 // Type is temporary. Only its type arguments are preserved. | 1581 // Type is temporary. Only its type arguments are preserved. |
| 1632 Type& type = Type::Handle( | 1582 Type& type = Type::Handle( |
| 1633 Type::New(instantiator_class, type_arguments, token_pos, Heap::kNew)); | 1583 Type::New(instantiator_class, type_arguments, token_pos, Heap::kNew)); |
| 1634 type ^= ClassFinalizer::FinalizeType( | 1584 type ^= ClassFinalizer::FinalizeType( |
| 1635 instantiator_class, type, ClassFinalizer::kFinalize); | 1585 instantiator_class, type, ClassFinalizer::kFinalize); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1666 return Bind(new LoadVMFieldComp( | 1616 return Bind(new LoadVMFieldComp( |
| 1667 instantiator, | 1617 instantiator, |
| 1668 type_arguments_instance_field_offset, | 1618 type_arguments_instance_field_offset, |
| 1669 Type::ZoneHandle())); // Not an instance, no type. | 1619 Type::ZoneHandle())); // Not an instance, no type. |
| 1670 } | 1620 } |
| 1671 | 1621 |
| 1672 | 1622 |
| 1673 Value* EffectGraphVisitor::BuildInstantiatedTypeArguments( | 1623 Value* EffectGraphVisitor::BuildInstantiatedTypeArguments( |
| 1674 intptr_t token_pos, | 1624 intptr_t token_pos, |
| 1675 const AbstractTypeArguments& type_arguments) { | 1625 const AbstractTypeArguments& type_arguments) { |
| 1676 InlineBailout("EffectGraphVisitor::BuildInstantiatedTypeArguments"); | |
| 1677 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) { | 1626 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) { |
| 1678 return Bind(new ConstantComp(type_arguments)); | 1627 return Bind(new ConstantComp(type_arguments)); |
| 1679 } | 1628 } |
| 1680 // The type arguments are uninstantiated. | 1629 // The type arguments are uninstantiated. |
| 1681 Value* instantiator_value = | 1630 Value* instantiator_value = |
| 1682 BuildInstantiatorTypeArguments(token_pos, NULL); | 1631 BuildInstantiatorTypeArguments(token_pos, NULL); |
| 1683 return Bind(new InstantiateTypeArgumentsComp(token_pos, | 1632 return Bind(new InstantiateTypeArgumentsComp(token_pos, |
| 1684 type_arguments, | 1633 type_arguments, |
| 1685 instantiator_value)); | 1634 instantiator_value)); |
| 1686 } | 1635 } |
| 1687 | 1636 |
| 1688 | 1637 |
| 1689 void EffectGraphVisitor::BuildConstructorTypeArguments( | 1638 void EffectGraphVisitor::BuildConstructorTypeArguments( |
| 1690 ConstructorCallNode* node, | 1639 ConstructorCallNode* node, |
| 1691 Value** type_arguments, | 1640 Value** type_arguments, |
| 1692 Value** instantiator, | 1641 Value** instantiator, |
| 1693 ZoneGrowableArray<PushArgumentInstr*>* call_arguments) { | 1642 ZoneGrowableArray<PushArgumentInstr*>* call_arguments) { |
| 1694 InlineBailout("EffectGraphVisitor::BuildConstructorTypeArguments"); | |
| 1695 const Class& cls = Class::ZoneHandle(node->constructor().Owner()); | 1643 const Class& cls = Class::ZoneHandle(node->constructor().Owner()); |
| 1696 ASSERT(cls.HasTypeArguments() && !node->constructor().IsFactory()); | 1644 ASSERT(cls.HasTypeArguments() && !node->constructor().IsFactory()); |
| 1697 if (node->type_arguments().IsNull() || | 1645 if (node->type_arguments().IsNull() || |
| 1698 node->type_arguments().IsInstantiated()) { | 1646 node->type_arguments().IsInstantiated()) { |
| 1699 Value* type_arguments_val = Bind(new ConstantComp(node->type_arguments())); | 1647 Value* type_arguments_val = Bind(new ConstantComp(node->type_arguments())); |
| 1700 if (call_arguments != NULL) { | 1648 if (call_arguments != NULL) { |
| 1701 ASSERT(type_arguments == NULL); | 1649 ASSERT(type_arguments == NULL); |
| 1702 call_arguments->Add(PushArgument(type_arguments_val)); | 1650 call_arguments->Add(PushArgument(type_arguments_val)); |
| 1703 } else { | 1651 } else { |
| 1704 ASSERT(type_arguments != NULL); | 1652 ASSERT(type_arguments != NULL); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1764 ASSERT(instantiator == NULL); | 1712 ASSERT(instantiator == NULL); |
| 1765 call_arguments->Add(PushArgument(instantiator_val)); | 1713 call_arguments->Add(PushArgument(instantiator_val)); |
| 1766 } else { | 1714 } else { |
| 1767 ASSERT(instantiator != NULL); | 1715 ASSERT(instantiator != NULL); |
| 1768 *instantiator = instantiator_val; | 1716 *instantiator = instantiator_val; |
| 1769 } | 1717 } |
| 1770 } | 1718 } |
| 1771 | 1719 |
| 1772 | 1720 |
| 1773 void ValueGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { | 1721 void ValueGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { |
| 1774 InlineBailout("ValueGraphVisitor::VisitConstructorCallNode"); | |
| 1775 if (node->constructor().IsFactory()) { | 1722 if (node->constructor().IsFactory()) { |
| 1776 EffectGraphVisitor::VisitConstructorCallNode(node); | 1723 EffectGraphVisitor::VisitConstructorCallNode(node); |
| 1777 return; | 1724 return; |
| 1778 } | 1725 } |
| 1779 | 1726 |
| 1780 // t_n contains the allocated and initialized object. | 1727 // t_n contains the allocated and initialized object. |
| 1781 // t_n <- AllocateObject(class) | 1728 // t_n <- AllocateObject(class) |
| 1782 // t_n <- StoreLocal(temp, t_n); | 1729 // t_n <- StoreLocal(temp, t_n); |
| 1783 // t_n+1 <- ctor-arg | 1730 // t_n+1 <- ctor-arg |
| 1784 // t_n+2... <- constructor arguments start here | 1731 // t_n+2... <- constructor arguments start here |
| 1785 // StaticCall(constructor, t_n, t_n+1, ...) | 1732 // StaticCall(constructor, t_n, t_n+1, ...) |
| 1786 // tn <- LoadLocal(temp) | 1733 // tn <- LoadLocal(temp) |
| 1787 | 1734 |
| 1788 Value* allocate = BuildObjectAllocation(node); | 1735 Value* allocate = BuildObjectAllocation(node); |
| 1789 Computation* store_allocated = BuildStoreLocal( | 1736 Computation* store_allocated = BuildStoreLocal( |
| 1790 node->allocated_object_var(), | 1737 node->allocated_object_var(), |
| 1791 allocate); | 1738 allocate); |
| 1792 Value* allocated_value = Bind(store_allocated); | 1739 Value* allocated_value = Bind(store_allocated); |
| 1793 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value); | 1740 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value); |
| 1794 BuildConstructorCall(node, push_allocated_value); | 1741 BuildConstructorCall(node, push_allocated_value); |
| 1795 Computation* load_allocated = BuildLoadLocal( | 1742 Computation* load_allocated = BuildLoadLocal( |
| 1796 node->allocated_object_var()); | 1743 node->allocated_object_var()); |
| 1797 allocated_value = Bind(load_allocated); | 1744 allocated_value = Bind(load_allocated); |
| 1798 ReturnValue(allocated_value); | 1745 ReturnValue(allocated_value); |
| 1799 } | 1746 } |
| 1800 | 1747 |
| 1801 | 1748 |
| 1802 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) { | 1749 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) { |
| 1803 InlineBailout("EffectGraphVisitor::VisitConstructorCallNode"); | |
| 1804 ValueGraphVisitor for_receiver(owner(), temp_index()); | 1750 ValueGraphVisitor for_receiver(owner(), temp_index()); |
| 1805 node->receiver()->Visit(&for_receiver); | 1751 node->receiver()->Visit(&for_receiver); |
| 1806 Append(for_receiver); | 1752 Append(for_receiver); |
| 1807 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); | 1753 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); |
| 1808 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1754 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1809 new ZoneGrowableArray<PushArgumentInstr*>(1); | 1755 new ZoneGrowableArray<PushArgumentInstr*>(1); |
| 1810 arguments->Add(push_receiver); | 1756 arguments->Add(push_receiver); |
| 1811 const String& name = | 1757 const String& name = |
| 1812 String::ZoneHandle(Field::GetterSymbol(node->field_name())); | 1758 String::ZoneHandle(Field::GetterSymbol(node->field_name())); |
| 1813 InstanceCallComp* call = new InstanceCallComp( | 1759 InstanceCallComp* call = new InstanceCallComp( |
| 1814 node->token_pos(), name, Token::kGET, | 1760 node->token_pos(), name, Token::kGET, |
| 1815 arguments, Array::ZoneHandle(), 1); | 1761 arguments, Array::ZoneHandle(), 1); |
| 1816 ReturnComputation(call); | 1762 ReturnComputation(call); |
| 1817 } | 1763 } |
| 1818 | 1764 |
| 1819 | 1765 |
| 1820 void EffectGraphVisitor::BuildInstanceSetterArguments( | 1766 void EffectGraphVisitor::BuildInstanceSetterArguments( |
| 1821 InstanceSetterNode* node, | 1767 InstanceSetterNode* node, |
| 1822 ZoneGrowableArray<PushArgumentInstr*>* arguments, | 1768 ZoneGrowableArray<PushArgumentInstr*>* arguments, |
| 1823 bool result_is_needed) { | 1769 bool result_is_needed) { |
| 1824 InlineBailout("EffectGraphVisitor::BuildInstanceSetterArguments"); | |
| 1825 ValueGraphVisitor for_receiver(owner(), temp_index()); | 1770 ValueGraphVisitor for_receiver(owner(), temp_index()); |
| 1826 node->receiver()->Visit(&for_receiver); | 1771 node->receiver()->Visit(&for_receiver); |
| 1827 Append(for_receiver); | 1772 Append(for_receiver); |
| 1828 arguments->Add(PushArgument(for_receiver.value())); | 1773 arguments->Add(PushArgument(for_receiver.value())); |
| 1829 | 1774 |
| 1830 ValueGraphVisitor for_value(owner(), temp_index()); | 1775 ValueGraphVisitor for_value(owner(), temp_index()); |
| 1831 node->value()->Visit(&for_value); | 1776 node->value()->Visit(&for_value); |
| 1832 Append(for_value); | 1777 Append(for_value); |
| 1833 | 1778 |
| 1834 Value* value = NULL; | 1779 Value* value = NULL; |
| 1835 if (result_is_needed) { | 1780 if (result_is_needed) { |
| 1836 value = Bind( | 1781 value = Bind( |
| 1837 BuildStoreLocal(*owner()->parsed_function().expression_temp_var(), | 1782 BuildStoreLocal(*owner()->parsed_function().expression_temp_var(), |
| 1838 for_value.value())); | 1783 for_value.value())); |
| 1839 } else { | 1784 } else { |
| 1840 value = for_value.value(); | 1785 value = for_value.value(); |
| 1841 } | 1786 } |
| 1842 arguments->Add(PushArgument(value)); | 1787 arguments->Add(PushArgument(value)); |
| 1843 } | 1788 } |
| 1844 | 1789 |
| 1845 | 1790 |
| 1846 void EffectGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { | 1791 void EffectGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { |
| 1847 InlineBailout("EffectGraphVisitor::VisitInstanceSetterNode"); | |
| 1848 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1792 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1849 new ZoneGrowableArray<PushArgumentInstr*>(2); | 1793 new ZoneGrowableArray<PushArgumentInstr*>(2); |
| 1850 BuildInstanceSetterArguments(node, arguments, false); // Value not used. | 1794 BuildInstanceSetterArguments(node, arguments, false); // Value not used. |
| 1851 const String& name = | 1795 const String& name = |
| 1852 String::ZoneHandle(Field::SetterSymbol(node->field_name())); | 1796 String::ZoneHandle(Field::SetterSymbol(node->field_name())); |
| 1853 InstanceCallComp* call = new InstanceCallComp(node->token_pos(), | 1797 InstanceCallComp* call = new InstanceCallComp(node->token_pos(), |
| 1854 name, | 1798 name, |
| 1855 Token::kSET, | 1799 Token::kSET, |
| 1856 arguments, | 1800 arguments, |
| 1857 Array::ZoneHandle(), | 1801 Array::ZoneHandle(), |
| 1858 1); // Checked argument count. | 1802 1); // Checked argument count. |
| 1859 ReturnComputation(call); | 1803 ReturnComputation(call); |
| 1860 } | 1804 } |
| 1861 | 1805 |
| 1862 | 1806 |
| 1863 void ValueGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { | 1807 void ValueGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { |
| 1864 InlineBailout("ValueGraphVisitor::VisitInstanceSetterNode"); | |
| 1865 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1808 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1866 new ZoneGrowableArray<PushArgumentInstr*>(2); | 1809 new ZoneGrowableArray<PushArgumentInstr*>(2); |
| 1867 BuildInstanceSetterArguments(node, arguments, true); // Value used. | 1810 BuildInstanceSetterArguments(node, arguments, true); // Value used. |
| 1868 const String& name = | 1811 const String& name = |
| 1869 String::ZoneHandle(Field::SetterSymbol(node->field_name())); | 1812 String::ZoneHandle(Field::SetterSymbol(node->field_name())); |
| 1870 Do(new InstanceCallComp(node->token_pos(), | 1813 Do(new InstanceCallComp(node->token_pos(), |
| 1871 name, | 1814 name, |
| 1872 Token::kSET, | 1815 Token::kSET, |
| 1873 arguments, | 1816 arguments, |
| 1874 Array::ZoneHandle(), | 1817 Array::ZoneHandle(), |
| 1875 1)); // Checked argument count. | 1818 1)); // Checked argument count. |
| 1876 ReturnComputation( | 1819 ReturnComputation( |
| 1877 BuildLoadLocal(*owner()->parsed_function().expression_temp_var())); | 1820 BuildLoadLocal(*owner()->parsed_function().expression_temp_var())); |
| 1878 } | 1821 } |
| 1879 | 1822 |
| 1880 | 1823 |
| 1881 void EffectGraphVisitor::VisitStaticGetterNode(StaticGetterNode* node) { | 1824 void EffectGraphVisitor::VisitStaticGetterNode(StaticGetterNode* node) { |
| 1882 InlineBailout("EffectGraphVisitor::VisitStaticGetterNode"); | |
| 1883 const String& getter_name = | 1825 const String& getter_name = |
| 1884 String::Handle(Field::GetterName(node->field_name())); | 1826 String::Handle(Field::GetterName(node->field_name())); |
| 1885 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1827 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1886 new ZoneGrowableArray<PushArgumentInstr*>(); | 1828 new ZoneGrowableArray<PushArgumentInstr*>(); |
| 1887 Function& getter_function = Function::ZoneHandle(); | 1829 Function& getter_function = Function::ZoneHandle(); |
| 1888 if (node->is_super_getter()) { | 1830 if (node->is_super_getter()) { |
| 1889 // Statically resolved instance getter, i.e. "super getter". | 1831 // Statically resolved instance getter, i.e. "super getter". |
| 1890 getter_function = | 1832 getter_function = |
| 1891 Resolver::ResolveDynamicAnyArgs(node->cls(), getter_name); | 1833 Resolver::ResolveDynamicAnyArgs(node->cls(), getter_name); |
| 1892 ASSERT(!getter_function.IsNull()); | 1834 ASSERT(!getter_function.IsNull()); |
| 1893 ASSERT(node->receiver() != NULL); | 1835 ASSERT(node->receiver() != NULL); |
| 1894 ValueGraphVisitor receiver_value(owner(), temp_index()); | 1836 ValueGraphVisitor receiver_value(owner(), temp_index()); |
| 1895 node->receiver()->Visit(&receiver_value); | 1837 node->receiver()->Visit(&receiver_value); |
| 1896 Append(receiver_value); | 1838 Append(receiver_value); |
| 1897 arguments->Add(PushArgument(receiver_value.value())); | 1839 arguments->Add(PushArgument(receiver_value.value())); |
| 1898 } else { | 1840 } else { |
| 1899 getter_function = node->cls().LookupStaticFunction(getter_name); | 1841 getter_function = node->cls().LookupStaticFunction(getter_name); |
| 1900 ASSERT(!getter_function.IsNull()); | 1842 ASSERT(!getter_function.IsNull()); |
| 1901 } | 1843 } |
| 1902 StaticCallComp* call = new StaticCallComp(node->token_pos(), | 1844 StaticCallComp* call = new StaticCallComp(node->token_pos(), |
| 1903 getter_function, | 1845 getter_function, |
| 1904 Array::ZoneHandle(), // No names. | 1846 Array::ZoneHandle(), // No names. |
| 1905 arguments); | 1847 arguments); |
| 1906 ReturnComputation(call); | 1848 ReturnComputation(call); |
| 1907 } | 1849 } |
| 1908 | 1850 |
| 1909 | 1851 |
| 1910 void EffectGraphVisitor::BuildStaticSetter(StaticSetterNode* node, | 1852 void EffectGraphVisitor::BuildStaticSetter(StaticSetterNode* node, |
| 1911 bool result_is_needed) { | 1853 bool result_is_needed) { |
| 1912 InlineBailout("EffectGraphVisitor::BuildStaticSetter"); | |
| 1913 const String& setter_name = | 1854 const String& setter_name = |
| 1914 String::Handle(Field::SetterName(node->field_name())); | 1855 String::Handle(Field::SetterName(node->field_name())); |
| 1915 // A super setter is an instance setter whose setter function is | 1856 // A super setter is an instance setter whose setter function is |
| 1916 // resolved at compile time (in the caller instance getter's super class). | 1857 // resolved at compile time (in the caller instance getter's super class). |
| 1917 // Unlike a static getter, a super getter has a receiver parameter. | 1858 // Unlike a static getter, a super getter has a receiver parameter. |
| 1918 const bool is_super_setter = (node->receiver() != NULL); | 1859 const bool is_super_setter = (node->receiver() != NULL); |
| 1919 const Function& setter_function = | 1860 const Function& setter_function = |
| 1920 Function::ZoneHandle(is_super_setter | 1861 Function::ZoneHandle(is_super_setter |
| 1921 ? Resolver::ResolveDynamicAnyArgs(node->cls(), setter_name) | 1862 ? Resolver::ResolveDynamicAnyArgs(node->cls(), setter_name) |
| 1922 : node->cls().LookupStaticFunction(setter_name)); | 1863 : node->cls().LookupStaticFunction(setter_name)); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1952 Do(call); | 1893 Do(call); |
| 1953 ReturnComputation( | 1894 ReturnComputation( |
| 1954 BuildLoadLocal(*owner()->parsed_function().expression_temp_var())); | 1895 BuildLoadLocal(*owner()->parsed_function().expression_temp_var())); |
| 1955 } else { | 1896 } else { |
| 1956 ReturnComputation(call); | 1897 ReturnComputation(call); |
| 1957 } | 1898 } |
| 1958 } | 1899 } |
| 1959 | 1900 |
| 1960 | 1901 |
| 1961 void EffectGraphVisitor::VisitStaticSetterNode(StaticSetterNode* node) { | 1902 void EffectGraphVisitor::VisitStaticSetterNode(StaticSetterNode* node) { |
| 1962 InlineBailout("EffectGraphVisitor::VisitStaticSetterNode"); | |
| 1963 BuildStaticSetter(node, false); // Result not needed. | 1903 BuildStaticSetter(node, false); // Result not needed. |
| 1964 } | 1904 } |
| 1965 | 1905 |
| 1966 | 1906 |
| 1967 void ValueGraphVisitor::VisitStaticSetterNode(StaticSetterNode* node) { | 1907 void ValueGraphVisitor::VisitStaticSetterNode(StaticSetterNode* node) { |
| 1968 InlineBailout("ValueGraphVisitor::VisitStaticSetterNode"); | |
| 1969 BuildStaticSetter(node, true); // Result needed. | 1908 BuildStaticSetter(node, true); // Result needed. |
| 1970 } | 1909 } |
| 1971 | 1910 |
| 1972 | 1911 |
| 1973 void EffectGraphVisitor::VisitNativeBodyNode(NativeBodyNode* node) { | 1912 void EffectGraphVisitor::VisitNativeBodyNode(NativeBodyNode* node) { |
| 1974 InlineBailout("EffectGraphVisitor::VisitNativeBodyNode"); | |
| 1975 NativeCallComp* native_call = new NativeCallComp(node); | 1913 NativeCallComp* native_call = new NativeCallComp(node); |
| 1976 ReturnComputation(native_call); | 1914 ReturnComputation(native_call); |
| 1977 } | 1915 } |
| 1978 | 1916 |
| 1979 | 1917 |
| 1980 void EffectGraphVisitor::VisitPrimaryNode(PrimaryNode* node) { | 1918 void EffectGraphVisitor::VisitPrimaryNode(PrimaryNode* node) { |
| 1981 InlineBailout("EffectGraphVisitor::VisitPrimaryNode"); | |
| 1982 // PrimaryNodes are temporary during parsing. | 1919 // PrimaryNodes are temporary during parsing. |
| 1983 UNREACHABLE(); | 1920 UNREACHABLE(); |
| 1984 } | 1921 } |
| 1985 | 1922 |
| 1986 | 1923 |
| 1987 // <Expression> ::= LoadLocal { local: LocalVariable } | 1924 // <Expression> ::= LoadLocal { local: LocalVariable } |
| 1988 void EffectGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) { | 1925 void EffectGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) { |
| 1989 InlineBailout("EffectGraphVisitor::VisitLoadLocalNode"); | |
| 1990 if (node->HasPseudo()) { | 1926 if (node->HasPseudo()) { |
| 1991 EffectGraphVisitor for_pseudo(owner(), temp_index()); | 1927 EffectGraphVisitor for_pseudo(owner(), temp_index()); |
| 1992 node->pseudo()->Visit(&for_pseudo); | 1928 node->pseudo()->Visit(&for_pseudo); |
| 1993 Append(for_pseudo); | 1929 Append(for_pseudo); |
| 1994 } | 1930 } |
| 1995 } | 1931 } |
| 1996 | 1932 |
| 1997 | 1933 |
| 1998 void ValueGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) { | 1934 void ValueGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) { |
| 1999 InlineBailout("ValueGraphVisitor::VisitLoadLocalNode"); | |
| 2000 EffectGraphVisitor::VisitLoadLocalNode(node); | 1935 EffectGraphVisitor::VisitLoadLocalNode(node); |
| 2001 Computation* load = BuildLoadLocal(node->local()); | 1936 Computation* load = BuildLoadLocal(node->local()); |
| 2002 ReturnComputation(load); | 1937 ReturnComputation(load); |
| 2003 } | 1938 } |
| 2004 | 1939 |
| 2005 | 1940 |
| 2006 // <Expression> ::= StoreLocal { local: LocalVariable | 1941 // <Expression> ::= StoreLocal { local: LocalVariable |
| 2007 // value: <Expression> } | 1942 // value: <Expression> } |
| 2008 void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) { | 1943 void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) { |
| 2009 InlineBailout("EffectGraphVisitor::VisitStoreLocalNode"); | |
| 2010 ValueGraphVisitor for_value(owner(), temp_index()); | 1944 ValueGraphVisitor for_value(owner(), temp_index()); |
| 2011 node->value()->Visit(&for_value); | 1945 node->value()->Visit(&for_value); |
| 2012 Append(for_value); | 1946 Append(for_value); |
| 2013 Value* store_value = for_value.value(); | 1947 Value* store_value = for_value.value(); |
| 2014 if (FLAG_enable_type_checks) { | 1948 if (FLAG_enable_type_checks) { |
| 2015 store_value = BuildAssignableValue(node->value()->token_pos(), | 1949 store_value = BuildAssignableValue(node->value()->token_pos(), |
| 2016 store_value, | 1950 store_value, |
| 2017 node->local().type(), | 1951 node->local().type(), |
| 2018 node->local().name()); | 1952 node->local().name()); |
| 2019 } | 1953 } |
| 2020 Computation* store = BuildStoreLocal(node->local(), store_value); | 1954 Computation* store = BuildStoreLocal(node->local(), store_value); |
| 2021 ReturnComputation(store); | 1955 ReturnComputation(store); |
| 2022 } | 1956 } |
| 2023 | 1957 |
| 2024 | 1958 |
| 2025 void EffectGraphVisitor::VisitLoadInstanceFieldNode( | 1959 void EffectGraphVisitor::VisitLoadInstanceFieldNode( |
| 2026 LoadInstanceFieldNode* node) { | 1960 LoadInstanceFieldNode* node) { |
| 2027 InlineBailout("EffectGraphVisitor::VisitLoadInstanceFieldNode"); | |
| 2028 ValueGraphVisitor for_instance(owner(), temp_index()); | 1961 ValueGraphVisitor for_instance(owner(), temp_index()); |
| 2029 node->instance()->Visit(&for_instance); | 1962 node->instance()->Visit(&for_instance); |
| 2030 Append(for_instance); | 1963 Append(for_instance); |
| 2031 LoadInstanceFieldComp* load = new LoadInstanceFieldComp( | 1964 LoadInstanceFieldComp* load = new LoadInstanceFieldComp( |
| 2032 node->field(), for_instance.value()); | 1965 node->field(), for_instance.value()); |
| 2033 ReturnComputation(load); | 1966 ReturnComputation(load); |
| 2034 } | 1967 } |
| 2035 | 1968 |
| 2036 | 1969 |
| 2037 void EffectGraphVisitor::VisitStoreInstanceFieldNode( | 1970 void EffectGraphVisitor::VisitStoreInstanceFieldNode( |
| 2038 StoreInstanceFieldNode* node) { | 1971 StoreInstanceFieldNode* node) { |
| 2039 InlineBailout("EffectGraphVisitor::VisitStoreInstanceFieldNode"); | |
| 2040 ValueGraphVisitor for_instance(owner(), temp_index()); | 1972 ValueGraphVisitor for_instance(owner(), temp_index()); |
| 2041 node->instance()->Visit(&for_instance); | 1973 node->instance()->Visit(&for_instance); |
| 2042 Append(for_instance); | 1974 Append(for_instance); |
| 2043 ValueGraphVisitor for_value(owner(), for_instance.temp_index()); | 1975 ValueGraphVisitor for_value(owner(), for_instance.temp_index()); |
| 2044 node->value()->Visit(&for_value); | 1976 node->value()->Visit(&for_value); |
| 2045 Append(for_value); | 1977 Append(for_value); |
| 2046 Value* store_value = for_value.value(); | 1978 Value* store_value = for_value.value(); |
| 2047 if (FLAG_enable_type_checks) { | 1979 if (FLAG_enable_type_checks) { |
| 2048 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); | 1980 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); |
| 2049 const String& dst_name = String::ZoneHandle(node->field().name()); | 1981 const String& dst_name = String::ZoneHandle(node->field().name()); |
| 2050 store_value = BuildAssignableValue(node->value()->token_pos(), | 1982 store_value = BuildAssignableValue(node->value()->token_pos(), |
| 2051 store_value, | 1983 store_value, |
| 2052 type, | 1984 type, |
| 2053 dst_name); | 1985 dst_name); |
| 2054 } | 1986 } |
| 2055 StoreInstanceFieldComp* store = new StoreInstanceFieldComp( | 1987 StoreInstanceFieldComp* store = new StoreInstanceFieldComp( |
| 2056 node->field(), for_instance.value(), store_value); | 1988 node->field(), for_instance.value(), store_value); |
| 2057 ReturnComputation(store); | 1989 ReturnComputation(store); |
| 2058 } | 1990 } |
| 2059 | 1991 |
| 2060 | 1992 |
| 2061 // StoreInstanceFieldNode does not return result. | 1993 // StoreInstanceFieldNode does not return result. |
| 2062 void ValueGraphVisitor::VisitStoreInstanceFieldNode( | 1994 void ValueGraphVisitor::VisitStoreInstanceFieldNode( |
| 2063 StoreInstanceFieldNode* node) { | 1995 StoreInstanceFieldNode* node) { |
| 2064 InlineBailout("ValueGraphVisitor::VisitStoreInstanceFieldNode"); | |
| 2065 UNIMPLEMENTED(); | 1996 UNIMPLEMENTED(); |
| 2066 } | 1997 } |
| 2067 | 1998 |
| 2068 | 1999 |
| 2069 void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) { | 2000 void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) { |
| 2070 InlineBailout("EffectGraphVisitor::VisitLoadStaticFieldNode"); | |
| 2071 LoadStaticFieldComp* load = new LoadStaticFieldComp(node->field()); | 2001 LoadStaticFieldComp* load = new LoadStaticFieldComp(node->field()); |
| 2072 ReturnComputation(load); | 2002 ReturnComputation(load); |
| 2073 } | 2003 } |
| 2074 | 2004 |
| 2075 | 2005 |
| 2076 void EffectGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) { | 2006 void EffectGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) { |
| 2077 InlineBailout("EffectGraphVisitor::VisitStoreStaticFieldNode"); | |
| 2078 ValueGraphVisitor for_value(owner(), temp_index()); | 2007 ValueGraphVisitor for_value(owner(), temp_index()); |
| 2079 node->value()->Visit(&for_value); | 2008 node->value()->Visit(&for_value); |
| 2080 Append(for_value); | 2009 Append(for_value); |
| 2081 Value* store_value = for_value.value(); | 2010 Value* store_value = for_value.value(); |
| 2082 if (FLAG_enable_type_checks) { | 2011 if (FLAG_enable_type_checks) { |
| 2083 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); | 2012 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); |
| 2084 const String& dst_name = String::ZoneHandle(node->field().name()); | 2013 const String& dst_name = String::ZoneHandle(node->field().name()); |
| 2085 store_value = BuildAssignableValue(node->value()->token_pos(), | 2014 store_value = BuildAssignableValue(node->value()->token_pos(), |
| 2086 store_value, | 2015 store_value, |
| 2087 type, | 2016 type, |
| 2088 dst_name); | 2017 dst_name); |
| 2089 } | 2018 } |
| 2090 StoreStaticFieldComp* store = | 2019 StoreStaticFieldComp* store = |
| 2091 new StoreStaticFieldComp(node->field(), store_value); | 2020 new StoreStaticFieldComp(node->field(), store_value); |
| 2092 ReturnComputation(store); | 2021 ReturnComputation(store); |
| 2093 } | 2022 } |
| 2094 | 2023 |
| 2095 | 2024 |
| 2096 void EffectGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) { | 2025 void EffectGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) { |
| 2097 InlineBailout("EffectGraphVisitor::VisitLoadIndexedNode"); | |
| 2098 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2026 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 2099 new ZoneGrowableArray<PushArgumentInstr*>(2); | 2027 new ZoneGrowableArray<PushArgumentInstr*>(2); |
| 2100 ValueGraphVisitor for_array(owner(), temp_index()); | 2028 ValueGraphVisitor for_array(owner(), temp_index()); |
| 2101 node->array()->Visit(&for_array); | 2029 node->array()->Visit(&for_array); |
| 2102 Append(for_array); | 2030 Append(for_array); |
| 2103 arguments->Add(PushArgument(for_array.value())); | 2031 arguments->Add(PushArgument(for_array.value())); |
| 2104 | 2032 |
| 2105 ValueGraphVisitor for_index(owner(), temp_index()); | 2033 ValueGraphVisitor for_index(owner(), temp_index()); |
| 2106 node->index_expr()->Visit(&for_index); | 2034 node->index_expr()->Visit(&for_index); |
| 2107 Append(for_index); | 2035 Append(for_index); |
| 2108 arguments->Add(PushArgument(for_index.value())); | 2036 arguments->Add(PushArgument(for_index.value())); |
| 2109 | 2037 |
| 2110 const intptr_t checked_argument_count = 1; | 2038 const intptr_t checked_argument_count = 1; |
| 2111 const String& name = | 2039 const String& name = |
| 2112 String::ZoneHandle(Symbols::New(Token::Str(Token::kINDEX))); | 2040 String::ZoneHandle(Symbols::New(Token::Str(Token::kINDEX))); |
| 2113 InstanceCallComp* load = new InstanceCallComp(node->token_pos(), | 2041 InstanceCallComp* load = new InstanceCallComp(node->token_pos(), |
| 2114 name, | 2042 name, |
| 2115 Token::kINDEX, | 2043 Token::kINDEX, |
| 2116 arguments, | 2044 arguments, |
| 2117 Array::ZoneHandle(), | 2045 Array::ZoneHandle(), |
| 2118 checked_argument_count); | 2046 checked_argument_count); |
| 2119 ReturnComputation(load); | 2047 ReturnComputation(load); |
| 2120 } | 2048 } |
| 2121 | 2049 |
| 2122 | 2050 |
| 2123 Computation* EffectGraphVisitor::BuildStoreIndexedValues( | 2051 Computation* EffectGraphVisitor::BuildStoreIndexedValues( |
| 2124 StoreIndexedNode* node, | 2052 StoreIndexedNode* node, |
| 2125 bool result_is_needed) { | 2053 bool result_is_needed) { |
| 2126 InlineBailout("EffectGraphVisitor::BuildStoreIndexedValues"); | |
| 2127 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2054 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 2128 new ZoneGrowableArray<PushArgumentInstr*>(3); | 2055 new ZoneGrowableArray<PushArgumentInstr*>(3); |
| 2129 ValueGraphVisitor for_array(owner(), temp_index()); | 2056 ValueGraphVisitor for_array(owner(), temp_index()); |
| 2130 node->array()->Visit(&for_array); | 2057 node->array()->Visit(&for_array); |
| 2131 Append(for_array); | 2058 Append(for_array); |
| 2132 arguments->Add(PushArgument(for_array.value())); | 2059 arguments->Add(PushArgument(for_array.value())); |
| 2133 | 2060 |
| 2134 ValueGraphVisitor for_index(owner(), temp_index()); | 2061 ValueGraphVisitor for_index(owner(), temp_index()); |
| 2135 node->index_expr()->Visit(&for_index); | 2062 node->index_expr()->Visit(&for_index); |
| 2136 Append(for_index); | 2063 Append(for_index); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 2161 if (result_is_needed) { | 2088 if (result_is_needed) { |
| 2162 Do(store); | 2089 Do(store); |
| 2163 return BuildLoadLocal(*owner()->parsed_function().expression_temp_var()); | 2090 return BuildLoadLocal(*owner()->parsed_function().expression_temp_var()); |
| 2164 } else { | 2091 } else { |
| 2165 return store; | 2092 return store; |
| 2166 } | 2093 } |
| 2167 } | 2094 } |
| 2168 | 2095 |
| 2169 | 2096 |
| 2170 void EffectGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) { | 2097 void EffectGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) { |
| 2171 InlineBailout("EffectGraphVisitor::VisitStoreIndexedNode"); | |
| 2172 ReturnComputation(BuildStoreIndexedValues(node, | 2098 ReturnComputation(BuildStoreIndexedValues(node, |
| 2173 false)); // Result not needed. | 2099 false)); // Result not needed. |
| 2174 } | 2100 } |
| 2175 | 2101 |
| 2176 | 2102 |
| 2177 void ValueGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) { | 2103 void ValueGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) { |
| 2178 InlineBailout("ValueGraphVisitor::VisitStoreIndexedNode"); | |
| 2179 ReturnComputation(BuildStoreIndexedValues(node, | 2104 ReturnComputation(BuildStoreIndexedValues(node, |
| 2180 true)); // Result is needed. | 2105 true)); // Result is needed. |
| 2181 } | 2106 } |
| 2182 | 2107 |
| 2183 | 2108 |
| 2184 bool EffectGraphVisitor::MustSaveRestoreContext(SequenceNode* node) const { | 2109 bool EffectGraphVisitor::MustSaveRestoreContext(SequenceNode* node) const { |
| 2185 return (node == owner()->parsed_function().node_sequence()) && | 2110 return (node == owner()->parsed_function().node_sequence()) && |
| 2186 (owner()->parsed_function().saved_context_var() != NULL); | 2111 (owner()->parsed_function().saved_context_var() != NULL); |
| 2187 } | 2112 } |
| 2188 | 2113 |
| 2189 | 2114 |
| 2190 void EffectGraphVisitor::UnchainContext() { | 2115 void EffectGraphVisitor::UnchainContext() { |
| 2191 InlineBailout("EffectGraphVisitor::UnchainContext"); | |
| 2192 Value* context = Bind(new CurrentContextComp()); | 2116 Value* context = Bind(new CurrentContextComp()); |
| 2193 Value* parent = Bind( | 2117 Value* parent = Bind( |
| 2194 new LoadVMFieldComp(context, | 2118 new LoadVMFieldComp(context, |
| 2195 Context::parent_offset(), | 2119 Context::parent_offset(), |
| 2196 Type::ZoneHandle())); // Not an instance, no type. | 2120 Type::ZoneHandle())); // Not an instance, no type. |
| 2197 Do(new StoreContextComp(parent)); | 2121 Do(new StoreContextComp(parent)); |
| 2198 } | 2122 } |
| 2199 | 2123 |
| 2200 | 2124 |
| 2201 // <Statement> ::= Sequence { scope: LocalScope | 2125 // <Statement> ::= Sequence { scope: LocalScope |
| 2202 // nodes: <Statement>* | 2126 // nodes: <Statement>* |
| 2203 // label: SourceLabel } | 2127 // label: SourceLabel } |
| 2204 void EffectGraphVisitor::VisitSequenceNode(SequenceNode* node) { | 2128 void EffectGraphVisitor::VisitSequenceNode(SequenceNode* node) { |
| 2205 LocalScope* scope = node->scope(); | 2129 LocalScope* scope = node->scope(); |
| 2206 const intptr_t num_context_variables = | 2130 const intptr_t num_context_variables = |
| 2207 (scope != NULL) ? scope->num_context_variables() : 0; | 2131 (scope != NULL) ? scope->num_context_variables() : 0; |
| 2208 int previous_context_level = owner()->context_level(); | 2132 int previous_context_level = owner()->context_level(); |
| 2209 if (num_context_variables > 0) { | 2133 if (num_context_variables > 0) { |
| 2210 InlineBailout("EffectGraphVisitor::VisitSequenceNode (captured vars)"); | |
| 2211 // The loop local scope declares variables that are captured. | 2134 // The loop local scope declares variables that are captured. |
| 2212 // Allocate and chain a new context. | 2135 // Allocate and chain a new context. |
| 2213 // Allocate context computation (uses current CTX) | 2136 // Allocate context computation (uses current CTX) |
| 2214 Value* allocated_context = | 2137 Value* allocated_context = |
| 2215 Bind(new AllocateContextComp(node->token_pos(), num_context_variables)); | 2138 Bind(new AllocateContextComp(node->token_pos(), num_context_variables)); |
| 2216 | 2139 |
| 2217 // If this node_sequence is the body of the function being compiled, and if | 2140 // If this node_sequence is the body of the function being compiled, and if |
| 2218 // this function is not a closure, do not link the current context as the | 2141 // this function is not a closure, do not link the current context as the |
| 2219 // parent of the newly allocated context, as it is not accessible. Instead, | 2142 // parent of the newly allocated context, as it is not accessible. Instead, |
| 2220 // save it in a pre-allocated variable and restore it on exit. | 2143 // save it in a pre-allocated variable and restore it on exit. |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2259 Value* null_constant = | 2182 Value* null_constant = |
| 2260 Bind(new ConstantComp(Object::ZoneHandle())); | 2183 Bind(new ConstantComp(Object::ZoneHandle())); |
| 2261 Do(BuildStoreLocal(*temp_local, null_constant)); | 2184 Do(BuildStoreLocal(*temp_local, null_constant)); |
| 2262 } | 2185 } |
| 2263 } | 2186 } |
| 2264 } | 2187 } |
| 2265 } | 2188 } |
| 2266 | 2189 |
| 2267 if (FLAG_enable_type_checks && | 2190 if (FLAG_enable_type_checks && |
| 2268 (node == owner()->parsed_function().node_sequence())) { | 2191 (node == owner()->parsed_function().node_sequence())) { |
| 2269 InlineBailout("EffectGraphVisitor::VisitSequenceNode (type check)"); | |
| 2270 const Function& function = owner()->parsed_function().function(); | 2192 const Function& function = owner()->parsed_function().function(); |
| 2271 const int num_params = function.NumberOfParameters(); | 2193 const int num_params = function.NumberOfParameters(); |
| 2272 int pos = 0; | 2194 int pos = 0; |
| 2273 if (function.IsConstructor()) { | 2195 if (function.IsConstructor()) { |
| 2274 // Skip type checking of receiver and phase for constructor functions. | 2196 // Skip type checking of receiver and phase for constructor functions. |
| 2275 pos = 2; | 2197 pos = 2; |
| 2276 } else if (function.IsFactory() || function.IsDynamicFunction()) { | 2198 } else if (function.IsFactory() || function.IsDynamicFunction()) { |
| 2277 // Skip type checking of type arguments for factory functions. | 2199 // Skip type checking of type arguments for factory functions. |
| 2278 // Skip type checking of receiver for instance functions. | 2200 // Skip type checking of receiver for instance functions. |
| 2279 pos = 1; | 2201 pos = 1; |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2333 } | 2255 } |
| 2334 | 2256 |
| 2335 // The outermost function sequence cannot contain a label. | 2257 // The outermost function sequence cannot contain a label. |
| 2336 ASSERT((node->label() == NULL) || | 2258 ASSERT((node->label() == NULL) || |
| 2337 (node != owner()->parsed_function().node_sequence())); | 2259 (node != owner()->parsed_function().node_sequence())); |
| 2338 owner()->set_context_level(previous_context_level); | 2260 owner()->set_context_level(previous_context_level); |
| 2339 } | 2261 } |
| 2340 | 2262 |
| 2341 | 2263 |
| 2342 void EffectGraphVisitor::VisitCatchClauseNode(CatchClauseNode* node) { | 2264 void EffectGraphVisitor::VisitCatchClauseNode(CatchClauseNode* node) { |
| 2343 InlineBailout("EffectGraphVisitor::VisitCatchClauseNode"); | |
| 2344 // NOTE: The implicit variables ':saved_context', ':exception_var' | 2265 // NOTE: The implicit variables ':saved_context', ':exception_var' |
| 2345 // and ':stacktrace_var' can never be captured variables. | 2266 // and ':stacktrace_var' can never be captured variables. |
| 2346 // Restores CTX from local variable ':saved_context'. | 2267 // Restores CTX from local variable ':saved_context'. |
| 2347 Do(new CatchEntryComp(node->exception_var(), node->stacktrace_var())); | 2268 Do(new CatchEntryComp(node->exception_var(), node->stacktrace_var())); |
| 2348 BuildLoadContext(node->context_var()); | 2269 BuildLoadContext(node->context_var()); |
| 2349 | 2270 |
| 2350 EffectGraphVisitor for_catch(owner(), temp_index()); | 2271 EffectGraphVisitor for_catch(owner(), temp_index()); |
| 2351 node->VisitChildren(&for_catch); | 2272 node->VisitChildren(&for_catch); |
| 2352 Append(for_catch); | 2273 Append(for_catch); |
| 2353 } | 2274 } |
| 2354 | 2275 |
| 2355 | 2276 |
| 2356 void EffectGraphVisitor::VisitTryCatchNode(TryCatchNode* node) { | 2277 void EffectGraphVisitor::VisitTryCatchNode(TryCatchNode* node) { |
| 2357 InlineBailout("EffectGraphVisitor::VisitTryCatchNode"); | |
| 2358 intptr_t old_try_index = owner()->try_index(); | 2278 intptr_t old_try_index = owner()->try_index(); |
| 2359 intptr_t try_index = owner()->AllocateTryIndex(); | 2279 intptr_t try_index = owner()->AllocateTryIndex(); |
| 2360 owner()->set_try_index(try_index); | 2280 owner()->set_try_index(try_index); |
| 2361 | 2281 |
| 2362 // Preserve CTX into local variable '%saved_context'. | 2282 // Preserve CTX into local variable '%saved_context'. |
| 2363 BuildStoreContext(node->context_var()); | 2283 BuildStoreContext(node->context_var()); |
| 2364 | 2284 |
| 2365 EffectGraphVisitor for_try_block(owner(), temp_index()); | 2285 EffectGraphVisitor for_try_block(owner(), temp_index()); |
| 2366 node->try_block()->Visit(&for_try_block); | 2286 node->try_block()->Visit(&for_try_block); |
| 2367 | 2287 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2405 // Generate code for the finally block if one exists. | 2325 // Generate code for the finally block if one exists. |
| 2406 if ((node->finally_block() != NULL) && is_open()) { | 2326 if ((node->finally_block() != NULL) && is_open()) { |
| 2407 EffectGraphVisitor for_finally_block(owner(), temp_index()); | 2327 EffectGraphVisitor for_finally_block(owner(), temp_index()); |
| 2408 node->finally_block()->Visit(&for_finally_block); | 2328 node->finally_block()->Visit(&for_finally_block); |
| 2409 Append(for_finally_block); | 2329 Append(for_finally_block); |
| 2410 } | 2330 } |
| 2411 } | 2331 } |
| 2412 | 2332 |
| 2413 | 2333 |
| 2414 void EffectGraphVisitor::BuildThrowNode(ThrowNode* node) { | 2334 void EffectGraphVisitor::BuildThrowNode(ThrowNode* node) { |
| 2415 InlineBailout("EffectGraphVisitor::BuildThrowNode"); | |
| 2416 ValueGraphVisitor for_exception(owner(), temp_index()); | 2335 ValueGraphVisitor for_exception(owner(), temp_index()); |
| 2417 node->exception()->Visit(&for_exception); | 2336 node->exception()->Visit(&for_exception); |
| 2418 Append(for_exception); | 2337 Append(for_exception); |
| 2419 PushArgument(for_exception.value()); | 2338 PushArgument(for_exception.value()); |
| 2420 Instruction* instr = NULL; | 2339 Instruction* instr = NULL; |
| 2421 if (node->stacktrace() == NULL) { | 2340 if (node->stacktrace() == NULL) { |
| 2422 instr = new ThrowInstr(node->token_pos()); | 2341 instr = new ThrowInstr(node->token_pos()); |
| 2423 } else { | 2342 } else { |
| 2424 ValueGraphVisitor for_stack_trace(owner(), temp_index()); | 2343 ValueGraphVisitor for_stack_trace(owner(), temp_index()); |
| 2425 node->stacktrace()->Visit(&for_stack_trace); | 2344 node->stacktrace()->Visit(&for_stack_trace); |
| 2426 Append(for_stack_trace); | 2345 Append(for_stack_trace); |
| 2427 PushArgument(for_stack_trace.value()); | 2346 PushArgument(for_stack_trace.value()); |
| 2428 instr = new ReThrowInstr(node->token_pos()); | 2347 instr = new ReThrowInstr(node->token_pos()); |
| 2429 } | 2348 } |
| 2430 AddInstruction(instr); | 2349 AddInstruction(instr); |
| 2431 } | 2350 } |
| 2432 | 2351 |
| 2433 | 2352 |
| 2434 void EffectGraphVisitor::VisitThrowNode(ThrowNode* node) { | 2353 void EffectGraphVisitor::VisitThrowNode(ThrowNode* node) { |
| 2435 InlineBailout("EffectGraphVisitor::VisitThrowNode"); | |
| 2436 BuildThrowNode(node); | 2354 BuildThrowNode(node); |
| 2437 CloseFragment(); | 2355 CloseFragment(); |
| 2438 } | 2356 } |
| 2439 | 2357 |
| 2440 | 2358 |
| 2441 // A throw cannot be part of an expression, however, the parser may replace | 2359 // A throw cannot be part of an expression, however, the parser may replace |
| 2442 // certain expression nodes with a throw. In that case generate a literal null | 2360 // certain expression nodes with a throw. In that case generate a literal null |
| 2443 // so that the fragment is not closed in the middle of an expression. | 2361 // so that the fragment is not closed in the middle of an expression. |
| 2444 void ValueGraphVisitor::VisitThrowNode(ThrowNode* node) { | 2362 void ValueGraphVisitor::VisitThrowNode(ThrowNode* node) { |
| 2445 InlineBailout("ValueGraphVisitor::VisitThrowNode"); | |
| 2446 BuildThrowNode(node); | 2363 BuildThrowNode(node); |
| 2447 ReturnComputation(new ConstantComp(Instance::ZoneHandle())); | 2364 ReturnComputation(new ConstantComp(Instance::ZoneHandle())); |
| 2448 } | 2365 } |
| 2449 | 2366 |
| 2450 | 2367 |
| 2451 void EffectGraphVisitor::VisitInlinedFinallyNode(InlinedFinallyNode* node) { | 2368 void EffectGraphVisitor::VisitInlinedFinallyNode(InlinedFinallyNode* node) { |
| 2452 InlineBailout("EffectGraphVisitor::VisitInlinedFinallyNode"); | |
| 2453 const intptr_t try_index = owner()->try_index(); | 2369 const intptr_t try_index = owner()->try_index(); |
| 2454 if (try_index >= 0) { | 2370 if (try_index >= 0) { |
| 2455 // We are about to generate code for an inlined finally block. Exceptions | 2371 // We are about to generate code for an inlined finally block. Exceptions |
| 2456 // thrown in this block of code should be treated as though they are | 2372 // thrown in this block of code should be treated as though they are |
| 2457 // thrown not from the current try block but the outer try block if any. | 2373 // thrown not from the current try block but the outer try block if any. |
| 2458 owner()->set_try_index((try_index - 1)); | 2374 owner()->set_try_index((try_index - 1)); |
| 2459 } | 2375 } |
| 2460 BuildLoadContext(node->context_var()); | 2376 BuildLoadContext(node->context_var()); |
| 2461 | 2377 |
| 2462 JoinEntryInstr* finally_entry = new JoinEntryInstr(owner()->try_index()); | 2378 JoinEntryInstr* finally_entry = new JoinEntryInstr(owner()->try_index()); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2494 // stack check on entry for leaf routines). | 2410 // stack check on entry for leaf routines). |
| 2495 for_effect.Do(new CheckStackOverflowComp(function.token_pos())); | 2411 for_effect.Do(new CheckStackOverflowComp(function.token_pos())); |
| 2496 parsed_function().node_sequence()->Visit(&for_effect); | 2412 parsed_function().node_sequence()->Visit(&for_effect); |
| 2497 AppendFragment(normal_entry, for_effect); | 2413 AppendFragment(normal_entry, for_effect); |
| 2498 // Check that the graph is properly terminated. | 2414 // Check that the graph is properly terminated. |
| 2499 ASSERT(!for_effect.is_open()); | 2415 ASSERT(!for_effect.is_open()); |
| 2500 return new FlowGraph(*this, graph_entry_); | 2416 return new FlowGraph(*this, graph_entry_); |
| 2501 } | 2417 } |
| 2502 | 2418 |
| 2503 | 2419 |
| 2504 FlowGraph* FlowGraphBuilder::BuildGraphForInlining(InliningContext context) { | |
| 2505 ASSERT(inlining_context_ == kNotInlining); | |
| 2506 inlining_context_ = context; | |
| 2507 exits_ = new ZoneGrowableArray<ReturnInstr*>(); | |
| 2508 TargetEntryInstr* normal_entry = new TargetEntryInstr( | |
| 2509 CatchClauseNode::kInvalidTryIndex); | |
| 2510 graph_entry_ = new GraphEntryInstr(normal_entry); | |
| 2511 EffectGraphVisitor for_effect(this, 0); | |
| 2512 parsed_function().node_sequence()->Visit(&for_effect); | |
| 2513 AppendFragment(normal_entry, for_effect); | |
| 2514 ASSERT(!for_effect.is_open()); | |
| 2515 FlowGraph* graph = new FlowGraph(*this, graph_entry_); | |
| 2516 graph->set_exits(exits_); | |
| 2517 return graph; | |
| 2518 } | |
| 2519 | |
| 2520 | |
| 2521 void FlowGraphBuilder::Bailout(const char* reason) { | 2420 void FlowGraphBuilder::Bailout(const char* reason) { |
| 2522 const char* kFormat = "FlowGraphBuilder Bailout: %s %s"; | 2421 const char* kFormat = "FlowGraphBuilder Bailout: %s %s"; |
| 2523 const char* function_name = parsed_function_.function().ToCString(); | 2422 const char* function_name = parsed_function_.function().ToCString(); |
| 2524 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; | 2423 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; |
| 2525 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 2424 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
| 2526 OS::SNPrint(chars, len, kFormat, function_name, reason); | 2425 OS::SNPrint(chars, len, kFormat, function_name, reason); |
| 2527 const Error& error = Error::Handle( | 2426 const Error& error = Error::Handle( |
| 2528 LanguageError::New(String::Handle(String::New(chars)))); | 2427 LanguageError::New(String::Handle(String::New(chars)))); |
| 2529 Isolate::Current()->long_jump_base()->Jump(1, error); | 2428 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 2530 } | 2429 } |
| 2531 | 2430 |
| 2532 | 2431 |
| 2533 } // namespace dart | 2432 } // namespace dart |
| OLD | NEW |