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