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: 2019-01-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 "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          85 :   virtual ~DeclarationContext() {
      54          85 :     if (is_initialized_) {
      55          85 :       Isolate* isolate = CcTest::isolate();
      56          85 :       HandleScope scope(isolate);
      57             :       Local<Context> context = Local<Context>::New(isolate, context_);
      58          85 :       context->Exit();
      59          85 :       context_.Reset();
      60             :     }
      61          85 :   }
      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          70 :   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          10 :   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         170 :     : is_initialized_(false), get_count_(0), set_count_(0), query_count_(0) {
     113             :   // Do nothing.
     114             : }
     115             : 
     116             : 
     117         100 : void DeclarationContext::InitializeIfNeeded() {
     118         115 :   if (is_initialized_) return;
     119          85 :   Isolate* isolate = CcTest::isolate();
     120          85 :   HandleScope scope(isolate);
     121          85 :   Local<FunctionTemplate> function = FunctionTemplate::New(isolate);
     122          85 :   Local<Value> data = External::New(CcTest::isolate(), this);
     123          85 :   GetHolder(function)->SetHandler(v8::NamedPropertyHandlerConfiguration(
     124         170 :       &HandleGet, &HandleSet, &HandleQuery, nullptr, nullptr, data));
     125             :   Local<Context> context = Context::New(
     126         170 :       isolate, nullptr, function->InstanceTemplate(), Local<Value>());
     127             :   context_.Reset(isolate, context);
     128          85 :   context->Enter();
     129          85 :   is_initialized_ = true;
     130             :   // Reset counts. Bootstrapping might have called into the interceptor.
     131          85 :   get_count_ = 0;
     132          85 :   set_count_ = 0;
     133          85 :   query_count_ = 0;
     134          85 :   PostInitializeContext(context);
     135             : }
     136             : 
     137             : 
     138          85 : void DeclarationContext::Check(const char* source, int get, int set, int query,
     139             :                                Expectations expectations,
     140         255 :                                v8::Local<Value> value) {
     141          85 :   InitializeIfNeeded();
     142             :   // A retry after a GC may pollute the counts, so perform gc now
     143             :   // to avoid that.
     144          85 :   CcTest::CollectGarbage(v8::internal::NEW_SPACE);
     145          85 :   HandleScope scope(CcTest::isolate());
     146         170 :   TryCatch catcher(CcTest::isolate());
     147          85 :   catcher.SetVerbose(true);
     148          85 :   Local<Context> context = CcTest::isolate()->GetCurrentContext();
     149             :   MaybeLocal<Script> script = Script::Compile(
     150             :       context,
     151          85 :       String::NewFromUtf8(CcTest::isolate(), source, v8::NewStringType::kNormal)
     152         170 :           .ToLocalChecked());
     153          85 :   if (expectations == EXPECT_ERROR) {
     154           0 :     CHECK(script.IsEmpty());
     155           0 :     return;
     156             :   }
     157          85 :   CHECK(!script.IsEmpty());
     158          85 :   MaybeLocal<Value> result = script.ToLocalChecked()->Run(context);
     159          85 :   CHECK_EQ(get, get_count());
     160          85 :   CHECK_EQ(set, set_count());
     161          85 :   CHECK_EQ(query, query_count());
     162          85 :   if (expectations == EXPECT_RESULT) {
     163          85 :     CHECK(!catcher.HasCaught());
     164          85 :     if (!value.IsEmpty()) {
     165         130 :       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         170 :   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          50 :   info.GetReturnValue().Set(context->Get(key));
     184          50 : }
     185             : 
     186             : 
     187          35 : void DeclarationContext::HandleSet(
     188             :     Local<Name> key, Local<Value> value,
     189             :     const v8::PropertyCallbackInfo<v8::Value>& info) {
     190             :   DeclarationContext* context = GetInstance(info.Data());
     191          35 :   context->set_count_++;
     192          35 :   info.GetReturnValue().Set(context->Set(key, value));
     193          35 : }
     194             : 
     195             : 
     196          25 : void DeclarationContext::HandleQuery(
     197             :     Local<Name> key, const v8::PropertyCallbackInfo<v8::Integer>& info) {
     198             :   DeclarationContext* context = GetInstance(info.Data());
     199          25 :   context->query_count_++;
     200          25 :   info.GetReturnValue().Set(context->Query(key));
     201          25 : }
     202             : 
     203             : 
     204             : DeclarationContext* DeclarationContext::GetInstance(Local<Value> data) {
     205         110 :   void* value = Local<External>::Cast(data)->Value();
     206             :   return static_cast<DeclarationContext*>(value);
     207             : }
     208             : 
     209             : 
     210          50 : v8::Local<Value> DeclarationContext::Get(Local<Name> key) {
     211          50 :   return v8::Local<Value>();
     212             : }
     213             : 
     214             : 
     215          35 : v8::Local<Value> DeclarationContext::Set(Local<Name> key, Local<Value> value) {
     216          35 :   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       28342 : TEST(Unknown) {
     229           5 :   HandleScope scope(CcTest::isolate());
     230           5 :   v8::V8::Initialize();
     231             : 
     232             :   { DeclarationContext context;
     233             :     context.Check("var x; x",
     234             :                   1,  // access
     235          10 :                   0, 0, EXPECT_RESULT, Undefined(CcTest::isolate()));
     236             :   }
     237             : 
     238             :   { DeclarationContext context;
     239             :     context.Check("var x = 0; x",
     240             :                   1,  // access
     241             :                   1,  // initialization
     242          10 :                   0, EXPECT_RESULT, Number::New(CcTest::isolate(), 0));
     243             :   }
     244             : 
     245             :   { DeclarationContext context;
     246             :     context.Check("function x() { }; x",
     247             :                   1,  // access
     248           5 :                   1, 1, EXPECT_RESULT);
     249           5 :   }
     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       28342 : TEST(Absent) {
     262           5 :   v8::Isolate* isolate = CcTest::isolate();
     263           5 :   v8::V8::Initialize();
     264           5 :   HandleScope scope(isolate);
     265             : 
     266             :   { AbsentPropertyContext context;
     267             :     context.Check("var x; x",
     268             :                   1,  // access
     269           5 :                   0, 0, EXPECT_RESULT, Undefined(isolate));
     270             :   }
     271             : 
     272             :   { AbsentPropertyContext context;
     273             :     context.Check("var x = 0; x",
     274             :                   1,  // access
     275             :                   1,  // initialization
     276          10 :                   0, EXPECT_RESULT, Number::New(isolate, 0));
     277             :   }
     278             : 
     279             :   { AbsentPropertyContext context;
     280             :     context.Check("function x() { }; x",
     281             :                   1,  // access
     282           5 :                   1, 1, EXPECT_RESULT);
     283             :   }
     284             : 
     285             :   { AbsentPropertyContext context;
     286             :     context.Check("if (false) { var x = 0 }; x",
     287             :                   1,  // access
     288           5 :                   0, 0, EXPECT_RESULT, Undefined(isolate));
     289           5 :   }
     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       28342 : TEST(Appearing) {
     331           5 :   v8::V8::Initialize();
     332           5 :   HandleScope scope(CcTest::isolate());
     333             : 
     334             :   { AppearingPropertyContext context;
     335             :     context.Check("var x; x",
     336             :                   1,  // access
     337          10 :                   0, 0, EXPECT_RESULT, Undefined(CcTest::isolate()));
     338             :   }
     339             : 
     340             :   { AppearingPropertyContext context;
     341             :     context.Check("var x = 0; x",
     342             :                   1,  // access
     343             :                   1,  // initialization
     344          10 :                   0, EXPECT_RESULT, Number::New(CcTest::isolate(), 0));
     345             :   }
     346             : 
     347             :   { AppearingPropertyContext context;
     348             :     context.Check("function x() { }; x",
     349             :                   1,  // access
     350           5 :                   1, 1, EXPECT_RESULT);
     351           5 :   }
     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       28342 : TEST(ExistsInPrototype) {
     373           5 :   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             :     context.Check("this.x = 87; this.x", 0, 0, 1, EXPECT_RESULT,
     379          10 :                   Number::New(CcTest::isolate(), 87));
     380             :   }
     381             : 
     382             :   { ExistsInPrototypeContext context;
     383             :     context.Check("var x; x",
     384             :                   0,
     385             :                   0,
     386             :                   0,
     387          10 :                   EXPECT_RESULT, Undefined(CcTest::isolate()));
     388             :   }
     389             : 
     390             :   { ExistsInPrototypeContext context;
     391             :     context.Check("var x = 0; x",
     392             :                   0,
     393             :                   0,
     394             :                   0,
     395          10 :                   EXPECT_RESULT, Number::New(CcTest::isolate(), 0));
     396           5 :   }
     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       28342 : TEST(AbsentInPrototype) {
     416           5 :   v8::V8::Initialize();
     417           5 :   HandleScope scope(CcTest::isolate());
     418             : 
     419             :   { AbsentInPrototypeContext context;
     420             :     context.Check("if (false) { var x = 0; }; x",
     421             :                   0,
     422             :                   0,
     423             :                   0,
     424          10 :                   EXPECT_RESULT, Undefined(CcTest::isolate()));
     425           5 :   }
     426           5 : }
     427             : 
     428             : 
     429             : 
     430          15 : class ExistsInHiddenPrototypeContext: public DeclarationContext {
     431             :  public:
     432          30 :   ExistsInHiddenPrototypeContext() {
     433          15 :     hidden_proto_ = FunctionTemplate::New(CcTest::isolate());
     434          15 :     hidden_proto_->SetHiddenPrototype(true);
     435          15 :   }
     436             : 
     437             :  protected:
     438           5 :   v8::Local<Integer> Query(Local<Name> key) override {
     439             :     // Let it seem that the property exists in the hidden prototype object.
     440           5 :     return Integer::New(isolate(), v8::None);
     441             :   }
     442             : 
     443             :   // Install the hidden prototype after the global object has been created.
     444          15 :   void PostInitializeContext(Local<Context> context) override {
     445          15 :     Local<Object> global_object = context->Global();
     446             :     Local<Object> hidden_proto = hidden_proto_->GetFunction(context)
     447          15 :                                      .ToLocalChecked()
     448             :                                      ->NewInstance(context)
     449             :                                      .ToLocalChecked();
     450             :     Local<Object> inner_global =
     451          15 :         Local<Object>::Cast(global_object->GetPrototype());
     452          30 :     inner_global->SetPrototype(context, hidden_proto).FromJust();
     453          15 :   }
     454             : 
     455             :   // Use the hidden prototype as the holder for the interceptors.
     456          15 :   Local<ObjectTemplate> GetHolder(Local<FunctionTemplate> function) override {
     457          15 :     return hidden_proto_->InstanceTemplate();
     458             :   }
     459             : 
     460             :  private:
     461             :   Local<FunctionTemplate> hidden_proto_;
     462             : };
     463             : 
     464             : 
     465       28342 : TEST(ExistsInHiddenPrototype) {
     466           5 :   HandleScope scope(CcTest::isolate());
     467             : 
     468           5 :   { ExistsInHiddenPrototypeContext context;
     469             :     context.Check("var x; x", 0, 0, 0, EXPECT_RESULT,
     470          10 :                   Undefined(CcTest::isolate()));
     471             :   }
     472             : 
     473           5 :   { ExistsInHiddenPrototypeContext context;
     474             :     context.Check("var x = 0; x", 0, 0, 0, EXPECT_RESULT,
     475          10 :                   Number::New(CcTest::isolate(), 0));
     476             :   }
     477             : 
     478           5 :   { ExistsInHiddenPrototypeContext context;
     479           5 :     context.Check("function x() { }; x", 0, 1, 1, EXPECT_RESULT);
     480           5 :   }
     481           5 : }
     482             : 
     483             : 
     484             : 
     485             : class SimpleContext {
     486             :  public:
     487         705 :   SimpleContext()
     488             :       : handle_scope_(CcTest::isolate()),
     489        1410 :         context_(Context::New(CcTest::isolate())) {
     490         705 :     context_->Enter();
     491         705 :   }
     492             : 
     493         705 :   ~SimpleContext() {
     494         705 :     context_->Exit();
     495             :   }
     496             : 
     497        2950 :   void Check(const char* source, Expectations expectations,
     498             :              v8::Local<Value> value = Local<Value>()) {
     499        2950 :     HandleScope scope(context_->GetIsolate());
     500        5900 :     TryCatch catcher(context_->GetIsolate());
     501        2950 :     catcher.SetVerbose(true);
     502             :     MaybeLocal<Script> script = Script::Compile(
     503             :         context_, String::NewFromUtf8(context_->GetIsolate(), source,
     504        2950 :                                       v8::NewStringType::kNormal)
     505        5900 :                       .ToLocalChecked());
     506        2950 :     if (expectations == EXPECT_ERROR) {
     507           0 :       CHECK(script.IsEmpty());
     508           0 :       return;
     509             :     }
     510        2950 :     CHECK(!script.IsEmpty());
     511        2950 :     MaybeLocal<Value> result = script.ToLocalChecked()->Run(context_);
     512        2950 :     if (expectations == EXPECT_RESULT) {
     513        2285 :       CHECK(!catcher.HasCaught());
     514        2285 :       if (!value.IsEmpty()) {
     515        4570 :         CHECK(value->Equals(context_, result.ToLocalChecked()).FromJust());
     516             :       }
     517             :     } else {
     518         665 :       CHECK(expectations == EXPECT_EXCEPTION);
     519         665 :       CHECK(catcher.HasCaught());
     520         665 :       if (!value.IsEmpty()) {
     521           0 :         CHECK(value->Equals(context_, catcher.Exception()).FromJust());
     522             :       }
     523        2950 :     }
     524             :   }
     525             : 
     526             :  private:
     527             :   HandleScope handle_scope_;
     528             :   Local<Context> context_;
     529             : };
     530             : 
     531             : 
     532       28342 : TEST(CrossScriptReferences) {
     533           5 :   v8::Isolate* isolate = CcTest::isolate();
     534           5 :   HandleScope scope(isolate);
     535             : 
     536           5 :   { SimpleContext context;
     537             :     context.Check("var x = 1; x",
     538          10 :                   EXPECT_RESULT, Number::New(isolate, 1));
     539             :     context.Check("var x = 2; x",
     540          10 :                   EXPECT_RESULT, Number::New(isolate, 2));
     541             :     context.Check("x = 5; x",
     542          10 :                   EXPECT_RESULT, Number::New(isolate, 5));
     543             :     context.Check("var x = 6; x",
     544          10 :                   EXPECT_RESULT, Number::New(isolate, 6));
     545             :     context.Check("this.x",
     546          10 :                   EXPECT_RESULT, Number::New(isolate, 6));
     547             :     context.Check("function x() { return 7 }; x()",
     548          10 :                   EXPECT_RESULT, Number::New(isolate, 7));
     549           5 :   }
     550           5 : }
     551             : 
     552             : 
     553       28342 : TEST(CrossScriptReferences_Simple) {
     554           5 :   i::FLAG_use_strict = true;
     555             : 
     556           5 :   v8::Isolate* isolate = CcTest::isolate();
     557           5 :   HandleScope scope(isolate);
     558             : 
     559             :   {
     560           5 :     SimpleContext context;
     561          10 :     context.Check("let x = 1; x", EXPECT_RESULT, Number::New(isolate, 1));
     562           5 :     context.Check("let x = 5; x", EXPECT_EXCEPTION);
     563           5 :   }
     564           5 : }
     565             : 
     566             : 
     567       28342 : TEST(CrossScriptReferences_Simple2) {
     568           5 :   i::FLAG_use_strict = true;
     569             : 
     570           5 :   v8::Isolate* isolate = CcTest::isolate();
     571           5 :   HandleScope scope(isolate);
     572             : 
     573         505 :   for (int k = 0; k < 100; k++) {
     574         500 :     SimpleContext context;
     575         500 :     bool cond = (k % 2) == 0;
     576         500 :     if (cond) {
     577         500 :       context.Check("let x = 1; x", EXPECT_RESULT, Number::New(isolate, 1));
     578         500 :       context.Check("let z = 4; z", EXPECT_RESULT, Number::New(isolate, 4));
     579             :     } else {
     580         500 :       context.Check("let z = 1; z", EXPECT_RESULT, Number::New(isolate, 1));
     581         500 :       context.Check("let x = 4; x", EXPECT_RESULT, Number::New(isolate, 4));
     582             :     }
     583             :     context.Check("let y = 2; x", EXPECT_RESULT,
     584        1000 :                   Number::New(isolate, cond ? 1 : 4));
     585           5 :   }
     586           5 : }
     587             : 
     588             : 
     589       28342 : TEST(CrossScriptReferencesHarmony) {
     590           5 :   v8::Isolate* isolate = CcTest::isolate();
     591           5 :   HandleScope scope(isolate);
     592             : 
     593             :   // Check that simple cross-script global scope access works.
     594             :   const char* decs[] = {"'use strict'; var x = 1; x",
     595             :                         "x",
     596             :                         "'use strict'; function x() { return 1 }; x()",
     597             :                         "x()",
     598             :                         "'use strict'; let x = 1; x",
     599             :                         "x",
     600             :                         "'use strict'; const x = 1; x",
     601             :                         "x",
     602           5 :                         nullptr};
     603             : 
     604          25 :   for (int i = 0; decs[i] != nullptr; i += 2) {
     605          20 :     SimpleContext context;
     606          40 :     context.Check(decs[i], EXPECT_RESULT, Number::New(isolate, 1));
     607          40 :     context.Check(decs[i+1], EXPECT_RESULT, Number::New(isolate, 1));
     608             :   }
     609             : 
     610             :   // Check that cross-script global scope access works with late declarations.
     611             :   {
     612           5 :     SimpleContext context;
     613             :     context.Check("function d0() { return x0 }",  // dynamic lookup
     614           5 :                   EXPECT_RESULT, Undefined(isolate));
     615             :     context.Check("this.x0 = -1;"
     616             :                   "d0()",
     617          10 :                   EXPECT_RESULT, Number::New(isolate, -1));
     618             :     context.Check("'use strict';"
     619             :                   "function f0() { let y = 10; return x0 + y }"
     620             :                   "function g0() { let y = 10; return eval('x0 + y') }"
     621             :                   "function h0() { let y = 10; return (1,eval)('x0') + y }"
     622             :                   "x0 + f0() + g0() + h0()",
     623          10 :                   EXPECT_RESULT, Number::New(isolate, 26));
     624             : 
     625             :     context.Check("'use strict';"
     626             :                   "let x1 = 1;"
     627             :                   "function f1() { let y = 10; return x1 + y }"
     628             :                   "function g1() { let y = 10; return eval('x1 + y') }"
     629             :                   "function h1() { let y = 10; return (1,eval)('x1') + y }"
     630             :                   "function i1() { "
     631             :                   "  let y = 10; return (typeof x2 === 'undefined' ? 0 : 2) + y"
     632             :                   "}"
     633             :                   "function j1() { let y = 10; return eval('x2 + y') }"
     634             :                   "function k1() { let y = 10; return (1,eval)('x2') + y }"
     635             :                   "function cl() { "
     636             :                   "  let y = 10; "
     637             :                   "  return { "
     638             :                   "    f: function(){ return x1 + y },"
     639             :                   "    g: function(){ return eval('x1 + y') },"
     640             :                   "    h: function(){ return (1,eval)('x1') + y },"
     641             :                   "    i: function(){"
     642             :                   "      return (typeof x2 == 'undefined' ? 0 : 2) + y"
     643             :                   "    },"
     644             :                   "    j: function(){ return eval('x2 + y') },"
     645             :                   "    k: function(){ return (1,eval)('x2') + y },"
     646             :                   "  }"
     647             :                   "}"
     648             :                   "let o = cl();"
     649             :                   "x1 + eval('x1') + (1,eval)('x1') + f1() + g1() + h1();",
     650          10 :                   EXPECT_RESULT, Number::New(isolate, 36));
     651             :     context.Check("x1 + eval('x1') + (1,eval)('x1') + f1() + g1() + h1();",
     652          10 :                   EXPECT_RESULT, Number::New(isolate, 36));
     653             :     context.Check("o.f() + o.g() + o.h();",
     654          10 :                   EXPECT_RESULT, Number::New(isolate, 33));
     655             :     context.Check("i1() + o.i();",
     656          10 :                   EXPECT_RESULT, Number::New(isolate, 20));
     657             : 
     658             :     context.Check("'use strict';"
     659             :                   "let x2 = 2;"
     660             :                   "function f2() { let y = 20; return x2 + y }"
     661             :                   "function g2() { let y = 20; return eval('x2 + y') }"
     662             :                   "function h2() { let y = 20; return (1,eval)('x2') + y }"
     663             :                   "function i2() { let y = 20; return x1 + y }"
     664             :                   "function j2() { let y = 20; return eval('x1 + y') }"
     665             :                   "function k2() { let y = 20; return (1,eval)('x1') + y }"
     666             :                   "x2 + eval('x2') + (1,eval)('x2') + f2() + g2() + h2();",
     667          10 :                   EXPECT_RESULT, Number::New(isolate, 72));
     668             :     context.Check("x1 + eval('x1') + (1,eval)('x1') + f1() + g1() + h1();",
     669          10 :                   EXPECT_RESULT, Number::New(isolate, 36));
     670             :     context.Check("i1() + j1() + k1();",
     671          10 :                   EXPECT_RESULT, Number::New(isolate, 36));
     672             :     context.Check("i2() + j2() + k2();",
     673          10 :                   EXPECT_RESULT, Number::New(isolate, 63));
     674             :     context.Check("o.f() + o.g() + o.h();",
     675          10 :                   EXPECT_RESULT, Number::New(isolate, 33));
     676             :     context.Check("o.i() + o.j() + o.k();",
     677          10 :                   EXPECT_RESULT, Number::New(isolate, 36));
     678             :     context.Check("i1() + o.i();",
     679          10 :                   EXPECT_RESULT, Number::New(isolate, 24));
     680             : 
     681             :     context.Check("'use strict';"
     682             :                   "let x0 = 100;"
     683             :                   "x0 + eval('x0') + (1,eval)('x0') + "
     684             :                   "    d0() + f0() + g0() + h0();",
     685          10 :                   EXPECT_RESULT, Number::New(isolate, 730));
     686             :     context.Check("x0 + eval('x0') + (1,eval)('x0') + "
     687             :                   "    d0() + f0() + g0() + h0();",
     688          10 :                   EXPECT_RESULT, Number::New(isolate, 730));
     689             :     context.Check("delete this.x0;"
     690             :                   "x0 + eval('x0') + (1,eval)('x0') + "
     691             :                   "    d0() + f0() + g0() + h0();",
     692          10 :                   EXPECT_RESULT, Number::New(isolate, 730));
     693             :     context.Check("this.x1 = 666;"
     694             :                   "x1 + eval('x1') + (1,eval)('x1') + f1() + g1() + h1();",
     695          10 :                   EXPECT_RESULT, Number::New(isolate, 36));
     696             :     context.Check("delete this.x1;"
     697             :                   "x1 + eval('x1') + (1,eval)('x1') + f1() + g1() + h1();",
     698          10 :                   EXPECT_RESULT, Number::New(isolate, 36));
     699             :   }
     700             : 
     701             :   // Check that caching does respect scopes.
     702             :   {
     703           5 :     SimpleContext context;
     704             :     const char* script1 = "(function(){ return y1 })()";
     705             :     const char* script2 = "(function(){ return y2 })()";
     706             : 
     707           5 :     context.Check(script1, EXPECT_EXCEPTION);
     708             :     context.Check("this.y1 = 1; this.y2 = 2; 0;",
     709          10 :                   EXPECT_RESULT, Number::New(isolate, 0));
     710             :     context.Check(script1,
     711          10 :                   EXPECT_RESULT, Number::New(isolate, 1));
     712             :     context.Check("'use strict'; let y1 = 3; 0;",
     713          10 :                   EXPECT_RESULT, Number::New(isolate, 0));
     714             :     context.Check(script1,
     715          10 :                   EXPECT_RESULT, Number::New(isolate, 3));
     716             :     context.Check("y1 = 4;",
     717          10 :                   EXPECT_RESULT, Number::New(isolate, 4));
     718             :     context.Check(script1,
     719          10 :                   EXPECT_RESULT, Number::New(isolate, 4));
     720             : 
     721             :     context.Check(script2,
     722          10 :                   EXPECT_RESULT, Number::New(isolate, 2));
     723             :     context.Check("'use strict'; let y2 = 5; 0;",
     724          10 :                   EXPECT_RESULT, Number::New(isolate, 0));
     725             :     context.Check(script1,
     726          10 :                   EXPECT_RESULT, Number::New(isolate, 4));
     727             :     context.Check(script2,
     728          10 :                   EXPECT_RESULT, Number::New(isolate, 5));
     729           5 :   }
     730           5 : }
     731             : 
     732             : 
     733       28342 : TEST(CrossScriptReferencesHarmonyRegress) {
     734           5 :   v8::Isolate* isolate = CcTest::isolate();
     735           5 :   HandleScope scope(isolate);
     736           5 :   SimpleContext context;
     737             :   context.Check(
     738             :       "'use strict';"
     739             :       "function i1() { "
     740             :       "  let y = 10; return (typeof x2 === 'undefined' ? 0 : 2) + y"
     741             :       "}"
     742             :       "i1();"
     743             :       "i1();",
     744          10 :       EXPECT_RESULT, Number::New(isolate, 10));
     745             :   context.Check(
     746             :       "'use strict';"
     747             :       "let x2 = 2; i1();",
     748          15 :       EXPECT_RESULT, Number::New(isolate, 12));
     749           5 : }
     750             : 
     751             : 
     752       28342 : TEST(GlobalLexicalOSR) {
     753           5 :   i::FLAG_use_strict = true;
     754             : 
     755           5 :   v8::Isolate* isolate = CcTest::isolate();
     756           5 :   HandleScope scope(isolate);
     757           5 :   SimpleContext context;
     758             : 
     759             :   context.Check("'use strict';"
     760             :                 "let x = 1; x;",
     761          10 :                 EXPECT_RESULT, Number::New(isolate, 1));
     762             :   context.Check("'use strict';"
     763             :                 "let y = 2*x;"
     764             :                 "++x;"
     765             :                 "let z = 0;"
     766             :                 "const limit = 100000;"
     767             :                 "for (var i = 0; i < limit; ++i) {"
     768             :                 "  z += x + y;"
     769             :                 "}"
     770             :                 "z;",
     771          15 :                 EXPECT_RESULT, Number::New(isolate, 400000));
     772           5 : }
     773             : 
     774             : 
     775       28342 : TEST(CrossScriptConflicts) {
     776           5 :   i::FLAG_use_strict = true;
     777             : 
     778           5 :   HandleScope scope(CcTest::isolate());
     779             : 
     780             :   const char* firsts[] = {"var x = 1; x", "function x() { return 1 }; x()",
     781           5 :                           "let x = 1; x", "const x = 1; x", nullptr};
     782             :   const char* seconds[] = {"var x = 2; x", "function x() { return 2 }; x()",
     783           5 :                            "let x = 2; x", "const x = 2; x", nullptr};
     784             : 
     785          25 :   for (int i = 0; firsts[i] != nullptr; ++i) {
     786          80 :     for (int j = 0; seconds[j] != nullptr; ++j) {
     787          80 :       SimpleContext context;
     788             :       context.Check(firsts[i], EXPECT_RESULT,
     789         160 :                     Number::New(CcTest::isolate(), 1));
     790          80 :       bool success_case = i < 2 && j < 2;
     791             :       Local<Value> success_result;
     792          80 :       if (success_case) success_result = Number::New(CcTest::isolate(), 2);
     793             : 
     794             :       context.Check(seconds[j], success_case ? EXPECT_RESULT : EXPECT_EXCEPTION,
     795          80 :                     success_result);
     796             :     }
     797           5 :   }
     798           5 : }
     799             : 
     800             : 
     801       28342 : TEST(CrossScriptDynamicLookup) {
     802           5 :   HandleScope handle_scope(CcTest::isolate());
     803             : 
     804             :   {
     805           5 :     SimpleContext context;
     806             :     Local<String> undefined_string =
     807             :         String::NewFromUtf8(CcTest::isolate(), "undefined",
     808           5 :                             v8::NewStringType::kInternalized)
     809           5 :             .ToLocalChecked();
     810             :     Local<String> number_string =
     811             :         String::NewFromUtf8(CcTest::isolate(), "number",
     812           5 :                             v8::NewStringType::kInternalized)
     813           5 :             .ToLocalChecked();
     814             : 
     815             :     context.Check(
     816             :         "function f(o) { with(o) { return x; } }"
     817             :         "function g(o) { with(o) { x = 15; } }"
     818             :         "function h(o) { with(o) { return typeof x; } }",
     819          10 :         EXPECT_RESULT, Undefined(CcTest::isolate()));
     820           5 :     context.Check("h({})", EXPECT_RESULT, undefined_string);
     821             :     context.Check(
     822             :         "'use strict';"
     823             :         "let x = 1;"
     824             :         "f({})",
     825          10 :         EXPECT_RESULT, Number::New(CcTest::isolate(), 1));
     826             :     context.Check(
     827             :         "'use strict';"
     828             :         "g({});0",
     829          10 :         EXPECT_RESULT, Number::New(CcTest::isolate(), 0));
     830          10 :     context.Check("f({})", EXPECT_RESULT, Number::New(CcTest::isolate(), 15));
     831           5 :     context.Check("h({})", EXPECT_RESULT, number_string);
     832           5 :   }
     833           5 : }
     834             : 
     835             : 
     836       28342 : TEST(CrossScriptGlobal) {
     837           5 :   HandleScope handle_scope(CcTest::isolate());
     838             :   {
     839           5 :     SimpleContext context;
     840             : 
     841             :     context.Check(
     842             :         "var global = this;"
     843             :         "global.x = 255;"
     844             :         "x",
     845          10 :         EXPECT_RESULT, Number::New(CcTest::isolate(), 255));
     846             :     context.Check(
     847             :         "'use strict';"
     848             :         "let x = 1;"
     849             :         "global.x",
     850          10 :         EXPECT_RESULT, Number::New(CcTest::isolate(), 255));
     851             :     context.Check("global.x = 15; x", EXPECT_RESULT,
     852          10 :                   Number::New(CcTest::isolate(), 1));
     853             :     context.Check("x = 221; global.x", EXPECT_RESULT,
     854          10 :                   Number::New(CcTest::isolate(), 15));
     855             :     context.Check(
     856             :         "z = 15;"
     857             :         "function f() { return z; };"
     858             :         "for (var k = 0; k < 3; k++) { f(); }"
     859             :         "f()",
     860          10 :         EXPECT_RESULT, Number::New(CcTest::isolate(), 15));
     861             :     context.Check(
     862             :         "'use strict';"
     863             :         "let z = 5; f()",
     864          10 :         EXPECT_RESULT, Number::New(CcTest::isolate(), 5));
     865             :     context.Check(
     866             :         "function f() { konst = 10; return konst; };"
     867             :         "f()",
     868          10 :         EXPECT_RESULT, Number::New(CcTest::isolate(), 10));
     869             :     context.Check(
     870             :         "'use strict';"
     871             :         "const konst = 255;"
     872             :         "f()",
     873           5 :         EXPECT_EXCEPTION);
     874           5 :   }
     875           5 : }
     876             : 
     877             : 
     878       28342 : TEST(CrossScriptStaticLookupUndeclared) {
     879           5 :   HandleScope handle_scope(CcTest::isolate());
     880             : 
     881             :   {
     882           5 :     SimpleContext context;
     883             :     Local<String> undefined_string =
     884             :         String::NewFromUtf8(CcTest::isolate(), "undefined",
     885           5 :                             v8::NewStringType::kInternalized)
     886           5 :             .ToLocalChecked();
     887             :     Local<String> number_string =
     888             :         String::NewFromUtf8(CcTest::isolate(), "number",
     889           5 :                             v8::NewStringType::kInternalized)
     890           5 :             .ToLocalChecked();
     891             : 
     892             :     context.Check(
     893             :         "function f(o) { return x; }"
     894             :         "function g(v) { x = v; }"
     895             :         "function h(o) { return typeof x; }",
     896          10 :         EXPECT_RESULT, Undefined(CcTest::isolate()));
     897           5 :     context.Check("h({})", EXPECT_RESULT, undefined_string);
     898             :     context.Check(
     899             :         "'use strict';"
     900             :         "let x = 1;"
     901             :         "f({})",
     902          10 :         EXPECT_RESULT, Number::New(CcTest::isolate(), 1));
     903             :     context.Check(
     904             :         "'use strict';"
     905             :         "g(15);x",
     906          10 :         EXPECT_RESULT, Number::New(CcTest::isolate(), 15));
     907           5 :     context.Check("h({})", EXPECT_RESULT, number_string);
     908          10 :     context.Check("f({})", EXPECT_RESULT, Number::New(CcTest::isolate(), 15));
     909           5 :     context.Check("h({})", EXPECT_RESULT, number_string);
     910           5 :   }
     911           5 : }
     912             : 
     913             : 
     914       28342 : TEST(CrossScriptLoadICs) {
     915           5 :   i::FLAG_allow_natives_syntax = true;
     916             : 
     917           5 :   HandleScope handle_scope(CcTest::isolate());
     918             : 
     919             :   {
     920           5 :     SimpleContext context;
     921             :     context.Check(
     922             :         "x = 15;"
     923             :         "function f() { return x; }"
     924             :         "function g() { return x; }"
     925             :         "f()",
     926          10 :         EXPECT_RESULT, Number::New(CcTest::isolate(), 15));
     927             :     context.Check(
     928             :         "'use strict';"
     929             :         "let x = 5;"
     930             :         "f()",
     931          10 :         EXPECT_RESULT, Number::New(CcTest::isolate(), 5));
     932          20 :     for (int k = 0; k < 3; k++) {
     933          30 :       context.Check("g()", EXPECT_RESULT, Number::New(CcTest::isolate(), 5));
     934             :     }
     935          15 :     for (int k = 0; k < 3; k++) {
     936          30 :       context.Check("f()", EXPECT_RESULT, Number::New(CcTest::isolate(), 5));
     937             :     }
     938             :     context.Check("%OptimizeFunctionOnNextCall(g); g()", EXPECT_RESULT,
     939          10 :                   Number::New(CcTest::isolate(), 5));
     940             :     context.Check("%OptimizeFunctionOnNextCall(f); f()", EXPECT_RESULT,
     941          10 :                   Number::New(CcTest::isolate(), 5));
     942             :   }
     943             :   {
     944           5 :     SimpleContext context;
     945             :     context.Check(
     946             :         "x = 15;"
     947             :         "function f() { return x; }"
     948             :         "f()",
     949          10 :         EXPECT_RESULT, Number::New(CcTest::isolate(), 15));
     950          20 :     for (int k = 0; k < 3; k++) {
     951          30 :       context.Check("f()", EXPECT_RESULT, Number::New(CcTest::isolate(), 15));
     952             :     }
     953             :     context.Check("%OptimizeFunctionOnNextCall(f); f()", EXPECT_RESULT,
     954          10 :                   Number::New(CcTest::isolate(), 15));
     955             :     context.Check(
     956             :         "'use strict';"
     957             :         "let x = 5;"
     958             :         "f()",
     959          10 :         EXPECT_RESULT, Number::New(CcTest::isolate(), 5));
     960          20 :     for (int k = 0; k < 3; k++) {
     961          30 :       context.Check("f()", EXPECT_RESULT, Number::New(CcTest::isolate(), 5));
     962             :     }
     963             :     context.Check("%OptimizeFunctionOnNextCall(f); f()", EXPECT_RESULT,
     964          10 :                   Number::New(CcTest::isolate(), 5));
     965           5 :   }
     966           5 : }
     967             : 
     968             : 
     969       28342 : TEST(CrossScriptStoreICs) {
     970           5 :   i::FLAG_allow_natives_syntax = true;
     971             : 
     972           5 :   HandleScope handle_scope(CcTest::isolate());
     973             : 
     974             :   {
     975           5 :     SimpleContext context;
     976             :     context.Check(
     977             :         "var global = this;"
     978             :         "x = 15;"
     979             :         "function f(v) { x = v; }"
     980             :         "function g(v) { x = v; }"
     981             :         "f(10); x",
     982          10 :         EXPECT_RESULT, Number::New(CcTest::isolate(), 10));
     983             :     context.Check(
     984             :         "'use strict';"
     985             :         "let x = 5;"
     986             :         "f(7); x",
     987          10 :         EXPECT_RESULT, Number::New(CcTest::isolate(), 7));
     988             :     context.Check("global.x", EXPECT_RESULT,
     989          10 :                   Number::New(CcTest::isolate(), 10));
     990          20 :     for (int k = 0; k < 3; k++) {
     991             :       context.Check("g(31); x", EXPECT_RESULT,
     992          30 :                     Number::New(CcTest::isolate(), 31));
     993             :     }
     994             :     context.Check("global.x", EXPECT_RESULT,
     995          10 :                   Number::New(CcTest::isolate(), 10));
     996          20 :     for (int k = 0; k < 3; k++) {
     997             :       context.Check("f(32); x", EXPECT_RESULT,
     998          30 :                     Number::New(CcTest::isolate(), 32));
     999             :     }
    1000             :     context.Check("global.x", EXPECT_RESULT,
    1001          10 :                   Number::New(CcTest::isolate(), 10));
    1002             :     context.Check("%OptimizeFunctionOnNextCall(g); g(18); x", EXPECT_RESULT,
    1003          10 :                   Number::New(CcTest::isolate(), 18));
    1004             :     context.Check("global.x", EXPECT_RESULT,
    1005          10 :                   Number::New(CcTest::isolate(), 10));
    1006             :     context.Check("%OptimizeFunctionOnNextCall(f); f(33); x", EXPECT_RESULT,
    1007          10 :                   Number::New(CcTest::isolate(), 33));
    1008             :     context.Check("global.x", EXPECT_RESULT,
    1009          10 :                   Number::New(CcTest::isolate(), 10));
    1010             :   }
    1011             :   {
    1012           5 :     SimpleContext context;
    1013             :     context.Check(
    1014             :         "var global = this;"
    1015             :         "x = 15;"
    1016             :         "function f(v) { x = v; }"
    1017             :         "f(10); x",
    1018          10 :         EXPECT_RESULT, Number::New(CcTest::isolate(), 10));
    1019          20 :     for (int k = 0; k < 3; k++) {
    1020             :       context.Check("f(18); x", EXPECT_RESULT,
    1021          30 :                     Number::New(CcTest::isolate(), 18));
    1022             :     }
    1023             :     context.Check("%OptimizeFunctionOnNextCall(f); f(20); x", EXPECT_RESULT,
    1024          10 :                   Number::New(CcTest::isolate(), 20));
    1025             :     context.Check(
    1026             :         "'use strict';"
    1027             :         "let x = 5;"
    1028             :         "f(8); x",
    1029          10 :         EXPECT_RESULT, Number::New(CcTest::isolate(), 8));
    1030             :     context.Check("global.x", EXPECT_RESULT,
    1031          10 :                   Number::New(CcTest::isolate(), 20));
    1032          20 :     for (int k = 0; k < 3; k++) {
    1033             :       context.Check("f(13); x", EXPECT_RESULT,
    1034          30 :                     Number::New(CcTest::isolate(), 13));
    1035             :     }
    1036             :     context.Check("global.x", EXPECT_RESULT,
    1037          10 :                   Number::New(CcTest::isolate(), 20));
    1038             :     context.Check("%OptimizeFunctionOnNextCall(f); f(41); x", EXPECT_RESULT,
    1039          10 :                   Number::New(CcTest::isolate(), 41));
    1040             :     context.Check("global.x", EXPECT_RESULT,
    1041          10 :                   Number::New(CcTest::isolate(), 20));
    1042           5 :   }
    1043           5 : }
    1044             : 
    1045             : 
    1046       28342 : TEST(CrossScriptAssignmentToConst) {
    1047           5 :   i::FLAG_allow_natives_syntax = true;
    1048             : 
    1049           5 :   HandleScope handle_scope(CcTest::isolate());
    1050             : 
    1051             :   {
    1052           5 :     SimpleContext context;
    1053             : 
    1054             :     context.Check("function f() { x = 27; }", EXPECT_RESULT,
    1055          10 :                   Undefined(CcTest::isolate()));
    1056             :     context.Check("'use strict';const x = 1; x", EXPECT_RESULT,
    1057          10 :                   Number::New(CcTest::isolate(), 1));
    1058           5 :     context.Check("f();", EXPECT_EXCEPTION);
    1059          10 :     context.Check("x", EXPECT_RESULT, Number::New(CcTest::isolate(), 1));
    1060           5 :     context.Check("f();", EXPECT_EXCEPTION);
    1061          10 :     context.Check("x", EXPECT_RESULT, Number::New(CcTest::isolate(), 1));
    1062           5 :     context.Check("%OptimizeFunctionOnNextCall(f);f();", EXPECT_EXCEPTION);
    1063          10 :     context.Check("x", EXPECT_RESULT, Number::New(CcTest::isolate(), 1));
    1064           5 :   }
    1065           5 : }
    1066             : 
    1067             : 
    1068       28342 : TEST(Regress425510) {
    1069           5 :   i::FLAG_allow_natives_syntax = true;
    1070             : 
    1071           5 :   HandleScope handle_scope(CcTest::isolate());
    1072             : 
    1073             :   {
    1074           5 :     SimpleContext context;
    1075             : 
    1076           5 :     context.Check("'use strict'; o; const o = 10", EXPECT_EXCEPTION);
    1077             : 
    1078         505 :     for (int i = 0; i < 100; i++) {
    1079         500 :       context.Check("o.prototype", EXPECT_EXCEPTION);
    1080             :     }
    1081           5 :   }
    1082           5 : }
    1083             : 
    1084             : 
    1085       28342 : TEST(Regress3941) {
    1086           5 :   i::FLAG_allow_natives_syntax = true;
    1087             : 
    1088           5 :   HandleScope handle_scope(CcTest::isolate());
    1089             : 
    1090             :   {
    1091           5 :     SimpleContext context;
    1092             :     context.Check("function f() { x = 1; }", EXPECT_RESULT,
    1093          10 :                   Undefined(CcTest::isolate()));
    1094           5 :     context.Check("'use strict'; f(); let x = 2; x", EXPECT_EXCEPTION);
    1095             :   }
    1096             : 
    1097             : 
    1098             :   {
    1099             :     // Train ICs.
    1100           5 :     SimpleContext context;
    1101             :     context.Check("function f() { x = 1; }", EXPECT_RESULT,
    1102          10 :                   Undefined(CcTest::isolate()));
    1103          25 :     for (int i = 0; i < 4; i++) {
    1104          40 :       context.Check("f(); x", EXPECT_RESULT, Number::New(CcTest::isolate(), 1));
    1105             :     }
    1106           5 :     context.Check("'use strict'; f(); let x = 2; x", EXPECT_EXCEPTION);
    1107             :   }
    1108             : 
    1109             : 
    1110             :   {
    1111             :     // Optimize.
    1112           5 :     SimpleContext context;
    1113             :     context.Check("function f() { x = 1; }", EXPECT_RESULT,
    1114          10 :                   Undefined(CcTest::isolate()));
    1115          25 :     for (int i = 0; i < 4; i++) {
    1116          40 :       context.Check("f(); x", EXPECT_RESULT, Number::New(CcTest::isolate(), 1));
    1117             :     }
    1118             :     context.Check("%OptimizeFunctionOnNextCall(f); f(); x", EXPECT_RESULT,
    1119          10 :                   Number::New(CcTest::isolate(), 1));
    1120             : 
    1121           5 :     context.Check("'use strict'; f(); let x = 2; x", EXPECT_EXCEPTION);
    1122           5 :   }
    1123           5 : }
    1124             : 
    1125             : 
    1126       28342 : TEST(Regress3941_Reads) {
    1127           5 :   i::FLAG_allow_natives_syntax = true;
    1128             : 
    1129           5 :   HandleScope handle_scope(CcTest::isolate());
    1130             : 
    1131             :   {
    1132           5 :     SimpleContext context;
    1133             :     context.Check("function f() { return x; }", EXPECT_RESULT,
    1134          10 :                   Undefined(CcTest::isolate()));
    1135           5 :     context.Check("'use strict'; f(); let x = 2; x", EXPECT_EXCEPTION);
    1136             :   }
    1137             : 
    1138             : 
    1139             :   {
    1140             :     // Train ICs.
    1141           5 :     SimpleContext context;
    1142             :     context.Check("function f() { return x; }", EXPECT_RESULT,
    1143          10 :                   Undefined(CcTest::isolate()));
    1144          25 :     for (int i = 0; i < 4; i++) {
    1145          20 :       context.Check("f()", EXPECT_EXCEPTION);
    1146             :     }
    1147           5 :     context.Check("'use strict'; f(); let x = 2; x", EXPECT_EXCEPTION);
    1148             :   }
    1149             : 
    1150             : 
    1151             :   {
    1152             :     // Optimize.
    1153           5 :     SimpleContext context;
    1154             :     context.Check("function f() { return x; }", EXPECT_RESULT,
    1155          10 :                   Undefined(CcTest::isolate()));
    1156          25 :     for (int i = 0; i < 4; i++) {
    1157          20 :       context.Check("f()", EXPECT_EXCEPTION);
    1158             :     }
    1159             :     context.Check("%OptimizeFunctionOnNextCall(f);", EXPECT_RESULT,
    1160          10 :                   Undefined(CcTest::isolate()));
    1161             : 
    1162           5 :     context.Check("'use strict'; f(); let x = 2; x", EXPECT_EXCEPTION);
    1163           5 :   }
    1164           5 : }
    1165             : 
    1166       85011 : }  // namespace v8

Generated by: LCOV version 1.10