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 HandleScope scope; |
| 709 TryCatch catcher; |
| 710 catcher.SetVerbose(true); |
| 711 Local<Script> script = Script::Compile(String::New(source)); |
| 712 if (expectations == EXPECT_ERROR) { |
| 713 CHECK(script.IsEmpty()); |
| 714 return; |
| 715 } |
| 716 CHECK(!script.IsEmpty()); |
| 717 Local<Value> result = script->Run(); |
| 718 if (expectations == EXPECT_RESULT) { |
| 719 CHECK(!catcher.HasCaught()); |
| 720 if (!value.IsEmpty()) { |
| 721 CHECK_EQ(value, result); |
| 722 } |
| 723 } else { |
| 724 CHECK(expectations == EXPECT_EXCEPTION); |
| 725 CHECK(catcher.HasCaught()); |
| 726 if (!value.IsEmpty()) { |
| 727 CHECK_EQ(value, catcher.Exception()); |
| 728 } |
| 729 } |
| 730 } |
| 731 |
| 732 private: |
| 733 Persistent<Context> context_; |
| 734 }; |
| 735 |
| 736 |
| 737 TEST(MultiScriptConflicts) { |
| 738 HandleScope scope; |
| 739 |
| 740 { SimpleContext context; |
| 741 context.Check("var x = 1; x", |
| 742 EXPECT_RESULT, Number::New(1)); |
| 743 context.Check("var x = 2; x", |
| 744 EXPECT_RESULT, Number::New(2)); |
| 745 context.Check("const x = 3; x", |
| 746 EXPECT_RESULT, Number::New(3)); |
| 747 context.Check("const x = 4; x", |
| 748 EXPECT_RESULT, Number::New(4)); |
| 749 context.Check("x = 5; x", |
| 750 EXPECT_RESULT, Number::New(5)); |
| 751 context.Check("var x = 6; x", |
| 752 EXPECT_RESULT, Number::New(6)); |
| 753 context.Check("this.x", |
| 754 EXPECT_RESULT, Number::New(6)); |
| 755 context.Check("function x() { return 7 }; x()", |
| 756 EXPECT_RESULT, Number::New(7)); |
| 757 } |
| 758 |
| 759 { SimpleContext context; |
| 760 context.Check("const x = 1; x", |
| 761 EXPECT_RESULT, Number::New(1)); |
| 762 context.Check("var x = 2; x", // assignment ignored |
| 763 EXPECT_RESULT, Number::New(1)); |
| 764 context.Check("const x = 3; x", |
| 765 EXPECT_RESULT, Number::New(1)); |
| 766 context.Check("x = 4; x", // assignment ignored |
| 767 EXPECT_RESULT, Number::New(1)); |
| 768 context.Check("var x = 5; x", // assignment ignored |
| 769 EXPECT_RESULT, Number::New(1)); |
| 770 context.Check("this.x", |
| 771 EXPECT_RESULT, Number::New(1)); |
| 772 context.Check("function x() { return 7 }; x", |
| 773 EXPECT_EXCEPTION); |
| 774 } |
| 775 |
| 776 i::FLAG_use_strict = true; |
| 777 i::FLAG_harmony_scoping = true; |
| 778 |
| 779 { SimpleContext context; |
| 780 context.Check("var x = 1; x", |
| 781 EXPECT_RESULT, Number::New(1)); |
| 782 context.Check("x", |
| 783 EXPECT_RESULT, Number::New(1)); |
| 784 context.Check("this.x", |
| 785 EXPECT_RESULT, Number::New(1)); |
| 786 } |
| 787 |
| 788 { SimpleContext context; |
| 789 context.Check("let x = 2; x", |
| 790 EXPECT_RESULT, Number::New(2)); |
| 791 context.Check("x", |
| 792 EXPECT_RESULT, Number::New(2)); |
| 793 context.Check("this.x", |
| 794 EXPECT_RESULT, Number::New(2)); |
| 795 } |
| 796 |
| 797 { SimpleContext context; |
| 798 context.Check("const x = 3; x", |
| 799 EXPECT_RESULT, Number::New(3)); |
| 800 context.Check("x", |
| 801 EXPECT_RESULT, Number::New(3)); |
| 802 context.Check("this.x", |
| 803 EXPECT_RESULT, Number::New(3)); |
| 804 } |
| 805 |
| 806 { SimpleContext context; |
| 807 context.Check("function x() { return 4 }; x()", |
| 808 EXPECT_RESULT, Number::New(4)); |
| 809 context.Check("x()", |
| 810 EXPECT_RESULT, Number::New(4)); |
| 811 context.Check("this.x()", |
| 812 EXPECT_RESULT, Number::New(4)); |
| 813 } |
| 814 |
| 815 // TODO(rossberg): All of the below should actually be errors in Harmony. |
| 816 |
| 817 { SimpleContext context; |
| 818 context.Check("var x = 1; x", |
| 819 EXPECT_RESULT, Number::New(1)); |
| 820 context.Check("let x = 2; x", |
| 821 EXPECT_RESULT, Number::New(2)); |
| 822 } |
| 823 |
| 824 { SimpleContext context; |
| 825 context.Check("var x = 1; x", |
| 826 EXPECT_RESULT, Number::New(1)); |
| 827 context.Check("const x = 2; x", |
| 828 EXPECT_RESULT, Number::New(2)); |
| 829 } |
| 830 |
| 831 { SimpleContext context; |
| 832 context.Check("function x() { return 1 }; x()", |
| 833 EXPECT_RESULT, Number::New(1)); |
| 834 context.Check("let x = 2; x", |
| 835 EXPECT_RESULT, Number::New(2)); |
| 836 } |
| 837 |
| 838 { SimpleContext context; |
| 839 context.Check("function x() { return 1 }; x()", |
| 840 EXPECT_RESULT, Number::New(1)); |
| 841 context.Check("const x = 2; x", |
| 842 EXPECT_RESULT, Number::New(2)); |
| 843 } |
| 844 |
| 845 { SimpleContext context; |
| 846 context.Check("let x = 1; x", |
| 847 EXPECT_RESULT, Number::New(1)); |
| 848 context.Check("var x = 2; x", |
| 849 EXPECT_RESULT, Number::New(2)); |
| 850 } |
| 851 |
| 852 { SimpleContext context; |
| 853 context.Check("let x = 1; x", |
| 854 EXPECT_RESULT, Number::New(1)); |
| 855 context.Check("let x = 2; x", |
| 856 EXPECT_RESULT, Number::New(2)); |
| 857 } |
| 858 |
| 859 { SimpleContext context; |
| 860 context.Check("let x = 1; x", |
| 861 EXPECT_RESULT, Number::New(1)); |
| 862 context.Check("const x = 2; x", |
| 863 EXPECT_RESULT, Number::New(2)); |
| 864 } |
| 865 |
| 866 { SimpleContext context; |
| 867 context.Check("let x = 1; x", |
| 868 EXPECT_RESULT, Number::New(1)); |
| 869 context.Check("function x() { return 2 }; x()", |
| 870 EXPECT_RESULT, Number::New(2)); |
| 871 } |
| 872 |
| 873 { SimpleContext context; |
| 874 context.Check("const x = 1; x", |
| 875 EXPECT_RESULT, Number::New(1)); |
| 876 context.Check("var x = 2; x", |
| 877 EXPECT_RESULT, Number::New(1)); |
| 878 } |
| 879 |
| 880 { SimpleContext context; |
| 881 context.Check("const x = 1; x", |
| 882 EXPECT_RESULT, Number::New(1)); |
| 883 context.Check("let x = 2; x", |
| 884 EXPECT_EXCEPTION); |
| 885 } |
| 886 |
| 887 { SimpleContext context; |
| 888 context.Check("const x = 1; x", |
| 889 EXPECT_RESULT, Number::New(1)); |
| 890 context.Check("const x = 2; x", |
| 891 EXPECT_RESULT, Number::New(1)); |
| 892 } |
| 893 |
| 894 { SimpleContext context; |
| 895 context.Check("const x = 1; x", |
| 896 EXPECT_RESULT, Number::New(1)); |
| 897 context.Check("function x() { return 2 }; x()", |
| 898 EXPECT_EXCEPTION); |
| 899 } |
| 900 } |
OLD | NEW |