Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(505)

Side by Side Diff: src/x64/codegen-x64.cc

Issue 147197: X64: Added support for "with" and "switch". (Closed)
Patch Set: Fixed constants in frames-x64.h. Stacktraces work. Created 11 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/x64/frames-x64.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 669 matching lines...) Expand 10 before | Expand all | Expand 10 after
680 // code by jumping to the return site. 680 // code by jumping to the return site.
681 function_return_.Jump(&return_value); 681 function_return_.Jump(&return_value);
682 } else { 682 } else {
683 function_return_.Bind(&return_value); 683 function_return_.Bind(&return_value);
684 GenerateReturnSequence(&return_value); 684 GenerateReturnSequence(&return_value);
685 } 685 }
686 } 686 }
687 } 687 }
688 688
689 689
690 void CodeGenerator::VisitWithEnterStatement(WithEnterStatement* a) { 690 void CodeGenerator::VisitWithEnterStatement(WithEnterStatement* node) {
691 UNIMPLEMENTED(); 691 ASSERT(!in_spilled_code());
692 } 692 Comment cmnt(masm_, "[ WithEnterStatement");
693 CodeForStatementPosition(node);
694 Load(node->expression());
695 Result context;
696 if (node->is_catch_block()) {
697 context = frame_->CallRuntime(Runtime::kPushCatchContext, 1);
698 } else {
699 context = frame_->CallRuntime(Runtime::kPushContext, 1);
700 }
693 701
694 void CodeGenerator::VisitWithExitStatement(WithExitStatement* a) { 702 // Update context local.
695 UNIMPLEMENTED(); 703 frame_->SaveContextRegister();
696 }
697 704
698 void CodeGenerator::VisitSwitchStatement(SwitchStatement* a) { 705 // Verify that the runtime call result and esi agree.
William Hesse 2009/06/26 08:25:18 rsi
699 UNIMPLEMENTED(); 706 if (FLAG_debug_code) {
707 __ cmpq(context.reg(), rsi);
708 __ Assert(equal, "Runtime::NewContext should end up in rsi");
709 }
700 } 710 }
701 711
702 712
713 void CodeGenerator::VisitWithExitStatement(WithExitStatement* node) {
714 ASSERT(!in_spilled_code());
715 Comment cmnt(masm_, "[ WithExitStatement");
716 CodeForStatementPosition(node);
717 // Pop context.
718 __ movq(rsi, ContextOperand(rsi, Context::PREVIOUS_INDEX));
719 // Update context local.
720 frame_->SaveContextRegister();
721 }
722
723
724 void CodeGenerator::VisitSwitchStatement(SwitchStatement* node) {
725 // TODO(X64): This code is completely generic and should be moved somewhere
726 // where it can be shared between architectures.
727 ASSERT(!in_spilled_code());
728 Comment cmnt(masm_, "[ SwitchStatement");
729 CodeForStatementPosition(node);
730 node->break_target()->set_direction(JumpTarget::FORWARD_ONLY);
731
732 // Compile the switch value.
733 Load(node->tag());
734
735 ZoneList<CaseClause*>* cases = node->cases();
736 int length = cases->length();
737 CaseClause* default_clause = NULL;
738
739 JumpTarget next_test;
740 // Compile the case label expressions and comparisons. Exit early
741 // if a comparison is unconditionally true. The target next_test is
742 // bound before the loop in order to indicate control flow to the
743 // first comparison.
744 next_test.Bind();
745 for (int i = 0; i < length && !next_test.is_unused(); i++) {
746 CaseClause* clause = cases->at(i);
747 // The default is not a test, but remember it for later.
748 if (clause->is_default()) {
749 default_clause = clause;
750 continue;
751 }
752
753 Comment cmnt(masm_, "[ Case comparison");
754 // We recycle the same target next_test for each test. Bind it if
755 // the previous test has not done so and then unuse it for the
756 // loop.
757 if (next_test.is_linked()) {
758 next_test.Bind();
759 }
760 next_test.Unuse();
761
762 // Duplicate the switch value.
763 frame_->Dup();
764
765 // Compile the label expression.
766 Load(clause->label());
767
768 // Compare and branch to the body if true or the next test if
769 // false. Prefer the next test as a fall through.
770 ControlDestination dest(clause->body_target(), &next_test, false);
771 Comparison(equal, true, &dest);
772
773 // If the comparison fell through to the true target, jump to the
774 // actual body.
775 if (dest.true_was_fall_through()) {
776 clause->body_target()->Unuse();
777 clause->body_target()->Jump();
778 }
779 }
780
781 // If there was control flow to a next test from the last one
782 // compiled, compile a jump to the default or break target.
783 if (!next_test.is_unused()) {
784 if (next_test.is_linked()) {
785 next_test.Bind();
786 }
787 // Drop the switch value.
788 frame_->Drop();
789 if (default_clause != NULL) {
790 default_clause->body_target()->Jump();
791 } else {
792 node->break_target()->Jump();
793 }
794 }
795
796 // The last instruction emitted was a jump, either to the default
797 // clause or the break target, or else to a case body from the loop
798 // that compiles the tests.
799 ASSERT(!has_valid_frame());
800 // Compile case bodies as needed.
801 for (int i = 0; i < length; i++) {
802 CaseClause* clause = cases->at(i);
803
804 // There are two ways to reach the body: from the corresponding
805 // test or as the fall through of the previous body.
806 if (clause->body_target()->is_linked() || has_valid_frame()) {
807 if (clause->body_target()->is_linked()) {
808 if (has_valid_frame()) {
809 // If we have both a jump to the test and a fall through, put
810 // a jump on the fall through path to avoid the dropping of
811 // the switch value on the test path. The exception is the
812 // default which has already had the switch value dropped.
813 if (clause->is_default()) {
814 clause->body_target()->Bind();
815 } else {
816 JumpTarget body;
817 body.Jump();
818 clause->body_target()->Bind();
819 frame_->Drop();
820 body.Bind();
821 }
822 } else {
823 // No fall through to worry about.
824 clause->body_target()->Bind();
825 if (!clause->is_default()) {
826 frame_->Drop();
827 }
828 }
829 } else {
830 // Otherwise, we have only fall through.
831 ASSERT(has_valid_frame());
832 }
833
834 // We are now prepared to compile the body.
835 Comment cmnt(masm_, "[ Case body");
836 VisitStatements(clause->statements());
837 }
838 clause->body_target()->Unuse();
839 }
840
841 // We may not have a valid frame here so bind the break target only
842 // if needed.
843 if (node->break_target()->is_linked()) {
844 node->break_target()->Bind();
845 }
846 node->break_target()->Unuse();
847 }
848
849
703 void CodeGenerator::VisitLoopStatement(LoopStatement* node) { 850 void CodeGenerator::VisitLoopStatement(LoopStatement* node) {
704 ASSERT(!in_spilled_code()); 851 ASSERT(!in_spilled_code());
705 Comment cmnt(masm_, "[ LoopStatement"); 852 Comment cmnt(masm_, "[ LoopStatement");
706 CodeForStatementPosition(node); 853 CodeForStatementPosition(node);
707 node->break_target()->set_direction(JumpTarget::FORWARD_ONLY); 854 node->break_target()->set_direction(JumpTarget::FORWARD_ONLY);
708 855
709 // Simple condition analysis. ALWAYS_TRUE and ALWAYS_FALSE represent a 856 // Simple condition analysis. ALWAYS_TRUE and ALWAYS_FALSE represent a
710 // known result for the test expression, with no side effects. 857 // known result for the test expression, with no side effects.
711 enum { ALWAYS_TRUE, ALWAYS_FALSE, DONT_KNOW } info = DONT_KNOW; 858 enum { ALWAYS_TRUE, ALWAYS_FALSE, DONT_KNOW } info = DONT_KNOW;
712 if (node->cond() == NULL) { 859 if (node->cond() == NULL) {
(...skipping 5297 matching lines...) Expand 10 before | Expand all | Expand 10 after
6010 break; 6157 break;
6011 default: 6158 default:
6012 UNREACHABLE(); 6159 UNREACHABLE();
6013 } 6160 }
6014 } 6161 }
6015 6162
6016 6163
6017 #undef __ 6164 #undef __
6018 6165
6019 } } // namespace v8::internal 6166 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/x64/frames-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698