Chromium Code Reviews| 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 |