| 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 |