LCOV - code coverage report
Current view: top level - test/cctest - test-decls.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 439 454 96.7 %
Date: 2017-10-20 Functions: 46 58 79.3 %

          Line data    Source code
       1             : // Copyright 2007-2008 the V8 project authors. All rights reserved.
       2             : // Redistribution and use in source and binary forms, with or without
       3             : // modification, are permitted provided that the following conditions are
       4             : // met:
       5             : //
       6             : //     * Redistributions of source code must retain the above copyright
       7             : //       notice, this list of conditions and the following disclaimer.
       8             : //     * Redistributions in binary form must reproduce the above
       9             : //       copyright notice, this list of conditions and the following
      10             : //       disclaimer in the documentation and/or other materials provided
      11             : //       with the distribution.
      12             : //     * Neither the name of Google Inc. nor the names of its
      13             : //       contributors may be used to endorse or promote products derived
      14             : //       from this software without specific prior written permission.
      15             : //
      16             : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      17             : // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      18             : // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
      19             : // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
      20             : // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      21             : // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
      22             : // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      23             : // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      24             : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      25             : // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
      26             : // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      27             : 
      28             : #include <stdlib.h>
      29             : 
      30             : #include "src/v8.h"
      31             : 
      32             : #include "src/heap/heap-inl.h"
      33             : #include "src/heap/heap.h"
      34             : #include "test/cctest/cctest.h"
      35             : 
      36             : namespace v8 {
      37             : 
      38             : namespace {
      39             : 
      40             : enum Expectations {
      41             :   EXPECT_RESULT,
      42             :   EXPECT_EXCEPTION,
      43             :   EXPECT_ERROR
      44             : };
      45             : 
      46             : 
      47             : // A DeclarationContext holds a reference to a v8::Context and keeps
      48             : // track of various declaration related counters to make it easier to
      49             : // track if global declarations in the presence of interceptors behave
      50             : // the right way.
      51             : class DeclarationContext {
      52             :  public:
      53             :   DeclarationContext();
      54             : 
      55          85 :   virtual ~DeclarationContext() {
      56          85 :     if (is_initialized_) {
      57          85 :       Isolate* isolate = CcTest::isolate();
      58          85 :       HandleScope scope(isolate);
      59             :       Local<Context> context = Local<Context>::New(isolate, context_);
      60          85 :       context->Exit();
      61          85 :       context_.Reset();
      62             :     }
      63          85 :   }
      64             : 
      65             :   void Check(const char* source, int get, int set, int has,
      66             :              Expectations expectations,
      67             :              v8::Local<Value> value = Local<Value>());
      68             : 
      69             :   int get_count() const { return get_count_; }
      70             :   int set_count() const { return set_count_; }
      71             :   int query_count() const { return query_count_; }
      72             : 
      73             :  protected:
      74             :   virtual v8::Local<Value> Get(Local<Name> key);
      75             :   virtual v8::Local<Value> Set(Local<Name> key, Local<Value> value);
      76             :   virtual v8::Local<Integer> Query(Local<Name> key);
      77             : 
      78             :   void InitializeIfNeeded();
      79             : 
      80             :   // Perform optional initialization steps on the context after it has
      81             :   // been created. Defaults to none but may be overwritten.
      82          70 :   virtual void PostInitializeContext(Local<Context> context) {}
      83             : 
      84             :   // Get the holder for the interceptor. Default to the instance template
      85             :   // but may be overwritten.
      86          50 :   virtual Local<ObjectTemplate> GetHolder(Local<FunctionTemplate> function) {
      87          50 :     return function->InstanceTemplate();
      88             :   }
      89             : 
      90             :   // The handlers are called as static functions that forward
      91             :   // to the instance specific virtual methods.
      92             :   static void HandleGet(Local<Name> key,
      93             :                         const v8::PropertyCallbackInfo<v8::Value>& info);
      94             :   static void HandleSet(Local<Name> key, Local<Value> value,
      95             :                         const v8::PropertyCallbackInfo<v8::Value>& info);
      96             :   static void HandleQuery(Local<Name> key,
      97             :                           const v8::PropertyCallbackInfo<v8::Integer>& info);
      98             : 
      99          10 :   v8::Isolate* isolate() const { return CcTest::isolate(); }
     100             : 
     101             :  private:
     102             :   bool is_initialized_;
     103             :   Persistent<Context> context_;
     104             : 
     105             :   int get_count_;
     106             :   int set_count_;
     107             :   int query_count_;
     108             : 
     109             :   static DeclarationContext* GetInstance(Local<Value> data);
     110             : };
     111             : 
     112             : 
     113             : DeclarationContext::DeclarationContext()
     114         170 :     : is_initialized_(false), get_count_(0), set_count_(0), query_count_(0) {
     115             :   // Do nothing.
     116             : }
     117             : 
     118             : 
     119         100 : void DeclarationContext::InitializeIfNeeded() {
     120         115 :   if (is_initialized_) return;
     121          85 :   Isolate* isolate = CcTest::isolate();
     122          85 :   HandleScope scope(isolate);
     123          85 :   Local<FunctionTemplate> function = FunctionTemplate::New(isolate);
     124          85 :   Local<Value> data = External::New(CcTest::isolate(), this);
     125          85 :   GetHolder(function)->SetHandler(v8::NamedPropertyHandlerConfiguration(
     126         170 :       &HandleGet, &HandleSet, &HandleQuery, 0, 0, data));
     127             :   Local<Context> context = Context::New(isolate,
     128             :                                         0,
     129             :                                         function->InstanceTemplate(),
     130         170 :                                         Local<Value>());
     131             :   context_.Reset(isolate, context);
     132          85 :   context->Enter();
     133          85 :   is_initialized_ = true;
     134             :   // Reset counts. Bootstrapping might have called into the interceptor.
     135          85 :   get_count_ = 0;
     136          85 :   set_count_ = 0;
     137          85 :   query_count_ = 0;
     138          85 :   PostInitializeContext(context);
     139             : }
     140             : 
     141             : 
     142          85 : void DeclarationContext::Check(const char* source, int get, int set, int query,
     143             :                                Expectations expectations,
     144         255 :                                v8::Local<Value> value) {
     145          85 :   InitializeIfNeeded();
     146             :   // A retry after a GC may pollute the counts, so perform gc now
     147             :   // to avoid that.
     148          85 :   CcTest::CollectGarbage(v8::internal::NEW_SPACE);
     149          85 :   HandleScope scope(CcTest::isolate());
     150         170 :   TryCatch catcher(CcTest::isolate());
     151          85 :   catcher.SetVerbose(true);
     152          85 :   Local<Context> context = CcTest::isolate()->GetCurrentContext();
     153             :   MaybeLocal<Script> script = Script::Compile(
     154             :       context,
     155          85 :       String::NewFromUtf8(CcTest::isolate(), source, v8::NewStringType::kNormal)
     156         170 :           .ToLocalChecked());
     157          85 :   if (expectations == EXPECT_ERROR) {
     158           0 :     CHECK(script.IsEmpty());
     159           0 :     return;
     160             :   }
     161          85 :   CHECK(!script.IsEmpty());
     162          85 :   MaybeLocal<Value> result = script.ToLocalChecked()->Run(context);
     163          85 :   CHECK_EQ(get, get_count());
     164          85 :   CHECK_EQ(set, set_count());
     165          85 :   CHECK_EQ(query, query_count());
     166          85 :   if (expectations == EXPECT_RESULT) {
     167          85 :     CHECK(!catcher.HasCaught());
     168          85 :     if (!value.IsEmpty()) {
     169         130 :       CHECK(value->Equals(context, result.ToLocalChecked()).FromJust());
     170             :     }
     171             :   } else {
     172           0 :     CHECK(expectations == EXPECT_EXCEPTION);
     173           0 :     CHECK(catcher.HasCaught());
     174           0 :     if (!value.IsEmpty()) {
     175           0 :       CHECK(value->Equals(context, catcher.Exception()).FromJust());
     176             :     }
     177             :   }
     178             :   // Clean slate for the next test.
     179         170 :   CcTest::CollectAllAvailableGarbage();
     180             : }
     181             : 
     182             : 
     183          50 : void DeclarationContext::HandleGet(
     184             :     Local<Name> key, const v8::PropertyCallbackInfo<v8::Value>& info) {
     185             :   DeclarationContext* context = GetInstance(info.Data());
     186          50 :   context->get_count_++;
     187          50 :   info.GetReturnValue().Set(context->Get(key));
     188          50 : }
     189             : 
     190             : 
     191          35 : void DeclarationContext::HandleSet(
     192             :     Local<Name> key, Local<Value> value,
     193             :     const v8::PropertyCallbackInfo<v8::Value>& info) {
     194             :   DeclarationContext* context = GetInstance(info.Data());
     195          35 :   context->set_count_++;
     196          35 :   info.GetReturnValue().Set(context->Set(key, value));
     197          35 : }
     198             : 
     199             : 
     200          25 : void DeclarationContext::HandleQuery(
     201             :     Local<Name> key, const v8::PropertyCallbackInfo<v8::Integer>& info) {
     202             :   DeclarationContext* context = GetInstance(info.Data());
     203          25 :   context->query_count_++;
     204          25 :   info.GetReturnValue().Set(context->Query(key));
     205          25 : }
     206             : 
     207             : 
     208             : DeclarationContext* DeclarationContext::GetInstance(Local<Value> data) {
     209         110 :   void* value = Local<External>::Cast(data)->Value();
     210             :   return static_cast<DeclarationContext*>(value);
     211             : }
     212             : 
     213             : 
     214          50 : v8::Local<Value> DeclarationContext::Get(Local<Name> key) {
     215          50 :   return v8::Local<Value>();
     216             : }
     217             : 
     218             : 
     219          35 : v8::Local<Value> DeclarationContext::Set(Local<Name> key, Local<Value> value) {
     220          35 :   return v8::Local<Value>();
     221             : }
     222             : 
     223             : 
     224           5 : v8::Local<Integer> DeclarationContext::Query(Local<Name> key) {
     225           5 :   return v8::Local<Integer>();
     226             : }
     227             : 
     228             : }  // namespace
     229             : 
     230             : // Test global declaration of a property the interceptor doesn't know
     231             : // about and doesn't handle.
     232       23723 : TEST(Unknown) {
     233           5 :   HandleScope scope(CcTest::isolate());
     234           5 :   v8::V8::Initialize();
     235             : 
     236             :   { DeclarationContext context;
     237             :     context.Check("var x; x",
     238             :                   1,  // access
     239          10 :                   0, 0, EXPECT_RESULT, Undefined(CcTest::isolate()));
     240             :   }
     241             : 
     242             :   { DeclarationContext context;
     243             :     context.Check("var x = 0; x",
     244             :                   1,  // access
     245             :                   1,  // initialization
     246          10 :                   0, EXPECT_RESULT, Number::New(CcTest::isolate(), 0));
     247             :   }
     248             : 
     249             :   { DeclarationContext context;
     250             :     context.Check("function x() { }; x",
     251             :                   1,  // access
     252           5 :                   1, 1, EXPECT_RESULT);
     253           5 :   }
     254           5 : }
     255             : 
     256             : 
     257          40 : class AbsentPropertyContext: public DeclarationContext {
     258             :  protected:
     259           5 :   virtual v8::Local<Integer> Query(Local<Name> key) {
     260           5 :     return v8::Local<Integer>();
     261             :   }
     262             : };
     263             : 
     264             : 
     265       23723 : TEST(Absent) {
     266           5 :   v8::Isolate* isolate = CcTest::isolate();
     267           5 :   v8::V8::Initialize();
     268           5 :   HandleScope scope(isolate);
     269             : 
     270             :   { AbsentPropertyContext context;
     271             :     context.Check("var x; x",
     272             :                   1,  // access
     273           5 :                   0, 0, EXPECT_RESULT, Undefined(isolate));
     274             :   }
     275             : 
     276             :   { AbsentPropertyContext context;
     277             :     context.Check("var x = 0; x",
     278             :                   1,  // access
     279             :                   1,  // initialization
     280          10 :                   0, EXPECT_RESULT, Number::New(isolate, 0));
     281             :   }
     282             : 
     283             :   { AbsentPropertyContext context;
     284             :     context.Check("function x() { }; x",
     285             :                   1,  // access
     286           5 :                   1, 1, EXPECT_RESULT);
     287             :   }
     288             : 
     289             :   { AbsentPropertyContext context;
     290             :     context.Check("if (false) { var x = 0 }; x",
     291             :                   1,  // access
     292           5 :                   0, 0, EXPECT_RESULT, Undefined(isolate));
     293           5 :   }
     294           5 : }
     295             : 
     296             : 
     297             : 
     298          15 : class AppearingPropertyContext: public DeclarationContext {
     299             :  public:
     300             :   enum State {
     301             :     DECLARE,
     302             :     INITIALIZE_IF_ASSIGN,
     303             :     UNKNOWN
     304             :   };
     305             : 
     306          15 :   AppearingPropertyContext() : state_(DECLARE) { }
     307             : 
     308             :  protected:
     309           5 :   virtual v8::Local<Integer> Query(Local<Name> key) {
     310           5 :     switch (state_) {
     311             :       case DECLARE:
     312             :         // Force declaration by returning that the
     313             :         // property is absent.
     314           5 :         state_ = INITIALIZE_IF_ASSIGN;
     315           5 :         return Local<Integer>();
     316             :       case INITIALIZE_IF_ASSIGN:
     317             :         // Return that the property is present so we only get the
     318             :         // setter called when initializing with a value.
     319           0 :         state_ = UNKNOWN;
     320           0 :         return Integer::New(isolate(), v8::None);
     321             :       default:
     322           0 :         CHECK(state_ == UNKNOWN);
     323             :         break;
     324             :     }
     325             :     // Do the lookup in the object.
     326           0 :     return v8::Local<Integer>();
     327             :   }
     328             : 
     329             :  private:
     330             :   State state_;
     331             : };
     332             : 
     333             : 
     334       23723 : TEST(Appearing) {
     335           5 :   v8::V8::Initialize();
     336           5 :   HandleScope scope(CcTest::isolate());
     337             : 
     338             :   { AppearingPropertyContext context;
     339             :     context.Check("var x; x",
     340             :                   1,  // access
     341          10 :                   0, 0, EXPECT_RESULT, Undefined(CcTest::isolate()));
     342             :   }
     343             : 
     344             :   { AppearingPropertyContext context;
     345             :     context.Check("var x = 0; x",
     346             :                   1,  // access
     347             :                   1,  // initialization
     348          10 :                   0, EXPECT_RESULT, Number::New(CcTest::isolate(), 0));
     349             :   }
     350             : 
     351             :   { AppearingPropertyContext context;
     352             :     context.Check("function x() { }; x",
     353             :                   1,  // access
     354           5 :                   1, 1, EXPECT_RESULT);
     355           5 :   }
     356           5 : }
     357             : 
     358             : 
     359             : 
     360          15 : class ExistsInPrototypeContext: public DeclarationContext {
     361             :  public:
     362          15 :   ExistsInPrototypeContext() { InitializeIfNeeded(); }
     363             :  protected:
     364           5 :   virtual v8::Local<Integer> Query(Local<Name> key) {
     365             :     // Let it seem that the property exists in the prototype object.
     366           5 :     return Integer::New(isolate(), v8::None);
     367             :   }
     368             : 
     369             :   // Use the prototype as the holder for the interceptors.
     370          15 :   virtual Local<ObjectTemplate> GetHolder(Local<FunctionTemplate> function) {
     371          15 :     return function->PrototypeTemplate();
     372             :   }
     373             : };
     374             : 
     375             : 
     376       23723 : TEST(ExistsInPrototype) {
     377           5 :   HandleScope scope(CcTest::isolate());
     378             : 
     379             :   // Sanity check to make sure that the holder of the interceptor
     380             :   // really is the prototype object.
     381             :   { ExistsInPrototypeContext context;
     382             :     context.Check("this.x = 87; this.x", 0, 0, 1, EXPECT_RESULT,
     383          10 :                   Number::New(CcTest::isolate(), 87));
     384             :   }
     385             : 
     386             :   { ExistsInPrototypeContext context;
     387             :     context.Check("var x; x",
     388             :                   0,
     389             :                   0,
     390             :                   0,
     391          10 :                   EXPECT_RESULT, Undefined(CcTest::isolate()));
     392             :   }
     393             : 
     394             :   { ExistsInPrototypeContext context;
     395             :     context.Check("var x = 0; x",
     396             :                   0,
     397             :                   0,
     398             :                   0,
     399          10 :                   EXPECT_RESULT, Number::New(CcTest::isolate(), 0));
     400           5 :   }
     401           5 : }
     402             : 
     403             : 
     404             : 
     405          10 : class AbsentInPrototypeContext: public DeclarationContext {
     406             :  protected:
     407           0 :   virtual v8::Local<Integer> Query(Local<Name> key) {
     408             :     // Let it seem that the property is absent in the prototype object.
     409           0 :     return Local<Integer>();
     410             :   }
     411             : 
     412             :   // Use the prototype as the holder for the interceptors.
     413           5 :   virtual Local<ObjectTemplate> GetHolder(Local<FunctionTemplate> function) {
     414           5 :     return function->PrototypeTemplate();
     415             :   }
     416             : };
     417             : 
     418             : 
     419       23723 : TEST(AbsentInPrototype) {
     420           5 :   v8::V8::Initialize();
     421           5 :   HandleScope scope(CcTest::isolate());
     422             : 
     423             :   { AbsentInPrototypeContext context;
     424             :     context.Check("if (false) { var x = 0; }; x",
     425             :                   0,
     426             :                   0,
     427             :                   0,
     428          10 :                   EXPECT_RESULT, Undefined(CcTest::isolate()));
     429           5 :   }
     430           5 : }
     431             : 
     432             : 
     433             : 
     434          15 : class ExistsInHiddenPrototypeContext: public DeclarationContext {
     435             :  public:
     436          30 :   ExistsInHiddenPrototypeContext() {
     437          15 :     hidden_proto_ = FunctionTemplate::New(CcTest::isolate());
     438          15 :     hidden_proto_->SetHiddenPrototype(true);
     439          15 :   }
     440             : 
     441             :  protected:
     442           5 :   virtual v8::Local<Integer> Query(Local<Name> key) {
     443             :     // Let it seem that the property exists in the hidden prototype object.
     444           5 :     return Integer::New(isolate(), v8::None);
     445             :   }
     446             : 
     447             :   // Install the hidden prototype after the global object has been created.
     448          15 :   virtual void PostInitializeContext(Local<Context> context) {
     449          15 :     Local<Object> global_object = context->Global();
     450             :     Local<Object> hidden_proto = hidden_proto_->GetFunction(context)
     451          15 :                                      .ToLocalChecked()
     452             :                                      ->NewInstance(context)
     453             :                                      .ToLocalChecked();
     454             :     Local<Object> inner_global =
     455          15 :         Local<Object>::Cast(global_object->GetPrototype());
     456          30 :     inner_global->SetPrototype(context, hidden_proto).FromJust();
     457          15 :   }
     458             : 
     459             :   // Use the hidden prototype as the holder for the interceptors.
     460          15 :   virtual Local<ObjectTemplate> GetHolder(Local<FunctionTemplate> function) {
     461          15 :     return hidden_proto_->InstanceTemplate();
     462             :   }
     463             : 
     464             :  private:
     465             :   Local<FunctionTemplate> hidden_proto_;
     466             : };
     467             : 
     468             : 
     469       23723 : TEST(ExistsInHiddenPrototype) {
     470           5 :   HandleScope scope(CcTest::isolate());
     471             : 
     472           5 :   { ExistsInHiddenPrototypeContext context;
     473             :     context.Check("var x; x", 0, 0, 0, EXPECT_RESULT,
     474          10 :                   Undefined(CcTest::isolate()));
     475             :   }
     476             : 
     477           5 :   { ExistsInHiddenPrototypeContext context;
     478             :     context.Check("var x = 0; x", 0, 0, 0, EXPECT_RESULT,
     479          10 :                   Number::New(CcTest::isolate(), 0));
     480             :   }
     481             : 
     482           5 :   { ExistsInHiddenPrototypeContext context;
     483           5 :     context.Check("function x() { }; x", 0, 1, 1, EXPECT_RESULT);
     484           5 :   }
     485           5 : }
     486             : 
     487             : 
     488             : 
     489             : class SimpleContext {
     490             :  public:
     491         705 :   SimpleContext()
     492             :       : handle_scope_(CcTest::isolate()),
     493        1410 :         context_(Context::New(CcTest::isolate())) {
     494         705 :     context_->Enter();
     495         705 :   }
     496             : 
     497         705 :   ~SimpleContext() {
     498         705 :     context_->Exit();
     499             :   }
     500             : 
     501        2950 :   void Check(const char* source, Expectations expectations,
     502             :              v8::Local<Value> value = Local<Value>()) {
     503        2950 :     HandleScope scope(context_->GetIsolate());
     504        5900 :     TryCatch catcher(context_->GetIsolate());
     505        2950 :     catcher.SetVerbose(true);
     506             :     MaybeLocal<Script> script = Script::Compile(
     507             :         context_, String::NewFromUtf8(context_->GetIsolate(), source,
     508        2950 :                                       v8::NewStringType::kNormal)
     509        5900 :                       .ToLocalChecked());
     510        2950 :     if (expectations == EXPECT_ERROR) {
     511           0 :       CHECK(script.IsEmpty());
     512           0 :       return;
     513             :     }
     514        2950 :     CHECK(!script.IsEmpty());
     515        2950 :     MaybeLocal<Value> result = script.ToLocalChecked()->Run(context_);
     516        2950 :     if (expectations == EXPECT_RESULT) {
     517        2285 :       CHECK(!catcher.HasCaught());
     518        2285 :       if (!value.IsEmpty()) {
     519        4570 :         CHECK(value->Equals(context_, result.ToLocalChecked()).FromJust());
     520             :       }
     521             :     } else {
     522         665 :       CHECK(expectations == EXPECT_EXCEPTION);
     523         665 :       CHECK(catcher.HasCaught());
     524         665 :       if (!value.IsEmpty()) {
     525           0 :         CHECK(value->Equals(context_, catcher.Exception()).FromJust());
     526             :       }
     527        2950 :     }
     528             :   }
     529             : 
     530             :  private:
     531             :   HandleScope handle_scope_;
     532             :   Local<Context> context_;
     533             : };
     534             : 
     535             : 
     536       23723 : TEST(CrossScriptReferences) {
     537           5 :   v8::Isolate* isolate = CcTest::isolate();
     538           5 :   HandleScope scope(isolate);
     539             : 
     540           5 :   { SimpleContext context;
     541             :     context.Check("var x = 1; x",
     542          10 :                   EXPECT_RESULT, Number::New(isolate, 1));
     543             :     context.Check("var x = 2; x",
     544          10 :                   EXPECT_RESULT, Number::New(isolate, 2));
     545             :     context.Check("x = 5; x",
     546          10 :                   EXPECT_RESULT, Number::New(isolate, 5));
     547             :     context.Check("var x = 6; x",
     548          10 :                   EXPECT_RESULT, Number::New(isolate, 6));
     549             :     context.Check("this.x",
     550          10 :                   EXPECT_RESULT, Number::New(isolate, 6));
     551             :     context.Check("function x() { return 7 }; x()",
     552          10 :                   EXPECT_RESULT, Number::New(isolate, 7));
     553           5 :   }
     554           5 : }
     555             : 
     556             : 
     557       23723 : TEST(CrossScriptReferences_Simple) {
     558           5 :   i::FLAG_use_strict = true;
     559             : 
     560           5 :   v8::Isolate* isolate = CcTest::isolate();
     561           5 :   HandleScope scope(isolate);
     562             : 
     563             :   {
     564           5 :     SimpleContext context;
     565          10 :     context.Check("let x = 1; x", EXPECT_RESULT, Number::New(isolate, 1));
     566           5 :     context.Check("let x = 5; x", EXPECT_EXCEPTION);
     567           5 :   }
     568           5 : }
     569             : 
     570             : 
     571       23723 : TEST(CrossScriptReferences_Simple2) {
     572           5 :   i::FLAG_use_strict = true;
     573             : 
     574           5 :   v8::Isolate* isolate = CcTest::isolate();
     575           5 :   HandleScope scope(isolate);
     576             : 
     577         505 :   for (int k = 0; k < 100; k++) {
     578         500 :     SimpleContext context;
     579         500 :     bool cond = (k % 2) == 0;
     580         500 :     if (cond) {
     581         500 :       context.Check("let x = 1; x", EXPECT_RESULT, Number::New(isolate, 1));
     582         500 :       context.Check("let z = 4; z", EXPECT_RESULT, Number::New(isolate, 4));
     583             :     } else {
     584         500 :       context.Check("let z = 1; z", EXPECT_RESULT, Number::New(isolate, 1));
     585         500 :       context.Check("let x = 4; x", EXPECT_RESULT, Number::New(isolate, 4));
     586             :     }
     587             :     context.Check("let y = 2; x", EXPECT_RESULT,
     588        1000 :                   Number::New(isolate, cond ? 1 : 4));
     589           5 :   }
     590           5 : }
     591             : 
     592             : 
     593       23723 : TEST(CrossScriptReferencesHarmony) {
     594           5 :   v8::Isolate* isolate = CcTest::isolate();
     595           5 :   HandleScope scope(isolate);
     596             : 
     597             :   // Check that simple cross-script global scope access works.
     598             :   const char* decs[] = {"'use strict'; var x = 1; x",
     599             :                         "x",
     600             :                         "'use strict'; function x() { return 1 }; x()",
     601             :                         "x()",
     602             :                         "'use strict'; let x = 1; x",
     603             :                         "x",
     604             :                         "'use strict'; const x = 1; x",
     605             :                         "x",
     606           5 :                         nullptr};
     607             : 
     608          25 :   for (int i = 0; decs[i] != nullptr; i += 2) {
     609          20 :     SimpleContext context;
     610          40 :     context.Check(decs[i], EXPECT_RESULT, Number::New(isolate, 1));
     611          40 :     context.Check(decs[i+1], EXPECT_RESULT, Number::New(isolate, 1));
     612             :   }
     613             : 
     614             :   // Check that cross-script global scope access works with late declarations.
     615             :   {
     616           5 :     SimpleContext context;
     617             :     context.Check("function d0() { return x0 }",  // dynamic lookup
     618           5 :                   EXPECT_RESULT, Undefined(isolate));
     619             :     context.Check("this.x0 = -1;"
     620             :                   "d0()",
     621          10 :                   EXPECT_RESULT, Number::New(isolate, -1));
     622             :     context.Check("'use strict';"
     623             :                   "function f0() { let y = 10; return x0 + y }"
     624             :                   "function g0() { let y = 10; return eval('x0 + y') }"
     625             :                   "function h0() { let y = 10; return (1,eval)('x0') + y }"
     626             :                   "x0 + f0() + g0() + h0()",
     627          10 :                   EXPECT_RESULT, Number::New(isolate, 26));
     628             : 
     629             :     context.Check("'use strict';"
     630             :                   "let x1 = 1;"
     631             :                   "function f1() { let y = 10; return x1 + y }"
     632             :                   "function g1() { let y = 10; return eval('x1 + y') }"
     633             :                   "function h1() { let y = 10; return (1,eval)('x1') + y }"
     634             :                   "function i1() { "
     635             :                   "  let y = 10; return (typeof x2 === 'undefined' ? 0 : 2) + y"
     636             :                   "}"
     637             :                   "function j1() { let y = 10; return eval('x2 + y') }"
     638             :                   "function k1() { let y = 10; return (1,eval)('x2') + y }"
     639             :                   "function cl() { "
     640             :                   "  let y = 10; "
     641             :                   "  return { "
     642             :                   "    f: function(){ return x1 + y },"
     643             :                   "    g: function(){ return eval('x1 + y') },"
     644             :                   "    h: function(){ return (1,eval)('x1') + y },"
     645             :                   "    i: function(){"
     646             :                   "      return (typeof x2 == 'undefined' ? 0 : 2) + y"
     647             :                   "    },"
     648             :                   "    j: function(){ return eval('x2 + y') },"
     649             :                   "    k: function(){ return (1,eval)('x2') + y },"
     650             :                   "  }"
     651             :                   "}"
     652             :                   "let o = cl();"
     653             :                   "x1 + eval('x1') + (1,eval)('x1') + f1() + g1() + h1();",
     654          10 :                   EXPECT_RESULT, Number::New(isolate, 36));
     655             :     context.Check("x1 + eval('x1') + (1,eval)('x1') + f1() + g1() + h1();",
     656          10 :                   EXPECT_RESULT, Number::New(isolate, 36));
     657             :     context.Check("o.f() + o.g() + o.h();",
     658          10 :                   EXPECT_RESULT, Number::New(isolate, 33));
     659             :     context.Check("i1() + o.i();",
     660          10 :                   EXPECT_RESULT, Number::New(isolate, 20));
     661             : 
     662             :     context.Check("'use strict';"
     663             :                   "let x2 = 2;"
     664             :                   "function f2() { let y = 20; return x2 + y }"
     665             :                   "function g2() { let y = 20; return eval('x2 + y') }"
     666             :                   "function h2() { let y = 20; return (1,eval)('x2') + y }"
     667             :                   "function i2() { let y = 20; return x1 + y }"
     668             :                   "function j2() { let y = 20; return eval('x1 + y') }"
     669             :                   "function k2() { let y = 20; return (1,eval)('x1') + y }"
     670             :                   "x2 + eval('x2') + (1,eval)('x2') + f2() + g2() + h2();",
     671          10 :                   EXPECT_RESULT, Number::New(isolate, 72));
     672             :     context.Check("x1 + eval('x1') + (1,eval)('x1') + f1() + g1() + h1();",
     673          10 :                   EXPECT_RESULT, Number::New(isolate, 36));
     674             :     context.Check("i1() + j1() + k1();",
     675          10 :                   EXPECT_RESULT, Number::New(isolate, 36));
     676             :     context.Check("i2() + j2() + k2();",
     677          10 :                   EXPECT_RESULT, Number::New(isolate, 63));
     678             :     context.Check("o.f() + o.g() + o.h();",
     679          10 :                   EXPECT_RESULT, Number::New(isolate, 33));
     680             :     context.Check("o.i() + o.j() + o.k();",
     681          10 :                   EXPECT_RESULT, Number::New(isolate, 36));
     682             :     context.Check("i1() + o.i();",
     683          10 :                   EXPECT_RESULT, Number::New(isolate, 24));
     684             : 
     685             :     context.Check("'use strict';"
     686             :                   "let x0 = 100;"
     687             :                   "x0 + eval('x0') + (1,eval)('x0') + "
     688             :                   "    d0() + f0() + g0() + h0();",
     689          10 :                   EXPECT_RESULT, Number::New(isolate, 730));
     690             :     context.Check("x0 + eval('x0') + (1,eval)('x0') + "
     691             :                   "    d0() + f0() + g0() + h0();",
     692          10 :                   EXPECT_RESULT, Number::New(isolate, 730));
     693             :     context.Check("delete this.x0;"
     694             :                   "x0 + eval('x0') + (1,eval)('x0') + "
     695             :                   "    d0() + f0() + g0() + h0();",
     696          10 :                   EXPECT_RESULT, Number::New(isolate, 730));
     697             :     context.Check("this.x1 = 666;"
     698             :                   "x1 + eval('x1') + (1,eval)('x1') + f1() + g1() + h1();",
     699          10 :                   EXPECT_RESULT, Number::New(isolate, 36));
     700             :     context.Check("delete this.x1;"
     701             :                   "x1 + eval('x1') + (1,eval)('x1') + f1() + g1() + h1();",
     702          10 :                   EXPECT_RESULT, Number::New(isolate, 36));
     703             :   }
     704             : 
     705             :   // Check that caching does respect scopes.
     706             :   {
     707           5 :     SimpleContext context;
     708             :     const char* script1 = "(function(){ return y1 })()";
     709             :     const char* script2 = "(function(){ return y2 })()";
     710             : 
     711           5 :     context.Check(script1, EXPECT_EXCEPTION);
     712             :     context.Check("this.y1 = 1; this.y2 = 2; 0;",
     713          10 :                   EXPECT_RESULT, Number::New(isolate, 0));
     714             :     context.Check(script1,
     715          10 :                   EXPECT_RESULT, Number::New(isolate, 1));
     716             :     context.Check("'use strict'; let y1 = 3; 0;",
     717          10 :                   EXPECT_RESULT, Number::New(isolate, 0));
     718             :     context.Check(script1,
     719          10 :                   EXPECT_RESULT, Number::New(isolate, 3));
     720             :     context.Check("y1 = 4;",
     721          10 :                   EXPECT_RESULT, Number::New(isolate, 4));
     722             :     context.Check(script1,
     723          10 :                   EXPECT_RESULT, Number::New(isolate, 4));
     724             : 
     725             :     context.Check(script2,
     726          10 :                   EXPECT_RESULT, Number::New(isolate, 2));
     727             :     context.Check("'use strict'; let y2 = 5; 0;",
     728          10 :                   EXPECT_RESULT, Number::New(isolate, 0));
     729             :     context.Check(script1,
     730          10 :                   EXPECT_RESULT, Number::New(isolate, 4));
     731             :     context.Check(script2,
     732          10 :                   EXPECT_RESULT, Number::New(isolate, 5));
     733           5 :   }
     734           5 : }
     735             : 
     736             : 
     737       23723 : TEST(CrossScriptReferencesHarmonyRegress) {
     738           5 :   v8::Isolate* isolate = CcTest::isolate();
     739           5 :   HandleScope scope(isolate);
     740           5 :   SimpleContext context;
     741             :   context.Check(
     742             :       "'use strict';"
     743             :       "function i1() { "
     744             :       "  let y = 10; return (typeof x2 === 'undefined' ? 0 : 2) + y"
     745             :       "}"
     746             :       "i1();"
     747             :       "i1();",
     748          10 :       EXPECT_RESULT, Number::New(isolate, 10));
     749             :   context.Check(
     750             :       "'use strict';"
     751             :       "let x2 = 2; i1();",
     752          15 :       EXPECT_RESULT, Number::New(isolate, 12));
     753           5 : }
     754             : 
     755             : 
     756       23723 : TEST(GlobalLexicalOSR) {
     757           5 :   i::FLAG_use_strict = true;
     758             : 
     759           5 :   v8::Isolate* isolate = CcTest::isolate();
     760           5 :   HandleScope scope(isolate);
     761           5 :   SimpleContext context;
     762             : 
     763             :   context.Check("'use strict';"
     764             :                 "let x = 1; x;",
     765          10 :                 EXPECT_RESULT, Number::New(isolate, 1));
     766             :   context.Check("'use strict';"
     767             :                 "let y = 2*x;"
     768             :                 "++x;"
     769             :                 "let z = 0;"
     770             :                 "const limit = 100000;"
     771             :                 "for (var i = 0; i < limit; ++i) {"
     772             :                 "  z += x + y;"
     773             :                 "}"
     774             :                 "z;",
     775          15 :                 EXPECT_RESULT, Number::New(isolate, 400000));
     776           5 : }
     777             : 
     778             : 
     779       23723 : TEST(CrossScriptConflicts) {
     780           5 :   i::FLAG_use_strict = true;
     781             : 
     782           5 :   HandleScope scope(CcTest::isolate());
     783             : 
     784             :   const char* firsts[] = {"var x = 1; x", "function x() { return 1 }; x()",
     785           5 :                           "let x = 1; x", "const x = 1; x", nullptr};
     786             :   const char* seconds[] = {"var x = 2; x", "function x() { return 2 }; x()",
     787           5 :                            "let x = 2; x", "const x = 2; x", nullptr};
     788             : 
     789          25 :   for (int i = 0; firsts[i] != nullptr; ++i) {
     790          80 :     for (int j = 0; seconds[j] != nullptr; ++j) {
     791          80 :       SimpleContext context;
     792             :       context.Check(firsts[i], EXPECT_RESULT,
     793         160 :                     Number::New(CcTest::isolate(), 1));
     794          80 :       bool success_case = i < 2 && j < 2;
     795             :       Local<Value> success_result;
     796          80 :       if (success_case) success_result = Number::New(CcTest::isolate(), 2);
     797             : 
     798             :       context.Check(seconds[j], success_case ? EXPECT_RESULT : EXPECT_EXCEPTION,
     799          80 :                     success_result);
     800             :     }
     801           5 :   }
     802           5 : }
     803             : 
     804             : 
     805       23723 : TEST(CrossScriptDynamicLookup) {
     806           5 :   HandleScope handle_scope(CcTest::isolate());
     807             : 
     808             :   {
     809           5 :     SimpleContext context;
     810             :     Local<String> undefined_string =
     811             :         String::NewFromUtf8(CcTest::isolate(), "undefined",
     812           5 :                             v8::NewStringType::kInternalized)
     813           5 :             .ToLocalChecked();
     814             :     Local<String> number_string =
     815             :         String::NewFromUtf8(CcTest::isolate(), "number",
     816           5 :                             v8::NewStringType::kInternalized)
     817           5 :             .ToLocalChecked();
     818             : 
     819             :     context.Check(
     820             :         "function f(o) { with(o) { return x; } }"
     821             :         "function g(o) { with(o) { x = 15; } }"
     822             :         "function h(o) { with(o) { return typeof x; } }",
     823          10 :         EXPECT_RESULT, Undefined(CcTest::isolate()));
     824           5 :     context.Check("h({})", EXPECT_RESULT, undefined_string);
     825             :     context.Check(
     826             :         "'use strict';"
     827             :         "let x = 1;"
     828             :         "f({})",
     829          10 :         EXPECT_RESULT, Number::New(CcTest::isolate(), 1));
     830             :     context.Check(
     831             :         "'use strict';"
     832             :         "g({});0",
     833          10 :         EXPECT_RESULT, Number::New(CcTest::isolate(), 0));
     834          10 :     context.Check("f({})", EXPECT_RESULT, Number::New(CcTest::isolate(), 15));
     835           5 :     context.Check("h({})", EXPECT_RESULT, number_string);
     836           5 :   }
     837           5 : }
     838             : 
     839             : 
     840       23723 : TEST(CrossScriptGlobal) {
     841           5 :   HandleScope handle_scope(CcTest::isolate());
     842             :   {
     843           5 :     SimpleContext context;
     844             : 
     845             :     context.Check(
     846             :         "var global = this;"
     847             :         "global.x = 255;"
     848             :         "x",
     849          10 :         EXPECT_RESULT, Number::New(CcTest::isolate(), 255));
     850             :     context.Check(
     851             :         "'use strict';"
     852             :         "let x = 1;"
     853             :         "global.x",
     854          10 :         EXPECT_RESULT, Number::New(CcTest::isolate(), 255));
     855             :     context.Check("global.x = 15; x", EXPECT_RESULT,
     856          10 :                   Number::New(CcTest::isolate(), 1));
     857             :     context.Check("x = 221; global.x", EXPECT_RESULT,
     858          10 :                   Number::New(CcTest::isolate(), 15));
     859             :     context.Check(
     860             :         "z = 15;"
     861             :         "function f() { return z; };"
     862             :         "for (var k = 0; k < 3; k++) { f(); }"
     863             :         "f()",
     864          10 :         EXPECT_RESULT, Number::New(CcTest::isolate(), 15));
     865             :     context.Check(
     866             :         "'use strict';"
     867             :         "let z = 5; f()",
     868          10 :         EXPECT_RESULT, Number::New(CcTest::isolate(), 5));
     869             :     context.Check(
     870             :         "function f() { konst = 10; return konst; };"
     871             :         "f()",
     872          10 :         EXPECT_RESULT, Number::New(CcTest::isolate(), 10));
     873             :     context.Check(
     874             :         "'use strict';"
     875             :         "const konst = 255;"
     876             :         "f()",
     877           5 :         EXPECT_EXCEPTION);
     878           5 :   }
     879           5 : }
     880             : 
     881             : 
     882       23723 : TEST(CrossScriptStaticLookupUndeclared) {
     883           5 :   HandleScope handle_scope(CcTest::isolate());
     884             : 
     885             :   {
     886           5 :     SimpleContext context;
     887             :     Local<String> undefined_string =
     888             :         String::NewFromUtf8(CcTest::isolate(), "undefined",
     889           5 :                             v8::NewStringType::kInternalized)
     890           5 :             .ToLocalChecked();
     891             :     Local<String> number_string =
     892             :         String::NewFromUtf8(CcTest::isolate(), "number",
     893           5 :                             v8::NewStringType::kInternalized)
     894           5 :             .ToLocalChecked();
     895             : 
     896             :     context.Check(
     897             :         "function f(o) { return x; }"
     898             :         "function g(v) { x = v; }"
     899             :         "function h(o) { return typeof x; }",
     900          10 :         EXPECT_RESULT, Undefined(CcTest::isolate()));
     901           5 :     context.Check("h({})", EXPECT_RESULT, undefined_string);
     902             :     context.Check(
     903             :         "'use strict';"
     904             :         "let x = 1;"
     905             :         "f({})",
     906          10 :         EXPECT_RESULT, Number::New(CcTest::isolate(), 1));
     907             :     context.Check(
     908             :         "'use strict';"
     909             :         "g(15);x",
     910          10 :         EXPECT_RESULT, Number::New(CcTest::isolate(), 15));
     911           5 :     context.Check("h({})", EXPECT_RESULT, number_string);
     912          10 :     context.Check("f({})", EXPECT_RESULT, Number::New(CcTest::isolate(), 15));
     913           5 :     context.Check("h({})", EXPECT_RESULT, number_string);
     914           5 :   }
     915           5 : }
     916             : 
     917             : 
     918       23723 : TEST(CrossScriptLoadICs) {
     919           5 :   i::FLAG_allow_natives_syntax = true;
     920             : 
     921           5 :   HandleScope handle_scope(CcTest::isolate());
     922             : 
     923             :   {
     924           5 :     SimpleContext context;
     925             :     context.Check(
     926             :         "x = 15;"
     927             :         "function f() { return x; }"
     928             :         "function g() { return x; }"
     929             :         "f()",
     930          10 :         EXPECT_RESULT, Number::New(CcTest::isolate(), 15));
     931             :     context.Check(
     932             :         "'use strict';"
     933             :         "let x = 5;"
     934             :         "f()",
     935          10 :         EXPECT_RESULT, Number::New(CcTest::isolate(), 5));
     936          20 :     for (int k = 0; k < 3; k++) {
     937          30 :       context.Check("g()", EXPECT_RESULT, Number::New(CcTest::isolate(), 5));
     938             :     }
     939          15 :     for (int k = 0; k < 3; k++) {
     940          30 :       context.Check("f()", EXPECT_RESULT, Number::New(CcTest::isolate(), 5));
     941             :     }
     942             :     context.Check("%OptimizeFunctionOnNextCall(g); g()", EXPECT_RESULT,
     943          10 :                   Number::New(CcTest::isolate(), 5));
     944             :     context.Check("%OptimizeFunctionOnNextCall(f); f()", EXPECT_RESULT,
     945          10 :                   Number::New(CcTest::isolate(), 5));
     946             :   }
     947             :   {
     948           5 :     SimpleContext context;
     949             :     context.Check(
     950             :         "x = 15;"
     951             :         "function f() { return x; }"
     952             :         "f()",
     953          10 :         EXPECT_RESULT, Number::New(CcTest::isolate(), 15));
     954          20 :     for (int k = 0; k < 3; k++) {
     955          30 :       context.Check("f()", EXPECT_RESULT, Number::New(CcTest::isolate(), 15));
     956             :     }
     957             :     context.Check("%OptimizeFunctionOnNextCall(f); f()", EXPECT_RESULT,
     958          10 :                   Number::New(CcTest::isolate(), 15));
     959             :     context.Check(
     960             :         "'use strict';"
     961             :         "let x = 5;"
     962             :         "f()",
     963          10 :         EXPECT_RESULT, Number::New(CcTest::isolate(), 5));
     964          20 :     for (int k = 0; k < 3; k++) {
     965          30 :       context.Check("f()", EXPECT_RESULT, Number::New(CcTest::isolate(), 5));
     966             :     }
     967             :     context.Check("%OptimizeFunctionOnNextCall(f); f()", EXPECT_RESULT,
     968          10 :                   Number::New(CcTest::isolate(), 5));
     969           5 :   }
     970           5 : }
     971             : 
     972             : 
     973       23723 : TEST(CrossScriptStoreICs) {
     974           5 :   i::FLAG_allow_natives_syntax = true;
     975             : 
     976           5 :   HandleScope handle_scope(CcTest::isolate());
     977             : 
     978             :   {
     979           5 :     SimpleContext context;
     980             :     context.Check(
     981             :         "var global = this;"
     982             :         "x = 15;"
     983             :         "function f(v) { x = v; }"
     984             :         "function g(v) { x = v; }"
     985             :         "f(10); x",
     986          10 :         EXPECT_RESULT, Number::New(CcTest::isolate(), 10));
     987             :     context.Check(
     988             :         "'use strict';"
     989             :         "let x = 5;"
     990             :         "f(7); x",
     991          10 :         EXPECT_RESULT, Number::New(CcTest::isolate(), 7));
     992             :     context.Check("global.x", EXPECT_RESULT,
     993          10 :                   Number::New(CcTest::isolate(), 10));
     994          20 :     for (int k = 0; k < 3; k++) {
     995             :       context.Check("g(31); x", EXPECT_RESULT,
     996          30 :                     Number::New(CcTest::isolate(), 31));
     997             :     }
     998             :     context.Check("global.x", EXPECT_RESULT,
     999          10 :                   Number::New(CcTest::isolate(), 10));
    1000          20 :     for (int k = 0; k < 3; k++) {
    1001             :       context.Check("f(32); x", EXPECT_RESULT,
    1002          30 :                     Number::New(CcTest::isolate(), 32));
    1003             :     }
    1004             :     context.Check("global.x", EXPECT_RESULT,
    1005          10 :                   Number::New(CcTest::isolate(), 10));
    1006             :     context.Check("%OptimizeFunctionOnNextCall(g); g(18); x", EXPECT_RESULT,
    1007          10 :                   Number::New(CcTest::isolate(), 18));
    1008             :     context.Check("global.x", EXPECT_RESULT,
    1009          10 :                   Number::New(CcTest::isolate(), 10));
    1010             :     context.Check("%OptimizeFunctionOnNextCall(f); f(33); x", EXPECT_RESULT,
    1011          10 :                   Number::New(CcTest::isolate(), 33));
    1012             :     context.Check("global.x", EXPECT_RESULT,
    1013          10 :                   Number::New(CcTest::isolate(), 10));
    1014             :   }
    1015             :   {
    1016           5 :     SimpleContext context;
    1017             :     context.Check(
    1018             :         "var global = this;"
    1019             :         "x = 15;"
    1020             :         "function f(v) { x = v; }"
    1021             :         "f(10); x",
    1022          10 :         EXPECT_RESULT, Number::New(CcTest::isolate(), 10));
    1023          20 :     for (int k = 0; k < 3; k++) {
    1024             :       context.Check("f(18); x", EXPECT_RESULT,
    1025          30 :                     Number::New(CcTest::isolate(), 18));
    1026             :     }
    1027             :     context.Check("%OptimizeFunctionOnNextCall(f); f(20); x", EXPECT_RESULT,
    1028          10 :                   Number::New(CcTest::isolate(), 20));
    1029             :     context.Check(
    1030             :         "'use strict';"
    1031             :         "let x = 5;"
    1032             :         "f(8); x",
    1033          10 :         EXPECT_RESULT, Number::New(CcTest::isolate(), 8));
    1034             :     context.Check("global.x", EXPECT_RESULT,
    1035          10 :                   Number::New(CcTest::isolate(), 20));
    1036          20 :     for (int k = 0; k < 3; k++) {
    1037             :       context.Check("f(13); x", EXPECT_RESULT,
    1038          30 :                     Number::New(CcTest::isolate(), 13));
    1039             :     }
    1040             :     context.Check("global.x", EXPECT_RESULT,
    1041          10 :                   Number::New(CcTest::isolate(), 20));
    1042             :     context.Check("%OptimizeFunctionOnNextCall(f); f(41); x", EXPECT_RESULT,
    1043          10 :                   Number::New(CcTest::isolate(), 41));
    1044             :     context.Check("global.x", EXPECT_RESULT,
    1045          10 :                   Number::New(CcTest::isolate(), 20));
    1046           5 :   }
    1047           5 : }
    1048             : 
    1049             : 
    1050       23723 : TEST(CrossScriptAssignmentToConst) {
    1051           5 :   i::FLAG_allow_natives_syntax = true;
    1052             : 
    1053           5 :   HandleScope handle_scope(CcTest::isolate());
    1054             : 
    1055             :   {
    1056           5 :     SimpleContext context;
    1057             : 
    1058             :     context.Check("function f() { x = 27; }", EXPECT_RESULT,
    1059          10 :                   Undefined(CcTest::isolate()));
    1060             :     context.Check("'use strict';const x = 1; x", EXPECT_RESULT,
    1061          10 :                   Number::New(CcTest::isolate(), 1));
    1062           5 :     context.Check("f();", EXPECT_EXCEPTION);
    1063          10 :     context.Check("x", EXPECT_RESULT, Number::New(CcTest::isolate(), 1));
    1064           5 :     context.Check("f();", EXPECT_EXCEPTION);
    1065          10 :     context.Check("x", EXPECT_RESULT, Number::New(CcTest::isolate(), 1));
    1066           5 :     context.Check("%OptimizeFunctionOnNextCall(f);f();", EXPECT_EXCEPTION);
    1067          10 :     context.Check("x", EXPECT_RESULT, Number::New(CcTest::isolate(), 1));
    1068           5 :   }
    1069           5 : }
    1070             : 
    1071             : 
    1072       23723 : TEST(Regress425510) {
    1073           5 :   i::FLAG_allow_natives_syntax = true;
    1074             : 
    1075           5 :   HandleScope handle_scope(CcTest::isolate());
    1076             : 
    1077             :   {
    1078           5 :     SimpleContext context;
    1079             : 
    1080           5 :     context.Check("'use strict'; o; const o = 10", EXPECT_EXCEPTION);
    1081             : 
    1082         505 :     for (int i = 0; i < 100; i++) {
    1083         500 :       context.Check("o.prototype", EXPECT_EXCEPTION);
    1084             :     }
    1085           5 :   }
    1086           5 : }
    1087             : 
    1088             : 
    1089       23723 : TEST(Regress3941) {
    1090           5 :   i::FLAG_allow_natives_syntax = true;
    1091             : 
    1092           5 :   HandleScope handle_scope(CcTest::isolate());
    1093             : 
    1094             :   {
    1095           5 :     SimpleContext context;
    1096             :     context.Check("function f() { x = 1; }", EXPECT_RESULT,
    1097          10 :                   Undefined(CcTest::isolate()));
    1098           5 :     context.Check("'use strict'; f(); let x = 2; x", EXPECT_EXCEPTION);
    1099             :   }
    1100             : 
    1101             : 
    1102             :   {
    1103             :     // Train ICs.
    1104           5 :     SimpleContext context;
    1105             :     context.Check("function f() { x = 1; }", EXPECT_RESULT,
    1106          10 :                   Undefined(CcTest::isolate()));
    1107          25 :     for (int i = 0; i < 4; i++) {
    1108          40 :       context.Check("f(); x", EXPECT_RESULT, Number::New(CcTest::isolate(), 1));
    1109             :     }
    1110           5 :     context.Check("'use strict'; f(); let x = 2; x", EXPECT_EXCEPTION);
    1111             :   }
    1112             : 
    1113             : 
    1114             :   {
    1115             :     // Optimize.
    1116           5 :     SimpleContext context;
    1117             :     context.Check("function f() { x = 1; }", EXPECT_RESULT,
    1118          10 :                   Undefined(CcTest::isolate()));
    1119          25 :     for (int i = 0; i < 4; i++) {
    1120          40 :       context.Check("f(); x", EXPECT_RESULT, Number::New(CcTest::isolate(), 1));
    1121             :     }
    1122             :     context.Check("%OptimizeFunctionOnNextCall(f); f(); x", EXPECT_RESULT,
    1123          10 :                   Number::New(CcTest::isolate(), 1));
    1124             : 
    1125           5 :     context.Check("'use strict'; f(); let x = 2; x", EXPECT_EXCEPTION);
    1126           5 :   }
    1127           5 : }
    1128             : 
    1129             : 
    1130       23723 : TEST(Regress3941_Reads) {
    1131           5 :   i::FLAG_allow_natives_syntax = true;
    1132             : 
    1133           5 :   HandleScope handle_scope(CcTest::isolate());
    1134             : 
    1135             :   {
    1136           5 :     SimpleContext context;
    1137             :     context.Check("function f() { return x; }", EXPECT_RESULT,
    1138          10 :                   Undefined(CcTest::isolate()));
    1139           5 :     context.Check("'use strict'; f(); let x = 2; x", EXPECT_EXCEPTION);
    1140             :   }
    1141             : 
    1142             : 
    1143             :   {
    1144             :     // Train ICs.
    1145           5 :     SimpleContext context;
    1146             :     context.Check("function f() { return x; }", EXPECT_RESULT,
    1147          10 :                   Undefined(CcTest::isolate()));
    1148          25 :     for (int i = 0; i < 4; i++) {
    1149          20 :       context.Check("f()", EXPECT_EXCEPTION);
    1150             :     }
    1151           5 :     context.Check("'use strict'; f(); let x = 2; x", EXPECT_EXCEPTION);
    1152             :   }
    1153             : 
    1154             : 
    1155             :   {
    1156             :     // Optimize.
    1157           5 :     SimpleContext context;
    1158             :     context.Check("function f() { return x; }", EXPECT_RESULT,
    1159          10 :                   Undefined(CcTest::isolate()));
    1160          25 :     for (int i = 0; i < 4; i++) {
    1161          20 :       context.Check("f()", EXPECT_EXCEPTION);
    1162             :     }
    1163             :     context.Check("%OptimizeFunctionOnNextCall(f);", EXPECT_RESULT,
    1164          10 :                   Undefined(CcTest::isolate()));
    1165             : 
    1166           5 :     context.Check("'use strict'; f(); let x = 2; x", EXPECT_EXCEPTION);
    1167           5 :   }
    1168           5 : }
    1169             : 
    1170       71154 : }  // namespace v8

Generated by: LCOV version 1.10