OLD | NEW |
---|---|
1 // Copyright 2007-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2007-2008 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 19 matching lines...) Expand all Loading... | |
30 #include "v8.h" | 30 #include "v8.h" |
31 | 31 |
32 #include "heap.h" | 32 #include "heap.h" |
33 #include "cctest.h" | 33 #include "cctest.h" |
34 | 34 |
35 using namespace v8; | 35 using namespace v8; |
36 | 36 |
37 | 37 |
38 enum Expectations { | 38 enum Expectations { |
39 EXPECT_RESULT, | 39 EXPECT_RESULT, |
40 EXPECT_EXCEPTION | 40 EXPECT_EXCEPTION, |
41 EXPECT_ERROR | |
41 }; | 42 }; |
42 | 43 |
43 | 44 |
44 // A DeclarationContext holds a reference to a v8::Context and keeps | 45 // A DeclarationContext holds a reference to a v8::Context and keeps |
45 // track of various declaration related counters to make it easier to | 46 // track of various declaration related counters to make it easier to |
46 // track if global declarations in the presence of interceptors behave | 47 // track if global declarations in the presence of interceptors behave |
47 // the right way. | 48 // the right way. |
48 class DeclarationContext { | 49 class DeclarationContext { |
49 public: | 50 public: |
50 DeclarationContext(); | 51 DeclarationContext(); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
88 const AccessorInfo& info); | 89 const AccessorInfo& info); |
89 static v8::Handle<Value> HandleSet(Local<String> key, | 90 static v8::Handle<Value> HandleSet(Local<String> key, |
90 Local<Value> value, | 91 Local<Value> value, |
91 const AccessorInfo& info); | 92 const AccessorInfo& info); |
92 static v8::Handle<Integer> HandleQuery(Local<String> key, | 93 static v8::Handle<Integer> HandleQuery(Local<String> key, |
93 const AccessorInfo& info); | 94 const AccessorInfo& info); |
94 | 95 |
95 private: | 96 private: |
96 bool is_initialized_; | 97 bool is_initialized_; |
97 Persistent<Context> context_; | 98 Persistent<Context> context_; |
98 Local<String> property_; | |
99 | 99 |
100 int get_count_; | 100 int get_count_; |
101 int set_count_; | 101 int set_count_; |
102 int query_count_; | 102 int query_count_; |
103 | 103 |
104 static DeclarationContext* GetInstance(const AccessorInfo& info); | 104 static DeclarationContext* GetInstance(const AccessorInfo& info); |
105 }; | 105 }; |
106 | 106 |
107 | 107 |
108 DeclarationContext::DeclarationContext() | 108 DeclarationContext::DeclarationContext() |
(...skipping 23 matching lines...) Expand all Loading... | |
132 int get, int set, int query, | 132 int get, int set, int query, |
133 Expectations expectations, | 133 Expectations expectations, |
134 v8::Handle<Value> value) { | 134 v8::Handle<Value> value) { |
135 InitializeIfNeeded(); | 135 InitializeIfNeeded(); |
136 // A retry after a GC may pollute the counts, so perform gc now | 136 // A retry after a GC may pollute the counts, so perform gc now |
137 // to avoid that. | 137 // to avoid that. |
138 HEAP->CollectGarbage(v8::internal::NEW_SPACE); | 138 HEAP->CollectGarbage(v8::internal::NEW_SPACE); |
139 HandleScope scope; | 139 HandleScope scope; |
140 TryCatch catcher; | 140 TryCatch catcher; |
141 catcher.SetVerbose(true); | 141 catcher.SetVerbose(true); |
142 Local<Value> result = Script::Compile(String::New(source))->Run(); | 142 Local<Script> script = Script::Compile(String::New(source)); |
143 if (expectations == EXPECT_ERROR) { | |
144 CHECK(script.IsEmpty()); | |
145 return; | |
146 } | |
147 CHECK(!script.IsEmpty()); | |
148 Local<Value> result = script->Run(); | |
143 CHECK_EQ(get, get_count()); | 149 CHECK_EQ(get, get_count()); |
144 CHECK_EQ(set, set_count()); | 150 CHECK_EQ(set, set_count()); |
145 CHECK_EQ(query, query_count()); | 151 CHECK_EQ(query, query_count()); |
146 if (expectations == EXPECT_RESULT) { | 152 if (expectations == EXPECT_RESULT) { |
147 CHECK(!catcher.HasCaught()); | 153 CHECK(!catcher.HasCaught()); |
148 if (!value.IsEmpty()) { | 154 if (!value.IsEmpty()) { |
149 CHECK_EQ(value, result); | 155 CHECK_EQ(value, result); |
150 } | 156 } |
151 } else { | 157 } else { |
152 CHECK(expectations == EXPECT_EXCEPTION); | 158 CHECK(expectations == EXPECT_EXCEPTION); |
(...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
674 | 680 |
675 // TODO(mstarzinger): The semantics of global const is vague. | 681 // TODO(mstarzinger): The semantics of global const is vague. |
676 { ExistsInHiddenPrototypeContext context; | 682 { ExistsInHiddenPrototypeContext context; |
677 context.Check("const x = 0; x", | 683 context.Check("const x = 0; x", |
678 0, | 684 0, |
679 0, | 685 0, |
680 1, // (re-)declaration | 686 1, // (re-)declaration |
681 EXPECT_RESULT, Number::New(0)); | 687 EXPECT_RESULT, Number::New(0)); |
682 } | 688 } |
683 } | 689 } |
690 | |
691 | |
692 | |
693 class SimpleContext { | |
694 public: | |
695 SimpleContext() { | |
696 context_ = Context::New(0); | |
697 context_->Enter(); | |
698 } | |
699 | |
700 virtual ~SimpleContext() { | |
701 context_->Exit(); | |
702 context_.Dispose(); | |
703 } | |
704 | |
705 void Check(const char* source, | |
706 Expectations expectations, | |
707 v8::Handle<Value> value = Local<Value>()) { | |
708 // A retry after a GC may pollute the counts, so perform gc now | |
709 // to avoid that. | |
710 HEAP->CollectGarbage(v8::internal::NEW_SPACE); | |
ulan
2012/08/23 16:10:17
Don't forget to remove it as we discussed offline.
| |
711 HandleScope scope; | |
712 TryCatch catcher; | |
713 catcher.SetVerbose(true); | |
714 Local<Script> script = Script::Compile(String::New(source)); | |
715 if (expectations == EXPECT_ERROR) { | |
716 CHECK(script.IsEmpty()); | |
717 return; | |
718 } | |
719 CHECK(!script.IsEmpty()); | |
720 Local<Value> result = script->Run(); | |
721 if (expectations == EXPECT_RESULT) { | |
722 CHECK(!catcher.HasCaught()); | |
723 if (!value.IsEmpty()) { | |
724 CHECK_EQ(value, result); | |
725 } | |
726 } else { | |
727 CHECK(expectations == EXPECT_EXCEPTION); | |
728 CHECK(catcher.HasCaught()); | |
729 if (!value.IsEmpty()) { | |
730 CHECK_EQ(value, catcher.Exception()); | |
731 } | |
732 } | |
733 } | |
734 | |
735 private: | |
736 Persistent<Context> context_; | |
737 }; | |
738 | |
739 | |
740 TEST(MultiScriptConflicts) { | |
741 HandleScope scope; | |
742 | |
743 { SimpleContext context; | |
744 context.Check("var x = 1; x", | |
745 EXPECT_RESULT, Number::New(1)); | |
746 context.Check("var x = 2; x", | |
747 EXPECT_RESULT, Number::New(2)); | |
748 context.Check("const x = 3; x", | |
749 EXPECT_RESULT, Number::New(3)); | |
750 context.Check("const x = 4; x", | |
751 EXPECT_RESULT, Number::New(4)); | |
752 context.Check("x = 5; x", | |
753 EXPECT_RESULT, Number::New(5)); | |
754 context.Check("var x = 6; x", | |
755 EXPECT_RESULT, Number::New(6)); | |
756 context.Check("this.x", | |
757 EXPECT_RESULT, Number::New(6)); | |
758 context.Check("function x() { return 7 }; x()", | |
759 EXPECT_RESULT, Number::New(7)); | |
760 } | |
761 | |
762 { SimpleContext context; | |
763 context.Check("const x = 1; x", | |
764 EXPECT_RESULT, Number::New(1)); | |
765 context.Check("var x = 2; x", // assignment ignored | |
766 EXPECT_RESULT, Number::New(1)); | |
767 context.Check("const x = 3; x", | |
768 EXPECT_RESULT, Number::New(1)); | |
769 context.Check("x = 4; x", // assignment ignored | |
770 EXPECT_RESULT, Number::New(1)); | |
771 context.Check("var x = 5; x", // assignment ignored | |
772 EXPECT_RESULT, Number::New(1)); | |
773 context.Check("this.x", | |
774 EXPECT_RESULT, Number::New(1)); | |
775 context.Check("function x() { return 7 }; x", | |
776 EXPECT_EXCEPTION); | |
777 } | |
778 | |
779 i::FLAG_use_strict = true; | |
780 i::FLAG_harmony_scoping = true; | |
781 | |
782 { SimpleContext context; | |
783 context.Check("var x = 1; x", | |
784 EXPECT_RESULT, Number::New(1)); | |
785 context.Check("x", | |
786 EXPECT_RESULT, Number::New(1)); | |
787 context.Check("this.x", | |
788 EXPECT_RESULT, Number::New(1)); | |
789 } | |
790 | |
791 { SimpleContext context; | |
792 context.Check("let x = 2; x", | |
793 EXPECT_RESULT, Number::New(2)); | |
794 context.Check("x", | |
795 EXPECT_RESULT, Number::New(2)); | |
796 context.Check("this.x", | |
797 EXPECT_RESULT, Number::New(2)); | |
798 } | |
799 | |
800 { SimpleContext context; | |
801 context.Check("const x = 3; x", | |
802 EXPECT_RESULT, Number::New(3)); | |
803 context.Check("x", | |
804 EXPECT_RESULT, Number::New(3)); | |
805 context.Check("this.x", | |
806 EXPECT_RESULT, Number::New(3)); | |
807 } | |
808 | |
809 { SimpleContext context; | |
810 context.Check("function x() { return 4 }; x()", | |
811 EXPECT_RESULT, Number::New(4)); | |
812 context.Check("x()", | |
813 EXPECT_RESULT, Number::New(4)); | |
814 context.Check("this.x()", | |
815 EXPECT_RESULT, Number::New(4)); | |
816 } | |
817 | |
818 // TODO(rossberg): All of the below should actually be errors in Harmony. | |
819 | |
820 { SimpleContext context; | |
821 context.Check("var x = 1; x", | |
822 EXPECT_RESULT, Number::New(1)); | |
823 context.Check("let x = 2; x", | |
824 EXPECT_RESULT, Number::New(2)); | |
825 } | |
826 | |
827 { SimpleContext context; | |
828 context.Check("var x = 1; x", | |
829 EXPECT_RESULT, Number::New(1)); | |
830 context.Check("const x = 2; x", | |
831 EXPECT_RESULT, Number::New(2)); | |
832 } | |
833 | |
834 { SimpleContext context; | |
835 context.Check("let x = 1; x", | |
836 EXPECT_RESULT, Number::New(1)); | |
837 context.Check("var x = 2; x", | |
838 EXPECT_RESULT, Number::New(2)); | |
839 } | |
840 | |
841 { SimpleContext context; | |
842 context.Check("let x = 1; x", | |
843 EXPECT_RESULT, Number::New(1)); | |
844 context.Check("let x = 2; x", | |
845 EXPECT_RESULT, Number::New(2)); | |
846 } | |
847 | |
848 { SimpleContext context; | |
849 context.Check("let x = 1; x", | |
850 EXPECT_RESULT, Number::New(1)); | |
851 context.Check("const x = 2; x", | |
852 EXPECT_RESULT, Number::New(2)); | |
853 } | |
854 | |
855 { SimpleContext context; | |
856 context.Check("let x = 1; x", | |
857 EXPECT_RESULT, Number::New(1)); | |
858 context.Check("function x() { return 2 }; x()", | |
859 EXPECT_RESULT, Number::New(2)); | |
860 } | |
861 | |
862 { SimpleContext context; | |
863 context.Check("const x = 1; x", | |
864 EXPECT_RESULT, Number::New(1)); | |
865 context.Check("var x = 2; x", | |
866 EXPECT_RESULT, Number::New(1)); | |
867 } | |
868 | |
869 { SimpleContext context; | |
870 context.Check("const x = 1; x", | |
871 EXPECT_RESULT, Number::New(1)); | |
872 context.Check("let x = 2; x", | |
873 EXPECT_EXCEPTION); | |
874 } | |
875 | |
876 { SimpleContext context; | |
877 context.Check("const x = 1; x", | |
878 EXPECT_RESULT, Number::New(1)); | |
879 context.Check("const x = 2; x", | |
880 EXPECT_RESULT, Number::New(1)); | |
881 } | |
882 | |
883 { SimpleContext context; | |
884 context.Check("const x = 1; x", | |
885 EXPECT_RESULT, Number::New(1)); | |
886 context.Check("function x() { return 2 }; x()", | |
887 EXPECT_EXCEPTION); | |
888 } | |
889 | |
890 { SimpleContext context; | |
891 context.Check("function x() { return 1 }; x()", | |
892 EXPECT_RESULT, Number::New(1)); | |
893 context.Check("let x = 2; x", | |
894 EXPECT_RESULT, Number::New(2)); | |
895 } | |
896 | |
897 { SimpleContext context; | |
898 context.Check("function x() { return 1 }; x()", | |
899 EXPECT_RESULT, Number::New(1)); | |
900 context.Check("const x = 2; x", | |
901 EXPECT_RESULT, Number::New(2)); | |
902 } | |
903 } | |
OLD | NEW |