LCOV - code coverage report
Current view: top level - test/cctest - test-decls.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 496 516 96.1 %
Date: 2019-04-17 Functions: 38 51 74.5 %

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

Generated by: LCOV version 1.10