| 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 |