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 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
45 // A DeclarationContext holds a reference to a v8::Context and keeps | 45 // A DeclarationContext holds a reference to a v8::Context and keeps |
46 // track of various declaration related counters to make it easier to | 46 // track of various declaration related counters to make it easier to |
47 // track if global declarations in the presence of interceptors behave | 47 // track if global declarations in the presence of interceptors behave |
48 // the right way. | 48 // the right way. |
49 class DeclarationContext { | 49 class DeclarationContext { |
50 public: | 50 public: |
51 DeclarationContext(); | 51 DeclarationContext(); |
52 | 52 |
53 virtual ~DeclarationContext() { | 53 virtual ~DeclarationContext() { |
54 if (is_initialized_) { | 54 if (is_initialized_) { |
55 Isolate* isolate = Isolate::GetCurrent(); | 55 Isolate* isolate = CcTest::isolate(); |
56 HandleScope scope(isolate); | 56 HandleScope scope(isolate); |
57 Local<Context> context = Local<Context>::New(isolate, context_); | 57 Local<Context> context = Local<Context>::New(isolate, context_); |
58 context->Exit(); | 58 context->Exit(); |
59 context_.Dispose(); | 59 context_.Dispose(); |
60 } | 60 } |
61 } | 61 } |
62 | 62 |
63 void Check(const char* source, | 63 void Check(const char* source, |
64 int get, int set, int has, | 64 int get, int set, int has, |
65 Expectations expectations, | 65 Expectations expectations, |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
109 | 109 |
110 | 110 |
111 DeclarationContext::DeclarationContext() | 111 DeclarationContext::DeclarationContext() |
112 : is_initialized_(false), get_count_(0), set_count_(0), query_count_(0) { | 112 : is_initialized_(false), get_count_(0), set_count_(0), query_count_(0) { |
113 // Do nothing. | 113 // Do nothing. |
114 } | 114 } |
115 | 115 |
116 | 116 |
117 void DeclarationContext::InitializeIfNeeded() { | 117 void DeclarationContext::InitializeIfNeeded() { |
118 if (is_initialized_) return; | 118 if (is_initialized_) return; |
119 Isolate* isolate = Isolate::GetCurrent(); | 119 Isolate* isolate = CcTest::isolate(); |
120 HandleScope scope(isolate); | 120 HandleScope scope(isolate); |
121 Local<FunctionTemplate> function = FunctionTemplate::New(); | 121 Local<FunctionTemplate> function = FunctionTemplate::New(); |
122 Local<Value> data = External::New(this); | 122 Local<Value> data = External::New(this); |
123 GetHolder(function)->SetNamedPropertyHandler(&HandleGet, | 123 GetHolder(function)->SetNamedPropertyHandler(&HandleGet, |
124 &HandleSet, | 124 &HandleSet, |
125 &HandleQuery, | 125 &HandleQuery, |
126 0, 0, | 126 0, 0, |
127 data); | 127 data); |
128 Local<Context> context = Context::New(isolate, | 128 Local<Context> context = Context::New(isolate, |
129 0, | 129 0, |
130 function->InstanceTemplate(), | 130 function->InstanceTemplate(), |
131 Local<Value>()); | 131 Local<Value>()); |
132 context_.Reset(isolate, context); | 132 context_.Reset(isolate, context); |
133 context->Enter(); | 133 context->Enter(); |
134 is_initialized_ = true; | 134 is_initialized_ = true; |
135 PostInitializeContext(context); | 135 PostInitializeContext(context); |
136 } | 136 } |
137 | 137 |
138 | 138 |
139 void DeclarationContext::Check(const char* source, | 139 void DeclarationContext::Check(const char* source, |
140 int get, int set, int query, | 140 int get, int set, int query, |
141 Expectations expectations, | 141 Expectations expectations, |
142 v8::Handle<Value> value) { | 142 v8::Handle<Value> value) { |
143 InitializeIfNeeded(); | 143 InitializeIfNeeded(); |
144 // A retry after a GC may pollute the counts, so perform gc now | 144 // A retry after a GC may pollute the counts, so perform gc now |
145 // to avoid that. | 145 // to avoid that. |
146 HEAP->CollectGarbage(v8::internal::NEW_SPACE); | 146 HEAP->CollectGarbage(v8::internal::NEW_SPACE); |
147 HandleScope scope(Isolate::GetCurrent()); | 147 HandleScope scope(CcTest::isolate()); |
148 TryCatch catcher; | 148 TryCatch catcher; |
149 catcher.SetVerbose(true); | 149 catcher.SetVerbose(true); |
150 Local<Script> script = Script::Compile(String::New(source)); | 150 Local<Script> script = Script::Compile(String::New(source)); |
151 if (expectations == EXPECT_ERROR) { | 151 if (expectations == EXPECT_ERROR) { |
152 CHECK(script.IsEmpty()); | 152 CHECK(script.IsEmpty()); |
153 return; | 153 return; |
154 } | 154 } |
155 CHECK(!script.IsEmpty()); | 155 CHECK(!script.IsEmpty()); |
156 Local<Value> result = script->Run(); | 156 Local<Value> result = script->Run(); |
157 CHECK_EQ(get, get_count()); | 157 CHECK_EQ(get, get_count()); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
219 | 219 |
220 | 220 |
221 v8::Handle<Integer> DeclarationContext::Query(Local<String> key) { | 221 v8::Handle<Integer> DeclarationContext::Query(Local<String> key) { |
222 return v8::Handle<Integer>(); | 222 return v8::Handle<Integer>(); |
223 } | 223 } |
224 | 224 |
225 | 225 |
226 // Test global declaration of a property the interceptor doesn't know | 226 // Test global declaration of a property the interceptor doesn't know |
227 // about and doesn't handle. | 227 // about and doesn't handle. |
228 TEST(Unknown) { | 228 TEST(Unknown) { |
229 HandleScope scope(Isolate::GetCurrent()); | 229 HandleScope scope(CcTest::isolate()); |
230 | 230 |
231 { DeclarationContext context; | 231 { DeclarationContext context; |
232 context.Check("var x; x", | 232 context.Check("var x; x", |
233 1, // access | 233 1, // access |
234 1, // declaration | 234 1, // declaration |
235 2, // declaration + initialization | 235 2, // declaration + initialization |
236 EXPECT_RESULT, Undefined()); | 236 EXPECT_RESULT, Undefined()); |
237 } | 237 } |
238 | 238 |
239 { DeclarationContext context; | 239 { DeclarationContext context; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
274 class PresentPropertyContext: public DeclarationContext { | 274 class PresentPropertyContext: public DeclarationContext { |
275 protected: | 275 protected: |
276 virtual v8::Handle<Integer> Query(Local<String> key) { | 276 virtual v8::Handle<Integer> Query(Local<String> key) { |
277 return Integer::New(v8::None); | 277 return Integer::New(v8::None); |
278 } | 278 } |
279 }; | 279 }; |
280 | 280 |
281 | 281 |
282 | 282 |
283 TEST(Present) { | 283 TEST(Present) { |
284 HandleScope scope(Isolate::GetCurrent()); | 284 HandleScope scope(CcTest::isolate()); |
285 | 285 |
286 { PresentPropertyContext context; | 286 { PresentPropertyContext context; |
287 context.Check("var x; x", | 287 context.Check("var x; x", |
288 1, // access | 288 1, // access |
289 0, | 289 0, |
290 2, // declaration + initialization | 290 2, // declaration + initialization |
291 EXPECT_EXCEPTION); // x is not defined! | 291 EXPECT_EXCEPTION); // x is not defined! |
292 } | 292 } |
293 | 293 |
294 { PresentPropertyContext context; | 294 { PresentPropertyContext context; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
328 | 328 |
329 class AbsentPropertyContext: public DeclarationContext { | 329 class AbsentPropertyContext: public DeclarationContext { |
330 protected: | 330 protected: |
331 virtual v8::Handle<Integer> Query(Local<String> key) { | 331 virtual v8::Handle<Integer> Query(Local<String> key) { |
332 return v8::Handle<Integer>(); | 332 return v8::Handle<Integer>(); |
333 } | 333 } |
334 }; | 334 }; |
335 | 335 |
336 | 336 |
337 TEST(Absent) { | 337 TEST(Absent) { |
338 HandleScope scope(Isolate::GetCurrent()); | 338 HandleScope scope(CcTest::isolate()); |
339 | 339 |
340 { AbsentPropertyContext context; | 340 { AbsentPropertyContext context; |
341 context.Check("var x; x", | 341 context.Check("var x; x", |
342 1, // access | 342 1, // access |
343 1, // declaration | 343 1, // declaration |
344 2, // declaration + initialization | 344 2, // declaration + initialization |
345 EXPECT_RESULT, Undefined()); | 345 EXPECT_RESULT, Undefined()); |
346 } | 346 } |
347 | 347 |
348 { AbsentPropertyContext context; | 348 { AbsentPropertyContext context; |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
418 // Do the lookup in the object. | 418 // Do the lookup in the object. |
419 return v8::Handle<Integer>(); | 419 return v8::Handle<Integer>(); |
420 } | 420 } |
421 | 421 |
422 private: | 422 private: |
423 State state_; | 423 State state_; |
424 }; | 424 }; |
425 | 425 |
426 | 426 |
427 TEST(Appearing) { | 427 TEST(Appearing) { |
428 HandleScope scope(Isolate::GetCurrent()); | 428 HandleScope scope(CcTest::isolate()); |
429 | 429 |
430 { AppearingPropertyContext context; | 430 { AppearingPropertyContext context; |
431 context.Check("var x; x", | 431 context.Check("var x; x", |
432 1, // access | 432 1, // access |
433 1, // declaration | 433 1, // declaration |
434 2, // declaration + initialization | 434 2, // declaration + initialization |
435 EXPECT_RESULT, Undefined()); | 435 EXPECT_RESULT, Undefined()); |
436 } | 436 } |
437 | 437 |
438 { AppearingPropertyContext context; | 438 { AppearingPropertyContext context; |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
510 // Do the lookup in the object. | 510 // Do the lookup in the object. |
511 return Handle<Integer>(); | 511 return Handle<Integer>(); |
512 } | 512 } |
513 | 513 |
514 private: | 514 private: |
515 State state_; | 515 State state_; |
516 }; | 516 }; |
517 | 517 |
518 | 518 |
519 TEST(Reappearing) { | 519 TEST(Reappearing) { |
520 HandleScope scope(Isolate::GetCurrent()); | 520 HandleScope scope(CcTest::isolate()); |
521 | 521 |
522 { ReappearingPropertyContext context; | 522 { ReappearingPropertyContext context; |
523 context.Check("const x; var x = 0", | 523 context.Check("const x; var x = 0", |
524 0, | 524 0, |
525 3, // const declaration+initialization, var initialization | 525 3, // const declaration+initialization, var initialization |
526 3, // 2 x declaration + var initialization | 526 3, // 2 x declaration + var initialization |
527 EXPECT_RESULT, Undefined()); | 527 EXPECT_RESULT, Undefined()); |
528 } | 528 } |
529 } | 529 } |
530 | 530 |
531 | 531 |
532 | 532 |
533 class ExistsInPrototypeContext: public DeclarationContext { | 533 class ExistsInPrototypeContext: public DeclarationContext { |
534 protected: | 534 protected: |
535 virtual v8::Handle<Integer> Query(Local<String> key) { | 535 virtual v8::Handle<Integer> Query(Local<String> key) { |
536 // Let it seem that the property exists in the prototype object. | 536 // Let it seem that the property exists in the prototype object. |
537 return Integer::New(v8::None); | 537 return Integer::New(v8::None); |
538 } | 538 } |
539 | 539 |
540 // Use the prototype as the holder for the interceptors. | 540 // Use the prototype as the holder for the interceptors. |
541 virtual Local<ObjectTemplate> GetHolder(Local<FunctionTemplate> function) { | 541 virtual Local<ObjectTemplate> GetHolder(Local<FunctionTemplate> function) { |
542 return function->PrototypeTemplate(); | 542 return function->PrototypeTemplate(); |
543 } | 543 } |
544 }; | 544 }; |
545 | 545 |
546 | 546 |
547 TEST(ExistsInPrototype) { | 547 TEST(ExistsInPrototype) { |
548 i::FLAG_es52_globals = true; | 548 i::FLAG_es52_globals = true; |
549 HandleScope scope(Isolate::GetCurrent()); | 549 HandleScope scope(CcTest::isolate()); |
550 | 550 |
551 // Sanity check to make sure that the holder of the interceptor | 551 // Sanity check to make sure that the holder of the interceptor |
552 // really is the prototype object. | 552 // really is the prototype object. |
553 { ExistsInPrototypeContext context; | 553 { ExistsInPrototypeContext context; |
554 context.Check("this.x = 87; this.x", | 554 context.Check("this.x = 87; this.x", |
555 0, | 555 0, |
556 0, | 556 0, |
557 0, | 557 0, |
558 EXPECT_RESULT, Number::New(87)); | 558 EXPECT_RESULT, Number::New(87)); |
559 } | 559 } |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
602 | 602 |
603 // Use the prototype as the holder for the interceptors. | 603 // Use the prototype as the holder for the interceptors. |
604 virtual Local<ObjectTemplate> GetHolder(Local<FunctionTemplate> function) { | 604 virtual Local<ObjectTemplate> GetHolder(Local<FunctionTemplate> function) { |
605 return function->PrototypeTemplate(); | 605 return function->PrototypeTemplate(); |
606 } | 606 } |
607 }; | 607 }; |
608 | 608 |
609 | 609 |
610 TEST(AbsentInPrototype) { | 610 TEST(AbsentInPrototype) { |
611 i::FLAG_es52_globals = true; | 611 i::FLAG_es52_globals = true; |
612 HandleScope scope(Isolate::GetCurrent()); | 612 HandleScope scope(CcTest::isolate()); |
613 | 613 |
614 { AbsentInPrototypeContext context; | 614 { AbsentInPrototypeContext context; |
615 context.Check("if (false) { var x = 0; }; x", | 615 context.Check("if (false) { var x = 0; }; x", |
616 0, | 616 0, |
617 0, | 617 0, |
618 0, | 618 0, |
619 EXPECT_RESULT, Undefined()); | 619 EXPECT_RESULT, Undefined()); |
620 } | 620 } |
621 } | 621 } |
622 | 622 |
(...skipping 26 matching lines...) Expand all Loading... |
649 return hidden_proto_->InstanceTemplate(); | 649 return hidden_proto_->InstanceTemplate(); |
650 } | 650 } |
651 | 651 |
652 private: | 652 private: |
653 Local<FunctionTemplate> hidden_proto_; | 653 Local<FunctionTemplate> hidden_proto_; |
654 }; | 654 }; |
655 | 655 |
656 | 656 |
657 TEST(ExistsInHiddenPrototype) { | 657 TEST(ExistsInHiddenPrototype) { |
658 i::FLAG_es52_globals = true; | 658 i::FLAG_es52_globals = true; |
659 HandleScope scope(Isolate::GetCurrent()); | 659 HandleScope scope(CcTest::isolate()); |
660 | 660 |
661 { ExistsInHiddenPrototypeContext context; | 661 { ExistsInHiddenPrototypeContext context; |
662 context.Check("var x; x", | 662 context.Check("var x; x", |
663 1, // access | 663 1, // access |
664 0, | 664 0, |
665 2, // declaration + initialization | 665 2, // declaration + initialization |
666 EXPECT_EXCEPTION); // x is not defined! | 666 EXPECT_EXCEPTION); // x is not defined! |
667 } | 667 } |
668 | 668 |
669 { ExistsInHiddenPrototypeContext context; | 669 { ExistsInHiddenPrototypeContext context; |
(...skipping 29 matching lines...) Expand all Loading... |
699 1, // (re-)declaration | 699 1, // (re-)declaration |
700 EXPECT_RESULT, Number::New(0)); | 700 EXPECT_RESULT, Number::New(0)); |
701 } | 701 } |
702 } | 702 } |
703 | 703 |
704 | 704 |
705 | 705 |
706 class SimpleContext { | 706 class SimpleContext { |
707 public: | 707 public: |
708 SimpleContext() | 708 SimpleContext() |
709 : handle_scope_(Isolate::GetCurrent()), | 709 : handle_scope_(CcTest::isolate()), |
710 context_(Context::New(Isolate::GetCurrent())) { | 710 context_(Context::New(CcTest::isolate())) { |
711 context_->Enter(); | 711 context_->Enter(); |
712 } | 712 } |
713 | 713 |
714 ~SimpleContext() { | 714 ~SimpleContext() { |
715 context_->Exit(); | 715 context_->Exit(); |
716 } | 716 } |
717 | 717 |
718 void Check(const char* source, | 718 void Check(const char* source, |
719 Expectations expectations, | 719 Expectations expectations, |
720 v8::Handle<Value> value = Local<Value>()) { | 720 v8::Handle<Value> value = Local<Value>()) { |
(...skipping 21 matching lines...) Expand all Loading... |
742 } | 742 } |
743 } | 743 } |
744 | 744 |
745 private: | 745 private: |
746 HandleScope handle_scope_; | 746 HandleScope handle_scope_; |
747 Local<Context> context_; | 747 Local<Context> context_; |
748 }; | 748 }; |
749 | 749 |
750 | 750 |
751 TEST(CrossScriptReferences) { | 751 TEST(CrossScriptReferences) { |
752 HandleScope scope(Isolate::GetCurrent()); | 752 HandleScope scope(CcTest::isolate()); |
753 | 753 |
754 { SimpleContext context; | 754 { SimpleContext context; |
755 context.Check("var x = 1; x", | 755 context.Check("var x = 1; x", |
756 EXPECT_RESULT, Number::New(1)); | 756 EXPECT_RESULT, Number::New(1)); |
757 context.Check("var x = 2; x", | 757 context.Check("var x = 2; x", |
758 EXPECT_RESULT, Number::New(2)); | 758 EXPECT_RESULT, Number::New(2)); |
759 context.Check("const x = 3; x", | 759 context.Check("const x = 3; x", |
760 EXPECT_RESULT, Number::New(3)); | 760 EXPECT_RESULT, Number::New(3)); |
761 context.Check("const x = 4; x", | 761 context.Check("const x = 4; x", |
762 EXPECT_RESULT, Number::New(4)); | 762 EXPECT_RESULT, Number::New(4)); |
(...skipping 24 matching lines...) Expand all Loading... |
787 EXPECT_EXCEPTION); | 787 EXPECT_EXCEPTION); |
788 } | 788 } |
789 } | 789 } |
790 | 790 |
791 | 791 |
792 TEST(CrossScriptReferencesHarmony) { | 792 TEST(CrossScriptReferencesHarmony) { |
793 i::FLAG_use_strict = true; | 793 i::FLAG_use_strict = true; |
794 i::FLAG_harmony_scoping = true; | 794 i::FLAG_harmony_scoping = true; |
795 i::FLAG_harmony_modules = true; | 795 i::FLAG_harmony_modules = true; |
796 | 796 |
797 HandleScope scope(Isolate::GetCurrent()); | 797 HandleScope scope(CcTest::isolate()); |
798 | 798 |
799 const char* decs[] = { | 799 const char* decs[] = { |
800 "var x = 1; x", "x", "this.x", | 800 "var x = 1; x", "x", "this.x", |
801 "function x() { return 1 }; x()", "x()", "this.x()", | 801 "function x() { return 1 }; x()", "x()", "this.x()", |
802 "let x = 1; x", "x", "this.x", | 802 "let x = 1; x", "x", "this.x", |
803 "const x = 1; x", "x", "this.x", | 803 "const x = 1; x", "x", "this.x", |
804 "module x { export let a = 1 }; x.a", "x.a", "this.x.a", | 804 "module x { export let a = 1 }; x.a", "x.a", "this.x.a", |
805 NULL | 805 NULL |
806 }; | 806 }; |
807 | 807 |
808 for (int i = 0; decs[i] != NULL; i += 3) { | 808 for (int i = 0; decs[i] != NULL; i += 3) { |
809 SimpleContext context; | 809 SimpleContext context; |
810 context.Check(decs[i], EXPECT_RESULT, Number::New(1)); | 810 context.Check(decs[i], EXPECT_RESULT, Number::New(1)); |
811 context.Check(decs[i+1], EXPECT_RESULT, Number::New(1)); | 811 context.Check(decs[i+1], EXPECT_RESULT, Number::New(1)); |
812 // TODO(rossberg): The current ES6 draft spec does not reflect lexical | 812 // TODO(rossberg): The current ES6 draft spec does not reflect lexical |
813 // bindings on the global object. However, this will probably change, in | 813 // bindings on the global object. However, this will probably change, in |
814 // which case we reactivate the following test. | 814 // which case we reactivate the following test. |
815 if (i/3 < 2) context.Check(decs[i+2], EXPECT_RESULT, Number::New(1)); | 815 if (i/3 < 2) context.Check(decs[i+2], EXPECT_RESULT, Number::New(1)); |
816 } | 816 } |
817 } | 817 } |
818 | 818 |
819 | 819 |
820 TEST(CrossScriptConflicts) { | 820 TEST(CrossScriptConflicts) { |
821 i::FLAG_use_strict = true; | 821 i::FLAG_use_strict = true; |
822 i::FLAG_harmony_scoping = true; | 822 i::FLAG_harmony_scoping = true; |
823 i::FLAG_harmony_modules = true; | 823 i::FLAG_harmony_modules = true; |
824 | 824 |
825 HandleScope scope(Isolate::GetCurrent()); | 825 HandleScope scope(CcTest::isolate()); |
826 | 826 |
827 const char* firsts[] = { | 827 const char* firsts[] = { |
828 "var x = 1; x", | 828 "var x = 1; x", |
829 "function x() { return 1 }; x()", | 829 "function x() { return 1 }; x()", |
830 "let x = 1; x", | 830 "let x = 1; x", |
831 "const x = 1; x", | 831 "const x = 1; x", |
832 "module x { export let a = 1 }; x.a", | 832 "module x { export let a = 1 }; x.a", |
833 NULL | 833 NULL |
834 }; | 834 }; |
835 const char* seconds[] = { | 835 const char* seconds[] = { |
(...skipping 10 matching lines...) Expand all Loading... |
846 SimpleContext context; | 846 SimpleContext context; |
847 context.Check(firsts[i], EXPECT_RESULT, Number::New(1)); | 847 context.Check(firsts[i], EXPECT_RESULT, Number::New(1)); |
848 // TODO(rossberg): All tests should actually be errors in Harmony, | 848 // TODO(rossberg): All tests should actually be errors in Harmony, |
849 // but we currently do not detect the cases where the first declaration | 849 // but we currently do not detect the cases where the first declaration |
850 // is not lexical. | 850 // is not lexical. |
851 context.Check(seconds[j], | 851 context.Check(seconds[j], |
852 i < 2 ? EXPECT_RESULT : EXPECT_ERROR, Number::New(2)); | 852 i < 2 ? EXPECT_RESULT : EXPECT_ERROR, Number::New(2)); |
853 } | 853 } |
854 } | 854 } |
855 } | 855 } |
OLD | NEW |