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 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
65 int set_count() const { return set_count_; } | 65 int set_count() const { return set_count_; } |
66 int query_count() const { return query_count_; } | 66 int query_count() const { return query_count_; } |
67 | 67 |
68 protected: | 68 protected: |
69 virtual v8::Handle<Value> Get(Local<String> key); | 69 virtual v8::Handle<Value> Get(Local<String> key); |
70 virtual v8::Handle<Value> Set(Local<String> key, Local<Value> value); | 70 virtual v8::Handle<Value> Set(Local<String> key, Local<Value> value); |
71 virtual v8::Handle<Integer> Query(Local<String> key); | 71 virtual v8::Handle<Integer> Query(Local<String> key); |
72 | 72 |
73 void InitializeIfNeeded(); | 73 void InitializeIfNeeded(); |
74 | 74 |
| 75 // Perform optional initialization steps on the context after it has |
| 76 // been created. Defaults to none but may be overwritten. |
| 77 virtual void PostInitializeContext(Handle<Context> context) {} |
| 78 |
75 // Get the holder for the interceptor. Default to the instance template | 79 // Get the holder for the interceptor. Default to the instance template |
76 // but may be overwritten. | 80 // but may be overwritten. |
77 virtual Local<ObjectTemplate> GetHolder(Local<FunctionTemplate> function) { | 81 virtual Local<ObjectTemplate> GetHolder(Local<FunctionTemplate> function) { |
78 return function->InstanceTemplate(); | 82 return function->InstanceTemplate(); |
79 } | 83 } |
80 | 84 |
81 // The handlers are called as static functions that forward | 85 // The handlers are called as static functions that forward |
82 // to the instance specific virtual methods. | 86 // to the instance specific virtual methods. |
83 static v8::Handle<Value> HandleGet(Local<String> key, | 87 static v8::Handle<Value> HandleGet(Local<String> key, |
84 const AccessorInfo& info); | 88 const AccessorInfo& info); |
(...skipping 28 matching lines...) Expand all Loading... |
113 Local<FunctionTemplate> function = FunctionTemplate::New(); | 117 Local<FunctionTemplate> function = FunctionTemplate::New(); |
114 Local<Value> data = External::New(this); | 118 Local<Value> data = External::New(this); |
115 GetHolder(function)->SetNamedPropertyHandler(&HandleGet, | 119 GetHolder(function)->SetNamedPropertyHandler(&HandleGet, |
116 &HandleSet, | 120 &HandleSet, |
117 &HandleQuery, | 121 &HandleQuery, |
118 0, 0, | 122 0, 0, |
119 data); | 123 data); |
120 context_ = Context::New(0, function->InstanceTemplate(), Local<Value>()); | 124 context_ = Context::New(0, function->InstanceTemplate(), Local<Value>()); |
121 context_->Enter(); | 125 context_->Enter(); |
122 is_initialized_ = true; | 126 is_initialized_ = true; |
| 127 PostInitializeContext(context_); |
123 } | 128 } |
124 | 129 |
125 | 130 |
126 void DeclarationContext::Check(const char* source, | 131 void DeclarationContext::Check(const char* source, |
127 int get, int set, int query, | 132 int get, int set, int query, |
128 Expectations expectations, | 133 Expectations expectations, |
129 v8::Handle<Value> value) { | 134 v8::Handle<Value> value) { |
130 InitializeIfNeeded(); | 135 InitializeIfNeeded(); |
131 // 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 |
132 // to avoid that. | 137 // to avoid that. |
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
529 { ExistsInPrototypeContext context; | 534 { ExistsInPrototypeContext context; |
530 context.Check("this.x = 87; this.x", | 535 context.Check("this.x = 87; this.x", |
531 0, | 536 0, |
532 0, | 537 0, |
533 0, | 538 0, |
534 EXPECT_RESULT, Number::New(87)); | 539 EXPECT_RESULT, Number::New(87)); |
535 } | 540 } |
536 | 541 |
537 { ExistsInPrototypeContext context; | 542 { ExistsInPrototypeContext context; |
538 context.Check("var x; x", | 543 context.Check("var x; x", |
539 0, // get | |
540 0, | 544 0, |
541 0, // declaration | 545 0, |
| 546 0, |
542 EXPECT_RESULT, Undefined()); | 547 EXPECT_RESULT, Undefined()); |
543 } | 548 } |
544 | 549 |
545 { ExistsInPrototypeContext context; | 550 { ExistsInPrototypeContext context; |
546 context.Check("var x = 0; x", | 551 context.Check("var x = 0; x", |
547 0, | 552 0, |
548 0, | 553 0, |
549 0, // declaration | 554 0, |
550 EXPECT_RESULT, Number::New(0)); | 555 EXPECT_RESULT, Number::New(0)); |
551 } | 556 } |
552 | 557 |
553 { ExistsInPrototypeContext context; | 558 { ExistsInPrototypeContext context; |
554 context.Check("const x; x", | 559 context.Check("const x; x", |
555 0, | 560 0, |
556 0, | 561 0, |
557 0, // declaration | 562 0, |
558 EXPECT_RESULT, Undefined()); | 563 EXPECT_RESULT, Undefined()); |
559 } | 564 } |
560 | 565 |
561 { ExistsInPrototypeContext context; | 566 { ExistsInPrototypeContext context; |
562 context.Check("const x = 0; x", | 567 context.Check("const x = 0; x", |
563 0, | 568 0, |
564 0, | 569 0, |
565 0, // declaration | 570 0, |
566 EXPECT_RESULT, Number::New(0)); | 571 EXPECT_RESULT, Number::New(0)); |
567 } | 572 } |
568 } | 573 } |
569 | 574 |
570 | 575 |
571 | 576 |
572 class AbsentInPrototypeContext: public DeclarationContext { | 577 class AbsentInPrototypeContext: public DeclarationContext { |
573 protected: | 578 protected: |
574 virtual v8::Handle<Integer> Query(Local<String> key) { | 579 virtual v8::Handle<Integer> Query(Local<String> key) { |
575 // Let it seem that the property is absent in the prototype object. | 580 // Let it seem that the property is absent in the prototype object. |
576 return Handle<Integer>(); | 581 return Handle<Integer>(); |
577 } | 582 } |
578 | 583 |
579 // Use the prototype as the holder for the interceptors. | 584 // Use the prototype as the holder for the interceptors. |
580 virtual Local<ObjectTemplate> GetHolder(Local<FunctionTemplate> function) { | 585 virtual Local<ObjectTemplate> GetHolder(Local<FunctionTemplate> function) { |
581 return function->PrototypeTemplate(); | 586 return function->PrototypeTemplate(); |
582 } | 587 } |
583 }; | 588 }; |
584 | 589 |
585 | 590 |
586 TEST(AbsentInPrototype) { | 591 TEST(AbsentInPrototype) { |
587 i::FLAG_es52_globals = true; | 592 i::FLAG_es52_globals = true; |
588 HandleScope scope; | 593 HandleScope scope; |
589 | 594 |
590 { AbsentInPrototypeContext context; | 595 { AbsentInPrototypeContext context; |
591 context.Check("if (false) { var x = 0; }; x", | 596 context.Check("if (false) { var x = 0; }; x", |
592 0, | 597 0, |
593 0, | 598 0, |
594 0, // declaration | 599 0, |
595 EXPECT_RESULT, Undefined()); | 600 EXPECT_RESULT, Undefined()); |
596 } | 601 } |
597 } | 602 } |
| 603 |
| 604 |
| 605 |
| 606 class ExistsInHiddenPrototypeContext: public DeclarationContext { |
| 607 public: |
| 608 ExistsInHiddenPrototypeContext() { |
| 609 hidden_proto_ = FunctionTemplate::New(); |
| 610 hidden_proto_->SetHiddenPrototype(true); |
| 611 } |
| 612 |
| 613 protected: |
| 614 virtual v8::Handle<Integer> Query(Local<String> key) { |
| 615 // Let it seem that the property exists in the hidden prototype object. |
| 616 return Integer::New(v8::None); |
| 617 } |
| 618 |
| 619 // Install the hidden prototype after the global object has been created. |
| 620 virtual void PostInitializeContext(Handle<Context> context) { |
| 621 Local<Object> global_object = context->Global(); |
| 622 Local<Object> hidden_proto = hidden_proto_->GetFunction()->NewInstance(); |
| 623 context->DetachGlobal(); |
| 624 context->Global()->SetPrototype(hidden_proto); |
| 625 context->ReattachGlobal(global_object); |
| 626 } |
| 627 |
| 628 // Use the hidden prototype as the holder for the interceptors. |
| 629 virtual Local<ObjectTemplate> GetHolder(Local<FunctionTemplate> function) { |
| 630 return hidden_proto_->InstanceTemplate(); |
| 631 } |
| 632 |
| 633 private: |
| 634 Local<FunctionTemplate> hidden_proto_; |
| 635 }; |
| 636 |
| 637 |
| 638 TEST(ExistsInHiddenPrototype) { |
| 639 i::FLAG_es52_globals = true; |
| 640 HandleScope scope; |
| 641 |
| 642 { ExistsInHiddenPrototypeContext context; |
| 643 context.Check("var x; x", |
| 644 1, // access |
| 645 0, |
| 646 2, // declaration + initialization |
| 647 EXPECT_EXCEPTION); // x is not defined! |
| 648 } |
| 649 |
| 650 { ExistsInHiddenPrototypeContext context; |
| 651 context.Check("var x = 0; x", |
| 652 1, // access |
| 653 1, // initialization |
| 654 2, // declaration + initialization |
| 655 EXPECT_RESULT, Number::New(0)); |
| 656 } |
| 657 |
| 658 { ExistsInHiddenPrototypeContext context; |
| 659 context.Check("function x() { }; x", |
| 660 0, |
| 661 0, |
| 662 0, |
| 663 EXPECT_RESULT); |
| 664 } |
| 665 |
| 666 // TODO(mstarzinger): The semantics of global const is vague. |
| 667 { ExistsInHiddenPrototypeContext context; |
| 668 context.Check("const x; x", |
| 669 0, |
| 670 0, |
| 671 1, // (re-)declaration |
| 672 EXPECT_RESULT, Undefined()); |
| 673 } |
| 674 |
| 675 // TODO(mstarzinger): The semantics of global const is vague. |
| 676 { ExistsInHiddenPrototypeContext context; |
| 677 context.Check("const x = 0; x", |
| 678 0, |
| 679 0, |
| 680 1, // (re-)declaration |
| 681 EXPECT_RESULT, Number::New(0)); |
| 682 } |
| 683 } |
OLD | NEW |