OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
310 offset += JavaScriptFrameConstants::kLocal0Offset; | 310 offset += JavaScriptFrameConstants::kLocal0Offset; |
311 break; | 311 break; |
312 case Slot::CONTEXT: | 312 case Slot::CONTEXT: |
313 case Slot::LOOKUP: | 313 case Slot::LOOKUP: |
314 UNREACHABLE(); | 314 UNREACHABLE(); |
315 } | 315 } |
316 return offset; | 316 return offset; |
317 } | 317 } |
318 | 318 |
319 | 319 |
| 320 void FullCodeGenerator::PrepareTest(Label* materialize_true, |
| 321 Label* materialize_false, |
| 322 Label** if_true, |
| 323 Label** if_false, |
| 324 Label** fall_through) { |
| 325 switch (context_) { |
| 326 case Expression::kUninitialized: |
| 327 UNREACHABLE(); |
| 328 break; |
| 329 case Expression::kEffect: |
| 330 // In an effect context, the true and the false case branch to the |
| 331 // same label. |
| 332 *if_true = *if_false = *fall_through = materialize_true; |
| 333 break; |
| 334 case Expression::kValue: |
| 335 *if_true = *fall_through = materialize_true; |
| 336 *if_false = materialize_false; |
| 337 break; |
| 338 case Expression::kTest: |
| 339 *if_true = true_label_; |
| 340 *if_false = false_label_; |
| 341 *fall_through = fall_through_; |
| 342 break; |
| 343 } |
| 344 } |
| 345 |
| 346 |
320 void FullCodeGenerator::VisitDeclarations( | 347 void FullCodeGenerator::VisitDeclarations( |
321 ZoneList<Declaration*>* declarations) { | 348 ZoneList<Declaration*>* declarations) { |
322 int length = declarations->length(); | 349 int length = declarations->length(); |
323 int globals = 0; | 350 int globals = 0; |
324 for (int i = 0; i < length; i++) { | 351 for (int i = 0; i < length; i++) { |
325 Declaration* decl = declarations->at(i); | 352 Declaration* decl = declarations->at(i); |
326 Variable* var = decl->proxy()->var(); | 353 Variable* var = decl->proxy()->var(); |
327 Slot* slot = var->slot(); | 354 Slot* slot = var->slot(); |
328 | 355 |
329 // If it was not possible to allocate the variable at compile | 356 // If it was not possible to allocate the variable at compile |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
514 Label eval_right, done; | 541 Label eval_right, done; |
515 | 542 |
516 // Set up the appropriate context for the left subexpression based | 543 // Set up the appropriate context for the left subexpression based |
517 // on the operation and our own context. Initially assume we can | 544 // on the operation and our own context. Initially assume we can |
518 // inherit both true and false labels from our context. | 545 // inherit both true and false labels from our context. |
519 if (expr->op() == Token::OR) { | 546 if (expr->op() == Token::OR) { |
520 switch (context_) { | 547 switch (context_) { |
521 case Expression::kUninitialized: | 548 case Expression::kUninitialized: |
522 UNREACHABLE(); | 549 UNREACHABLE(); |
523 case Expression::kEffect: | 550 case Expression::kEffect: |
524 VisitForControl(expr->left(), &done, &eval_right); | 551 VisitForControl(expr->left(), &done, &eval_right, &eval_right); |
525 break; | 552 break; |
526 case Expression::kValue: | 553 case Expression::kValue: |
527 VisitLogicalForValue(expr->left(), expr->op(), location_, &done); | 554 VisitLogicalForValue(expr->left(), expr->op(), location_, &done); |
528 break; | 555 break; |
529 case Expression::kTest: | 556 case Expression::kTest: |
530 VisitForControl(expr->left(), true_label_, &eval_right); | 557 VisitForControl(expr->left(), true_label_, &eval_right, &eval_right); |
531 break; | 558 break; |
532 } | 559 } |
533 } else { | 560 } else { |
534 ASSERT_EQ(Token::AND, expr->op()); | 561 ASSERT_EQ(Token::AND, expr->op()); |
535 switch (context_) { | 562 switch (context_) { |
536 case Expression::kUninitialized: | 563 case Expression::kUninitialized: |
537 UNREACHABLE(); | 564 UNREACHABLE(); |
538 case Expression::kEffect: | 565 case Expression::kEffect: |
539 VisitForControl(expr->left(), &eval_right, &done); | 566 VisitForControl(expr->left(), &eval_right, &done, &eval_right); |
540 break; | 567 break; |
541 case Expression::kValue: | 568 case Expression::kValue: |
542 VisitLogicalForValue(expr->left(), expr->op(), location_, &done); | 569 VisitLogicalForValue(expr->left(), expr->op(), location_, &done); |
543 break; | 570 break; |
544 case Expression::kTest: | 571 case Expression::kTest: |
545 VisitForControl(expr->left(), &eval_right, false_label_); | 572 VisitForControl(expr->left(), &eval_right, false_label_, &eval_right); |
546 break; | 573 break; |
547 } | 574 } |
548 } | 575 } |
549 | 576 |
550 __ bind(&eval_right); | 577 __ bind(&eval_right); |
551 Visit(expr->right()); | 578 Visit(expr->right()); |
552 | 579 |
553 __ bind(&done); | 580 __ bind(&done); |
554 } | 581 } |
555 | 582 |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
611 Comment cmnt(masm_, "[ EmptyStatement"); | 638 Comment cmnt(masm_, "[ EmptyStatement"); |
612 SetStatementPosition(stmt); | 639 SetStatementPosition(stmt); |
613 } | 640 } |
614 | 641 |
615 | 642 |
616 void FullCodeGenerator::VisitIfStatement(IfStatement* stmt) { | 643 void FullCodeGenerator::VisitIfStatement(IfStatement* stmt) { |
617 Comment cmnt(masm_, "[ IfStatement"); | 644 Comment cmnt(masm_, "[ IfStatement"); |
618 SetStatementPosition(stmt); | 645 SetStatementPosition(stmt); |
619 Label then_part, else_part, done; | 646 Label then_part, else_part, done; |
620 | 647 |
621 // Do not worry about optimizing for empty then or else bodies. | 648 if (stmt->HasElseStatement()) { |
622 VisitForControl(stmt->condition(), &then_part, &else_part); | 649 VisitForControl(stmt->condition(), &then_part, &else_part, &then_part); |
| 650 __ bind(&then_part); |
| 651 Visit(stmt->then_statement()); |
| 652 __ jmp(&done); |
623 | 653 |
624 __ bind(&then_part); | 654 __ bind(&else_part); |
625 Visit(stmt->then_statement()); | 655 Visit(stmt->else_statement()); |
626 __ jmp(&done); | 656 } else { |
627 | 657 VisitForControl(stmt->condition(), &then_part, &done, &then_part); |
628 __ bind(&else_part); | 658 __ bind(&then_part); |
629 Visit(stmt->else_statement()); | 659 Visit(stmt->then_statement()); |
630 | 660 } |
631 __ bind(&done); | 661 __ bind(&done); |
632 } | 662 } |
633 | 663 |
634 | 664 |
635 void FullCodeGenerator::VisitContinueStatement(ContinueStatement* stmt) { | 665 void FullCodeGenerator::VisitContinueStatement(ContinueStatement* stmt) { |
636 Comment cmnt(masm_, "[ ContinueStatement"); | 666 Comment cmnt(masm_, "[ ContinueStatement"); |
637 SetStatementPosition(stmt); | 667 SetStatementPosition(stmt); |
638 NestedStatement* current = nesting_stack_; | 668 NestedStatement* current = nesting_stack_; |
639 int stack_depth = 0; | 669 int stack_depth = 0; |
640 while (!current->IsContinueTarget(stmt->target())) { | 670 while (!current->IsContinueTarget(stmt->target())) { |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
708 // Pop context. | 738 // Pop context. |
709 LoadContextField(context_register(), Context::PREVIOUS_INDEX); | 739 LoadContextField(context_register(), Context::PREVIOUS_INDEX); |
710 // Update local stack frame context field. | 740 // Update local stack frame context field. |
711 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); | 741 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); |
712 } | 742 } |
713 | 743 |
714 | 744 |
715 void FullCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) { | 745 void FullCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) { |
716 Comment cmnt(masm_, "[ DoWhileStatement"); | 746 Comment cmnt(masm_, "[ DoWhileStatement"); |
717 SetStatementPosition(stmt); | 747 SetStatementPosition(stmt); |
718 Label body, stack_limit_hit, stack_check_success; | 748 Label body, stack_limit_hit, stack_check_success, done; |
719 | 749 |
720 Iteration loop_statement(this, stmt); | 750 Iteration loop_statement(this, stmt); |
721 increment_loop_depth(); | 751 increment_loop_depth(); |
722 | 752 |
723 __ bind(&body); | 753 __ bind(&body); |
724 Visit(stmt->body()); | 754 Visit(stmt->body()); |
725 | 755 |
726 // Check stack before looping. | 756 // Check stack before looping. |
727 __ StackLimitCheck(&stack_limit_hit); | 757 __ StackLimitCheck(&stack_limit_hit); |
728 __ bind(&stack_check_success); | 758 __ bind(&stack_check_success); |
729 | 759 |
| 760 // Record the position of the do while condition and make sure it is |
| 761 // possible to break on the condition. |
730 __ bind(loop_statement.continue_target()); | 762 __ bind(loop_statement.continue_target()); |
| 763 SetExpressionPosition(stmt->cond(), stmt->condition_position()); |
| 764 VisitForControl(stmt->cond(), |
| 765 &body, |
| 766 loop_statement.break_target(), |
| 767 loop_statement.break_target()); |
731 | 768 |
732 // Record the position of the do while condition and make sure it is possible | 769 __ bind(loop_statement.break_target()); |
733 // to break on the condition. | 770 __ jmp(&done); |
734 SetExpressionPosition(stmt->cond(), stmt->condition_position()); | |
735 | |
736 VisitForControl(stmt->cond(), &body, loop_statement.break_target()); | |
737 | 771 |
738 __ bind(&stack_limit_hit); | 772 __ bind(&stack_limit_hit); |
739 StackCheckStub stack_stub; | 773 StackCheckStub stack_stub; |
740 __ CallStub(&stack_stub); | 774 __ CallStub(&stack_stub); |
741 __ jmp(&stack_check_success); | 775 __ jmp(&stack_check_success); |
742 | 776 |
743 __ bind(loop_statement.break_target()); | 777 __ bind(&done); |
744 | |
745 decrement_loop_depth(); | 778 decrement_loop_depth(); |
746 } | 779 } |
747 | 780 |
748 | 781 |
749 void FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) { | 782 void FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) { |
750 Comment cmnt(masm_, "[ WhileStatement"); | 783 Comment cmnt(masm_, "[ WhileStatement"); |
751 Label body, stack_limit_hit, stack_check_success; | 784 Label body, stack_limit_hit, stack_check_success; |
752 | 785 |
753 Iteration loop_statement(this, stmt); | 786 Iteration loop_statement(this, stmt); |
754 increment_loop_depth(); | 787 increment_loop_depth(); |
755 | 788 |
756 // Emit the test at the bottom of the loop. | 789 // Emit the test at the bottom of the loop. |
757 __ jmp(loop_statement.continue_target()); | 790 __ jmp(loop_statement.continue_target()); |
758 | 791 |
| 792 __ bind(&stack_limit_hit); |
| 793 StackCheckStub stack_stub; |
| 794 __ CallStub(&stack_stub); |
| 795 __ jmp(&stack_check_success); |
| 796 |
759 __ bind(&body); | 797 __ bind(&body); |
760 Visit(stmt->body()); | 798 Visit(stmt->body()); |
| 799 __ bind(loop_statement.continue_target()); |
761 | 800 |
762 __ bind(loop_statement.continue_target()); | 801 // Emit the statement position here as this is where the while |
763 // Emit the statement position here as this is where the while statement code | 802 // statement code starts. |
764 // starts. | |
765 SetStatementPosition(stmt); | 803 SetStatementPosition(stmt); |
766 | 804 |
767 // Check stack before looping. | 805 // Check stack before looping. |
768 __ StackLimitCheck(&stack_limit_hit); | 806 __ StackLimitCheck(&stack_limit_hit); |
769 __ bind(&stack_check_success); | 807 __ bind(&stack_check_success); |
770 | 808 |
771 VisitForControl(stmt->cond(), &body, loop_statement.break_target()); | 809 VisitForControl(stmt->cond(), |
772 | 810 &body, |
773 __ bind(&stack_limit_hit); | 811 loop_statement.break_target(), |
774 StackCheckStub stack_stub; | 812 loop_statement.break_target()); |
775 __ CallStub(&stack_stub); | |
776 __ jmp(&stack_check_success); | |
777 | 813 |
778 __ bind(loop_statement.break_target()); | 814 __ bind(loop_statement.break_target()); |
779 decrement_loop_depth(); | 815 decrement_loop_depth(); |
780 } | 816 } |
781 | 817 |
782 | 818 |
783 void FullCodeGenerator::VisitForStatement(ForStatement* stmt) { | 819 void FullCodeGenerator::VisitForStatement(ForStatement* stmt) { |
784 Comment cmnt(masm_, "[ ForStatement"); | 820 Comment cmnt(masm_, "[ ForStatement"); |
785 Label test, body, stack_limit_hit, stack_check_success; | 821 Label test, body, stack_limit_hit, stack_check_success; |
786 | 822 |
787 Iteration loop_statement(this, stmt); | 823 Iteration loop_statement(this, stmt); |
788 if (stmt->init() != NULL) { | 824 if (stmt->init() != NULL) { |
789 Visit(stmt->init()); | 825 Visit(stmt->init()); |
790 } | 826 } |
791 | 827 |
792 increment_loop_depth(); | 828 increment_loop_depth(); |
793 // Emit the test at the bottom of the loop (even if empty). | 829 // Emit the test at the bottom of the loop (even if empty). |
794 __ jmp(&test); | 830 __ jmp(&test); |
795 | 831 |
| 832 __ bind(&stack_limit_hit); |
| 833 StackCheckStub stack_stub; |
| 834 __ CallStub(&stack_stub); |
| 835 __ jmp(&stack_check_success); |
| 836 |
796 __ bind(&body); | 837 __ bind(&body); |
797 Visit(stmt->body()); | 838 Visit(stmt->body()); |
798 | 839 |
799 __ bind(loop_statement.continue_target()); | 840 __ bind(loop_statement.continue_target()); |
800 | 841 |
801 SetStatementPosition(stmt); | 842 SetStatementPosition(stmt); |
802 if (stmt->next() != NULL) { | 843 if (stmt->next() != NULL) { |
803 Visit(stmt->next()); | 844 Visit(stmt->next()); |
804 } | 845 } |
805 | 846 |
806 __ bind(&test); | 847 __ bind(&test); |
807 // Emit the statement position here as this is where the for statement code | 848 // Emit the statement position here as this is where the for |
808 // starts. | 849 // statement code starts. |
809 SetStatementPosition(stmt); | 850 SetStatementPosition(stmt); |
810 | 851 |
811 // Check stack before looping. | 852 // Check stack before looping. |
812 __ StackLimitCheck(&stack_limit_hit); | 853 __ StackLimitCheck(&stack_limit_hit); |
813 __ bind(&stack_check_success); | 854 __ bind(&stack_check_success); |
814 | 855 |
815 if (stmt->cond() != NULL) { | 856 if (stmt->cond() != NULL) { |
816 VisitForControl(stmt->cond(), &body, loop_statement.break_target()); | 857 VisitForControl(stmt->cond(), |
| 858 &body, |
| 859 loop_statement.break_target(), |
| 860 loop_statement.break_target()); |
817 } else { | 861 } else { |
818 __ jmp(&body); | 862 __ jmp(&body); |
819 } | 863 } |
820 | 864 |
821 __ bind(&stack_limit_hit); | |
822 StackCheckStub stack_stub; | |
823 __ CallStub(&stack_stub); | |
824 __ jmp(&stack_check_success); | |
825 | |
826 __ bind(loop_statement.break_target()); | 865 __ bind(loop_statement.break_target()); |
827 decrement_loop_depth(); | 866 decrement_loop_depth(); |
828 } | 867 } |
829 | 868 |
830 | 869 |
831 void FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { | 870 void FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { |
832 Comment cmnt(masm_, "[ TryCatchStatement"); | 871 Comment cmnt(masm_, "[ TryCatchStatement"); |
833 SetStatementPosition(stmt); | 872 SetStatementPosition(stmt); |
834 // The try block adds a handler to the exception handler chain | 873 // The try block adds a handler to the exception handler chain |
835 // before entering, and removes it again when exiting normally. | 874 // before entering, and removes it again when exiting normally. |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
942 | 981 |
943 __ DebugBreak(); | 982 __ DebugBreak(); |
944 // Ignore the return value. | 983 // Ignore the return value. |
945 #endif | 984 #endif |
946 } | 985 } |
947 | 986 |
948 | 987 |
949 void FullCodeGenerator::VisitConditional(Conditional* expr) { | 988 void FullCodeGenerator::VisitConditional(Conditional* expr) { |
950 Comment cmnt(masm_, "[ Conditional"); | 989 Comment cmnt(masm_, "[ Conditional"); |
951 Label true_case, false_case, done; | 990 Label true_case, false_case, done; |
952 VisitForControl(expr->condition(), &true_case, &false_case); | 991 VisitForControl(expr->condition(), &true_case, &false_case, &true_case); |
953 | 992 |
954 __ bind(&true_case); | 993 __ bind(&true_case); |
955 SetExpressionPosition(expr->then_expression(), | 994 SetExpressionPosition(expr->then_expression(), |
956 expr->then_expression_position()); | 995 expr->then_expression_position()); |
957 Visit(expr->then_expression()); | 996 Visit(expr->then_expression()); |
958 // If control flow falls through Visit, jump to done. | 997 // If control flow falls through Visit, jump to done. |
959 if (context_ == Expression::kEffect || context_ == Expression::kValue) { | 998 if (context_ == Expression::kEffect || context_ == Expression::kValue) { |
960 __ jmp(&done); | 999 __ jmp(&done); |
961 } | 1000 } |
962 | 1001 |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1047 ASSERT(args->length() == 1); | 1086 ASSERT(args->length() == 1); |
1048 VisitForValue(args->at(0), kStack); | 1087 VisitForValue(args->at(0), kStack); |
1049 __ CallRuntime(Runtime::kRegExpCloneResult, 1); | 1088 __ CallRuntime(Runtime::kRegExpCloneResult, 1); |
1050 Apply(context_, result_register()); | 1089 Apply(context_, result_register()); |
1051 } | 1090 } |
1052 | 1091 |
1053 #undef __ | 1092 #undef __ |
1054 | 1093 |
1055 | 1094 |
1056 } } // namespace v8::internal | 1095 } } // namespace v8::internal |
OLD | NEW |