// Copyright 2007-2008 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//     * Neither the name of Google Inc. nor the names of its
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include <stdlib.h>

#include "src/v8.h"

#include "src/heap/heap-inl.h"
#include "src/heap/heap.h"
#include "test/cctest/cctest.h"

namespace v8 {

namespace {

enum Expectations {
  EXPECT_RESULT,
  EXPECT_EXCEPTION,
  EXPECT_ERROR
};


// A DeclarationContext holds a reference to a v8::Context and keeps
// track of various declaration related counters to make it easier to
// track if global declarations in the presence of interceptors behave
// the right way.
class DeclarationContext {
 public:
  DeclarationContext();

  virtual ~DeclarationContext() {
    if (is_initialized_) {
      Isolate* isolate = CcTest::isolate();
      HandleScope scope(isolate);
      Local<Context> context = Local<Context>::New(isolate, context_);
      context->Exit();
      context_.Reset();
    }
  }

  void Check(const char* source, int get, int set, int has,
             Expectations expectations,
             v8::Local<Value> value = Local<Value>());

  int get_count() const { return get_count_; }
  int set_count() const { return set_count_; }
  int query_count() const { return query_count_; }

 protected:
  virtual v8::Local<Value> Get(Local<Name> key);
  virtual v8::Local<Value> Set(Local<Name> key, Local<Value> value);
  virtual v8::Local<Integer> Query(Local<Name> key);

  void InitializeIfNeeded();

  // Perform optional initialization steps on the context after it has
  // been created. Defaults to none but may be overwritten.
  virtual void PostInitializeContext(Local<Context> context) {}

  // Get the holder for the interceptor. Default to the instance template
  // but may be overwritten.
  virtual Local<ObjectTemplate> GetHolder(Local<FunctionTemplate> function) {
    return function->InstanceTemplate();
  }

  // The handlers are called as static functions that forward
  // to the instance specific virtual methods.
  static void HandleGet(Local<Name> key,
                        const v8::PropertyCallbackInfo<v8::Value>& info);
  static void HandleSet(Local<Name> key, Local<Value> value,
                        const v8::PropertyCallbackInfo<v8::Value>& info);
  static void HandleQuery(Local<Name> key,
                          const v8::PropertyCallbackInfo<v8::Integer>& info);

  v8::Isolate* isolate() const { return CcTest::isolate(); }

 private:
  bool is_initialized_;
  Persistent<Context> context_;

  int get_count_;
  int set_count_;
  int query_count_;

  static DeclarationContext* GetInstance(Local<Value> data);
};


DeclarationContext::DeclarationContext()
    : is_initialized_(false), get_count_(0), set_count_(0), query_count_(0) {
  // Do nothing.
}


void DeclarationContext::InitializeIfNeeded() {
  if (is_initialized_) return;
  Isolate* isolate = CcTest::isolate();
  HandleScope scope(isolate);
  Local<FunctionTemplate> function = FunctionTemplate::New(isolate);
  Local<Value> data = External::New(CcTest::isolate(), this);
  GetHolder(function)->SetHandler(v8::NamedPropertyHandlerConfiguration(
      &HandleGet, &HandleSet, &HandleQuery, 0, 0, data));
  Local<Context> context = Context::New(isolate,
                                        0,
                                        function->InstanceTemplate(),
                                        Local<Value>());
  context_.Reset(isolate, context);
  context->Enter();
  is_initialized_ = true;
  // Reset counts. Bootstrapping might have called into the interceptor.
  get_count_ = 0;
  set_count_ = 0;
  query_count_ = 0;
  PostInitializeContext(context);
}


void DeclarationContext::Check(const char* source, int get, int set, int query,
                               Expectations expectations,
                               v8::Local<Value> value) {
  InitializeIfNeeded();
  // A retry after a GC may pollute the counts, so perform gc now
  // to avoid that.
  CcTest::CollectGarbage(v8::internal::NEW_SPACE);
  HandleScope scope(CcTest::isolate());
  TryCatch catcher(CcTest::isolate());
  catcher.SetVerbose(true);
  Local<Context> context = CcTest::isolate()->GetCurrentContext();
  MaybeLocal<Script> script = Script::Compile(
      context,
      String::NewFromUtf8(CcTest::isolate(), source, v8::NewStringType::kNormal)
          .ToLocalChecked());
  if (expectations == EXPECT_ERROR) {
    CHECK(script.IsEmpty());
    return;
  }
  CHECK(!script.IsEmpty());
  MaybeLocal<Value> result = script.ToLocalChecked()->Run(context);
  CHECK_EQ(get, get_count());
  CHECK_EQ(set, set_count());
  CHECK_EQ(query, query_count());
  if (expectations == EXPECT_RESULT) {
    CHECK(!catcher.HasCaught());
    if (!value.IsEmpty()) {
      CHECK(value->Equals(context, result.ToLocalChecked()).FromJust());
    }
  } else {
    CHECK(expectations == EXPECT_EXCEPTION);
    CHECK(catcher.HasCaught());
    if (!value.IsEmpty()) {
      CHECK(value->Equals(context, catcher.Exception()).FromJust());
    }
  }
  // Clean slate for the next test.
  CcTest::CollectAllAvailableGarbage();
}


void DeclarationContext::HandleGet(
    Local<Name> key, const v8::PropertyCallbackInfo<v8::Value>& info) {
  DeclarationContext* context = GetInstance(info.Data());
  context->get_count_++;
  info.GetReturnValue().Set(context->Get(key));
}


void DeclarationContext::HandleSet(
    Local<Name> key, Local<Value> value,
    const v8::PropertyCallbackInfo<v8::Value>& info) {
  DeclarationContext* context = GetInstance(info.Data());
  context->set_count_++;
  info.GetReturnValue().Set(context->Set(key, value));
}


void DeclarationContext::HandleQuery(
    Local<Name> key, const v8::PropertyCallbackInfo<v8::Integer>& info) {
  DeclarationContext* context = GetInstance(info.Data());
  context->query_count_++;
  info.GetReturnValue().Set(context->Query(key));
}


DeclarationContext* DeclarationContext::GetInstance(Local<Value> data) {
  void* value = Local<External>::Cast(data)->Value();
  return static_cast<DeclarationContext*>(value);
}


v8::Local<Value> DeclarationContext::Get(Local<Name> key) {
  return v8::Local<Value>();
}


v8::Local<Value> DeclarationContext::Set(Local<Name> key, Local<Value> value) {
  return v8::Local<Value>();
}


v8::Local<Integer> DeclarationContext::Query(Local<Name> key) {
  return v8::Local<Integer>();
}

}  // namespace

// Test global declaration of a property the interceptor doesn't know
// about and doesn't handle.
TEST(Unknown) {
  HandleScope scope(CcTest::isolate());
  v8::V8::Initialize();

  { DeclarationContext context;
    context.Check("var x; x",
                  1,  // access
                  0, 0, EXPECT_RESULT, Undefined(CcTest::isolate()));
  }

  { DeclarationContext context;
    context.Check("var x = 0; x",
                  1,  // access
                  1,  // initialization
                  0, EXPECT_RESULT, Number::New(CcTest::isolate(), 0));
  }

  { DeclarationContext context;
    context.Check("function x() { }; x",
                  1,  // access
                  1, 1, EXPECT_RESULT);
  }
}


class AbsentPropertyContext: public DeclarationContext {
 protected:
  virtual v8::Local<Integer> Query(Local<Name> key) {
    return v8::Local<Integer>();
  }
};


TEST(Absent) {
  v8::Isolate* isolate = CcTest::isolate();
  v8::V8::Initialize();
  HandleScope scope(isolate);

  { AbsentPropertyContext context;
    context.Check("var x; x",
                  1,  // access
                  0, 0, EXPECT_RESULT, Undefined(isolate));
  }

  { AbsentPropertyContext context;
    context.Check("var x = 0; x",
                  1,  // access
                  1,  // initialization
                  0, EXPECT_RESULT, Number::New(isolate, 0));
  }

  { AbsentPropertyContext context;
    context.Check("function x() { }; x",
                  1,  // access
                  1, 1, EXPECT_RESULT);
  }

  { AbsentPropertyContext context;
    context.Check("if (false) { var x = 0 }; x",
                  1,  // access
                  0, 0, EXPECT_RESULT, Undefined(isolate));
  }
}



class AppearingPropertyContext: public DeclarationContext {
 public:
  enum State {
    DECLARE,
    INITIALIZE_IF_ASSIGN,
    UNKNOWN
  };

  AppearingPropertyContext() : state_(DECLARE) { }

 protected:
  virtual v8::Local<Integer> Query(Local<Name> key) {
    switch (state_) {
      case DECLARE:
        // Force declaration by returning that the
        // property is absent.
        state_ = INITIALIZE_IF_ASSIGN;
        return Local<Integer>();
      case INITIALIZE_IF_ASSIGN:
        // Return that the property is present so we only get the
        // setter called when initializing with a value.
        state_ = UNKNOWN;
        return Integer::New(isolate(), v8::None);
      default:
        CHECK(state_ == UNKNOWN);
        break;
    }
    // Do the lookup in the object.
    return v8::Local<Integer>();
  }

 private:
  State state_;
};


TEST(Appearing) {
  v8::V8::Initialize();
  HandleScope scope(CcTest::isolate());

  { AppearingPropertyContext context;
    context.Check("var x; x",
                  1,  // access
                  0, 0, EXPECT_RESULT, Undefined(CcTest::isolate()));
  }

  { AppearingPropertyContext context;
    context.Check("var x = 0; x",
                  1,  // access
                  1,  // initialization
                  0, EXPECT_RESULT, Number::New(CcTest::isolate(), 0));
  }

  { AppearingPropertyContext context;
    context.Check("function x() { }; x",
                  1,  // access
                  1, 1, EXPECT_RESULT);
  }
}



class ExistsInPrototypeContext: public DeclarationContext {
 public:
  ExistsInPrototypeContext() { InitializeIfNeeded(); }
 protected:
  virtual v8::Local<Integer> Query(Local<Name> key) {
    // Let it seem that the property exists in the prototype object.
    return Integer::New(isolate(), v8::None);
  }

  // Use the prototype as the holder for the interceptors.
  virtual Local<ObjectTemplate> GetHolder(Local<FunctionTemplate> function) {
    return function->PrototypeTemplate();
  }
};


TEST(ExistsInPrototype) {
  HandleScope scope(CcTest::isolate());

  // Sanity check to make sure that the holder of the interceptor
  // really is the prototype object.
  { ExistsInPrototypeContext context;
    context.Check("this.x = 87; this.x", 0, 0, 1, EXPECT_RESULT,
                  Number::New(CcTest::isolate(), 87));
  }

  { ExistsInPrototypeContext context;
    context.Check("var x; x",
                  0,
                  0,
                  0,
                  EXPECT_RESULT, Undefined(CcTest::isolate()));
  }

  { ExistsInPrototypeContext context;
    context.Check("var x = 0; x",
                  0,
                  0,
                  0,
                  EXPECT_RESULT, Number::New(CcTest::isolate(), 0));
  }
}



class AbsentInPrototypeContext: public DeclarationContext {
 protected:
  virtual v8::Local<Integer> Query(Local<Name> key) {
    // Let it seem that the property is absent in the prototype object.
    return Local<Integer>();
  }

  // Use the prototype as the holder for the interceptors.
  virtual Local<ObjectTemplate> GetHolder(Local<FunctionTemplate> function) {
    return function->PrototypeTemplate();
  }
};


TEST(AbsentInPrototype) {
  v8::V8::Initialize();
  HandleScope scope(CcTest::isolate());

  { AbsentInPrototypeContext context;
    context.Check("if (false) { var x = 0; }; x",
                  0,
                  0,
                  0,
                  EXPECT_RESULT, Undefined(CcTest::isolate()));
  }
}



class ExistsInHiddenPrototypeContext: public DeclarationContext {
 public:
  ExistsInHiddenPrototypeContext() {
    hidden_proto_ = FunctionTemplate::New(CcTest::isolate());
    hidden_proto_->SetHiddenPrototype(true);
  }

 protected:
  virtual v8::Local<Integer> Query(Local<Name> key) {
    // Let it seem that the property exists in the hidden prototype object.
    return Integer::New(isolate(), v8::None);
  }

  // Install the hidden prototype after the global object has been created.
  virtual void PostInitializeContext(Local<Context> context) {
    Local<Object> global_object = context->Global();
    Local<Object> hidden_proto = hidden_proto_->GetFunction(context)
                                     .ToLocalChecked()
                                     ->NewInstance(context)
                                     .ToLocalChecked();
    Local<Object> inner_global =
        Local<Object>::Cast(global_object->GetPrototype());
    inner_global->SetPrototype(context, hidden_proto).FromJust();
  }

  // Use the hidden prototype as the holder for the interceptors.
  virtual Local<ObjectTemplate> GetHolder(Local<FunctionTemplate> function) {
    return hidden_proto_->InstanceTemplate();
  }

 private:
  Local<FunctionTemplate> hidden_proto_;
};


TEST(ExistsInHiddenPrototype) {
  HandleScope scope(CcTest::isolate());

  { ExistsInHiddenPrototypeContext context;
    context.Check("var x; x", 0, 0, 0, EXPECT_RESULT,
                  Undefined(CcTest::isolate()));
  }

  { ExistsInHiddenPrototypeContext context;
    context.Check("var x = 0; x", 0, 0, 0, EXPECT_RESULT,
                  Number::New(CcTest::isolate(), 0));
  }

  { ExistsInHiddenPrototypeContext context;
    context.Check("function x() { }; x", 0, 1, 1, EXPECT_RESULT);
  }
}



class SimpleContext {
 public:
  SimpleContext()
      : handle_scope_(CcTest::isolate()),
        context_(Context::New(CcTest::isolate())) {
    context_->Enter();
  }

  ~SimpleContext() {
    context_->Exit();
  }

  void Check(const char* source, Expectations expectations,
             v8::Local<Value> value = Local<Value>()) {
    HandleScope scope(context_->GetIsolate());
    TryCatch catcher(context_->GetIsolate());
    catcher.SetVerbose(true);
    MaybeLocal<Script> script = Script::Compile(
        context_, String::NewFromUtf8(context_->GetIsolate(), source,
                                      v8::NewStringType::kNormal)
                      .ToLocalChecked());
    if (expectations == EXPECT_ERROR) {
      CHECK(script.IsEmpty());
      return;
    }
    CHECK(!script.IsEmpty());
    MaybeLocal<Value> result = script.ToLocalChecked()->Run(context_);
    if (expectations == EXPECT_RESULT) {
      CHECK(!catcher.HasCaught());
      if (!value.IsEmpty()) {
        CHECK(value->Equals(context_, result.ToLocalChecked()).FromJust());
      }
    } else {
      CHECK(expectations == EXPECT_EXCEPTION);
      CHECK(catcher.HasCaught());
      if (!value.IsEmpty()) {
        CHECK(value->Equals(context_, catcher.Exception()).FromJust());
      }
    }
  }

 private:
  HandleScope handle_scope_;
  Local<Context> context_;
};


TEST(CrossScriptReferences) {
  v8::Isolate* isolate = CcTest::isolate();
  HandleScope scope(isolate);

  { SimpleContext context;
    context.Check("var x = 1; x",
                  EXPECT_RESULT, Number::New(isolate, 1));
    context.Check("var x = 2; x",
                  EXPECT_RESULT, Number::New(isolate, 2));
    context.Check("x = 5; x",
                  EXPECT_RESULT, Number::New(isolate, 5));
    context.Check("var x = 6; x",
                  EXPECT_RESULT, Number::New(isolate, 6));
    context.Check("this.x",
                  EXPECT_RESULT, Number::New(isolate, 6));
    context.Check("function x() { return 7 }; x()",
                  EXPECT_RESULT, Number::New(isolate, 7));
  }
}


TEST(CrossScriptReferences_Simple) {
  i::FLAG_use_strict = true;

  v8::Isolate* isolate = CcTest::isolate();
  HandleScope scope(isolate);

  {
    SimpleContext context;
    context.Check("let x = 1; x", EXPECT_RESULT, Number::New(isolate, 1));
    context.Check("let x = 5; x", EXPECT_EXCEPTION);
  }
}


TEST(CrossScriptReferences_Simple2) {
  i::FLAG_use_strict = true;

  v8::Isolate* isolate = CcTest::isolate();
  HandleScope scope(isolate);

  for (int k = 0; k < 100; k++) {
    SimpleContext context;
    bool cond = (k % 2) == 0;
    if (cond) {
      context.Check("let x = 1; x", EXPECT_RESULT, Number::New(isolate, 1));
      context.Check("let z = 4; z", EXPECT_RESULT, Number::New(isolate, 4));
    } else {
      context.Check("let z = 1; z", EXPECT_RESULT, Number::New(isolate, 1));
      context.Check("let x = 4; x", EXPECT_RESULT, Number::New(isolate, 4));
    }
    context.Check("let y = 2; x", EXPECT_RESULT,
                  Number::New(isolate, cond ? 1 : 4));
  }
}


TEST(CrossScriptReferencesHarmony) {
  v8::Isolate* isolate = CcTest::isolate();
  HandleScope scope(isolate);

  // Check that simple cross-script global scope access works.
  const char* decs[] = {
    "'use strict'; var x = 1; x", "x",
    "'use strict'; function x() { return 1 }; x()", "x()",
    "'use strict'; let x = 1; x", "x",
    "'use strict'; const x = 1; x", "x",
    NULL
  };

  for (int i = 0; decs[i] != NULL; i += 2) {
    SimpleContext context;
    context.Check(decs[i], EXPECT_RESULT, Number::New(isolate, 1));
    context.Check(decs[i+1], EXPECT_RESULT, Number::New(isolate, 1));
  }

  // Check that cross-script global scope access works with late declarations.
  {
    SimpleContext context;
    context.Check("function d0() { return x0 }",  // dynamic lookup
                  EXPECT_RESULT, Undefined(isolate));
    context.Check("this.x0 = -1;"
                  "d0()",
                  EXPECT_RESULT, Number::New(isolate, -1));
    context.Check("'use strict';"
                  "function f0() { let y = 10; return x0 + y }"
                  "function g0() { let y = 10; return eval('x0 + y') }"
                  "function h0() { let y = 10; return (1,eval)('x0') + y }"
                  "x0 + f0() + g0() + h0()",
                  EXPECT_RESULT, Number::New(isolate, 26));

    context.Check("'use strict';"
                  "let x1 = 1;"
                  "function f1() { let y = 10; return x1 + y }"
                  "function g1() { let y = 10; return eval('x1 + y') }"
                  "function h1() { let y = 10; return (1,eval)('x1') + y }"
                  "function i1() { "
                  "  let y = 10; return (typeof x2 === 'undefined' ? 0 : 2) + y"
                  "}"
                  "function j1() { let y = 10; return eval('x2 + y') }"
                  "function k1() { let y = 10; return (1,eval)('x2') + y }"
                  "function cl() { "
                  "  let y = 10; "
                  "  return { "
                  "    f: function(){ return x1 + y },"
                  "    g: function(){ return eval('x1 + y') },"
                  "    h: function(){ return (1,eval)('x1') + y },"
                  "    i: function(){"
                  "      return (typeof x2 == 'undefined' ? 0 : 2) + y"
                  "    },"
                  "    j: function(){ return eval('x2 + y') },"
                  "    k: function(){ return (1,eval)('x2') + y },"
                  "  }"
                  "}"
                  "let o = cl();"
                  "x1 + eval('x1') + (1,eval)('x1') + f1() + g1() + h1();",
                  EXPECT_RESULT, Number::New(isolate, 36));
    context.Check("x1 + eval('x1') + (1,eval)('x1') + f1() + g1() + h1();",
                  EXPECT_RESULT, Number::New(isolate, 36));
    context.Check("o.f() + o.g() + o.h();",
                  EXPECT_RESULT, Number::New(isolate, 33));
    context.Check("i1() + o.i();",
                  EXPECT_RESULT, Number::New(isolate, 20));

    context.Check("'use strict';"
                  "let x2 = 2;"
                  "function f2() { let y = 20; return x2 + y }"
                  "function g2() { let y = 20; return eval('x2 + y') }"
                  "function h2() { let y = 20; return (1,eval)('x2') + y }"
                  "function i2() { let y = 20; return x1 + y }"
                  "function j2() { let y = 20; return eval('x1 + y') }"
                  "function k2() { let y = 20; return (1,eval)('x1') + y }"
                  "x2 + eval('x2') + (1,eval)('x2') + f2() + g2() + h2();",
                  EXPECT_RESULT, Number::New(isolate, 72));
    context.Check("x1 + eval('x1') + (1,eval)('x1') + f1() + g1() + h1();",
                  EXPECT_RESULT, Number::New(isolate, 36));
    context.Check("i1() + j1() + k1();",
                  EXPECT_RESULT, Number::New(isolate, 36));
    context.Check("i2() + j2() + k2();",
                  EXPECT_RESULT, Number::New(isolate, 63));
    context.Check("o.f() + o.g() + o.h();",
                  EXPECT_RESULT, Number::New(isolate, 33));
    context.Check("o.i() + o.j() + o.k();",
                  EXPECT_RESULT, Number::New(isolate, 36));
    context.Check("i1() + o.i();",
                  EXPECT_RESULT, Number::New(isolate, 24));

    context.Check("'use strict';"
                  "let x0 = 100;"
                  "x0 + eval('x0') + (1,eval)('x0') + "
                  "    d0() + f0() + g0() + h0();",
                  EXPECT_RESULT, Number::New(isolate, 730));
    context.Check("x0 + eval('x0') + (1,eval)('x0') + "
                  "    d0() + f0() + g0() + h0();",
                  EXPECT_RESULT, Number::New(isolate, 730));
    context.Check("delete this.x0;"
                  "x0 + eval('x0') + (1,eval)('x0') + "
                  "    d0() + f0() + g0() + h0();",
                  EXPECT_RESULT, Number::New(isolate, 730));
    context.Check("this.x1 = 666;"
                  "x1 + eval('x1') + (1,eval)('x1') + f1() + g1() + h1();",
                  EXPECT_RESULT, Number::New(isolate, 36));
    context.Check("delete this.x1;"
                  "x1 + eval('x1') + (1,eval)('x1') + f1() + g1() + h1();",
                  EXPECT_RESULT, Number::New(isolate, 36));
  }

  // Check that caching does respect scopes.
  {
    SimpleContext context;
    const char* script1 = "(function(){ return y1 })()";
    const char* script2 = "(function(){ return y2 })()";

    context.Check(script1, EXPECT_EXCEPTION);
    context.Check("this.y1 = 1; this.y2 = 2; 0;",
                  EXPECT_RESULT, Number::New(isolate, 0));
    context.Check(script1,
                  EXPECT_RESULT, Number::New(isolate, 1));
    context.Check("'use strict'; let y1 = 3; 0;",
                  EXPECT_RESULT, Number::New(isolate, 0));
    context.Check(script1,
                  EXPECT_RESULT, Number::New(isolate, 3));
    context.Check("y1 = 4;",
                  EXPECT_RESULT, Number::New(isolate, 4));
    context.Check(script1,
                  EXPECT_RESULT, Number::New(isolate, 4));

    context.Check(script2,
                  EXPECT_RESULT, Number::New(isolate, 2));
    context.Check("'use strict'; let y2 = 5; 0;",
                  EXPECT_RESULT, Number::New(isolate, 0));
    context.Check(script1,
                  EXPECT_RESULT, Number::New(isolate, 4));
    context.Check(script2,
                  EXPECT_RESULT, Number::New(isolate, 5));
  }
}


TEST(CrossScriptReferencesHarmonyRegress) {
  v8::Isolate* isolate = CcTest::isolate();
  HandleScope scope(isolate);
  SimpleContext context;
  context.Check(
      "'use strict';"
      "function i1() { "
      "  let y = 10; return (typeof x2 === 'undefined' ? 0 : 2) + y"
      "}"
      "i1();"
      "i1();",
      EXPECT_RESULT, Number::New(isolate, 10));
  context.Check(
      "'use strict';"
      "let x2 = 2; i1();",
      EXPECT_RESULT, Number::New(isolate, 12));
}


TEST(GlobalLexicalOSR) {
  i::FLAG_use_strict = true;

  v8::Isolate* isolate = CcTest::isolate();
  HandleScope scope(isolate);
  SimpleContext context;

  context.Check("'use strict';"
                "let x = 1; x;",
                EXPECT_RESULT, Number::New(isolate, 1));
  context.Check("'use strict';"
                "let y = 2*x;"
                "++x;"
                "let z = 0;"
                "const limit = 100000;"
                "for (var i = 0; i < limit; ++i) {"
                "  z += x + y;"
                "}"
                "z;",
                EXPECT_RESULT, Number::New(isolate, 400000));
}


TEST(CrossScriptConflicts) {
  i::FLAG_use_strict = true;

  HandleScope scope(CcTest::isolate());

  const char* firsts[] = {
    "var x = 1; x",
    "function x() { return 1 }; x()",
    "let x = 1; x",
    "const x = 1; x",
    NULL
  };
  const char* seconds[] = {
    "var x = 2; x",
    "function x() { return 2 }; x()",
    "let x = 2; x",
    "const x = 2; x",
    NULL
  };

  for (int i = 0; firsts[i] != NULL; ++i) {
    for (int j = 0; seconds[j] != NULL; ++j) {
      SimpleContext context;
      context.Check(firsts[i], EXPECT_RESULT,
                    Number::New(CcTest::isolate(), 1));
      bool success_case = i < 2 && j < 2;
      Local<Value> success_result;
      if (success_case) success_result = Number::New(CcTest::isolate(), 2);

      context.Check(seconds[j], success_case ? EXPECT_RESULT : EXPECT_EXCEPTION,
                    success_result);
    }
  }
}


TEST(CrossScriptDynamicLookup) {
  HandleScope handle_scope(CcTest::isolate());

  {
    SimpleContext context;
    Local<String> undefined_string =
        String::NewFromUtf8(CcTest::isolate(), "undefined",
                            v8::NewStringType::kInternalized)
            .ToLocalChecked();
    Local<String> number_string =
        String::NewFromUtf8(CcTest::isolate(), "number",
                            v8::NewStringType::kInternalized)
            .ToLocalChecked();

    context.Check(
        "function f(o) { with(o) { return x; } }"
        "function g(o) { with(o) { x = 15; } }"
        "function h(o) { with(o) { return typeof x; } }",
        EXPECT_RESULT, Undefined(CcTest::isolate()));
    context.Check("h({})", EXPECT_RESULT, undefined_string);
    context.Check(
        "'use strict';"
        "let x = 1;"
        "f({})",
        EXPECT_RESULT, Number::New(CcTest::isolate(), 1));
    context.Check(
        "'use strict';"
        "g({});0",
        EXPECT_RESULT, Number::New(CcTest::isolate(), 0));
    context.Check("f({})", EXPECT_RESULT, Number::New(CcTest::isolate(), 15));
    context.Check("h({})", EXPECT_RESULT, number_string);
  }
}


TEST(CrossScriptGlobal) {
  HandleScope handle_scope(CcTest::isolate());
  {
    SimpleContext context;

    context.Check(
        "var global = this;"
        "global.x = 255;"
        "x",
        EXPECT_RESULT, Number::New(CcTest::isolate(), 255));
    context.Check(
        "'use strict';"
        "let x = 1;"
        "global.x",
        EXPECT_RESULT, Number::New(CcTest::isolate(), 255));
    context.Check("global.x = 15; x", EXPECT_RESULT,
                  Number::New(CcTest::isolate(), 1));
    context.Check("x = 221; global.x", EXPECT_RESULT,
                  Number::New(CcTest::isolate(), 15));
    context.Check(
        "z = 15;"
        "function f() { return z; };"
        "for (var k = 0; k < 3; k++) { f(); }"
        "f()",
        EXPECT_RESULT, Number::New(CcTest::isolate(), 15));
    context.Check(
        "'use strict';"
        "let z = 5; f()",
        EXPECT_RESULT, Number::New(CcTest::isolate(), 5));
    context.Check(
        "function f() { konst = 10; return konst; };"
        "f()",
        EXPECT_RESULT, Number::New(CcTest::isolate(), 10));
    context.Check(
        "'use strict';"
        "const konst = 255;"
        "f()",
        EXPECT_EXCEPTION);
  }
}


TEST(CrossScriptStaticLookupUndeclared) {
  HandleScope handle_scope(CcTest::isolate());

  {
    SimpleContext context;
    Local<String> undefined_string =
        String::NewFromUtf8(CcTest::isolate(), "undefined",
                            v8::NewStringType::kInternalized)
            .ToLocalChecked();
    Local<String> number_string =
        String::NewFromUtf8(CcTest::isolate(), "number",
                            v8::NewStringType::kInternalized)
            .ToLocalChecked();

    context.Check(
        "function f(o) { return x; }"
        "function g(v) { x = v; }"
        "function h(o) { return typeof x; }",
        EXPECT_RESULT, Undefined(CcTest::isolate()));
    context.Check("h({})", EXPECT_RESULT, undefined_string);
    context.Check(
        "'use strict';"
        "let x = 1;"
        "f({})",
        EXPECT_RESULT, Number::New(CcTest::isolate(), 1));
    context.Check(
        "'use strict';"
        "g(15);x",
        EXPECT_RESULT, Number::New(CcTest::isolate(), 15));
    context.Check("h({})", EXPECT_RESULT, number_string);
    context.Check("f({})", EXPECT_RESULT, Number::New(CcTest::isolate(), 15));
    context.Check("h({})", EXPECT_RESULT, number_string);
  }
}


TEST(CrossScriptLoadICs) {
  i::FLAG_allow_natives_syntax = true;

  HandleScope handle_scope(CcTest::isolate());

  {
    SimpleContext context;
    context.Check(
        "x = 15;"
        "function f() { return x; }"
        "function g() { return x; }"
        "f()",
        EXPECT_RESULT, Number::New(CcTest::isolate(), 15));
    context.Check(
        "'use strict';"
        "let x = 5;"
        "f()",
        EXPECT_RESULT, Number::New(CcTest::isolate(), 5));
    for (int k = 0; k < 3; k++) {
      context.Check("g()", EXPECT_RESULT, Number::New(CcTest::isolate(), 5));
    }
    for (int k = 0; k < 3; k++) {
      context.Check("f()", EXPECT_RESULT, Number::New(CcTest::isolate(), 5));
    }
    context.Check("%OptimizeFunctionOnNextCall(g); g()", EXPECT_RESULT,
                  Number::New(CcTest::isolate(), 5));
    context.Check("%OptimizeFunctionOnNextCall(f); f()", EXPECT_RESULT,
                  Number::New(CcTest::isolate(), 5));
  }
  {
    SimpleContext context;
    context.Check(
        "x = 15;"
        "function f() { return x; }"
        "f()",
        EXPECT_RESULT, Number::New(CcTest::isolate(), 15));
    for (int k = 0; k < 3; k++) {
      context.Check("f()", EXPECT_RESULT, Number::New(CcTest::isolate(), 15));
    }
    context.Check("%OptimizeFunctionOnNextCall(f); f()", EXPECT_RESULT,
                  Number::New(CcTest::isolate(), 15));
    context.Check(
        "'use strict';"
        "let x = 5;"
        "f()",
        EXPECT_RESULT, Number::New(CcTest::isolate(), 5));
    for (int k = 0; k < 3; k++) {
      context.Check("f()", EXPECT_RESULT, Number::New(CcTest::isolate(), 5));
    }
    context.Check("%OptimizeFunctionOnNextCall(f); f()", EXPECT_RESULT,
                  Number::New(CcTest::isolate(), 5));
  }
}


TEST(CrossScriptStoreICs) {
  i::FLAG_allow_natives_syntax = true;

  HandleScope handle_scope(CcTest::isolate());

  {
    SimpleContext context;
    context.Check(
        "var global = this;"
        "x = 15;"
        "function f(v) { x = v; }"
        "function g(v) { x = v; }"
        "f(10); x",
        EXPECT_RESULT, Number::New(CcTest::isolate(), 10));
    context.Check(
        "'use strict';"
        "let x = 5;"
        "f(7); x",
        EXPECT_RESULT, Number::New(CcTest::isolate(), 7));
    context.Check("global.x", EXPECT_RESULT,
                  Number::New(CcTest::isolate(), 10));
    for (int k = 0; k < 3; k++) {
      context.Check("g(31); x", EXPECT_RESULT,
                    Number::New(CcTest::isolate(), 31));
    }
    context.Check("global.x", EXPECT_RESULT,
                  Number::New(CcTest::isolate(), 10));
    for (int k = 0; k < 3; k++) {
      context.Check("f(32); x", EXPECT_RESULT,
                    Number::New(CcTest::isolate(), 32));
    }
    context.Check("global.x", EXPECT_RESULT,
                  Number::New(CcTest::isolate(), 10));
    context.Check("%OptimizeFunctionOnNextCall(g); g(18); x", EXPECT_RESULT,
                  Number::New(CcTest::isolate(), 18));
    context.Check("global.x", EXPECT_RESULT,
                  Number::New(CcTest::isolate(), 10));
    context.Check("%OptimizeFunctionOnNextCall(f); f(33); x", EXPECT_RESULT,
                  Number::New(CcTest::isolate(), 33));
    context.Check("global.x", EXPECT_RESULT,
                  Number::New(CcTest::isolate(), 10));
  }
  {
    SimpleContext context;
    context.Check(
        "var global = this;"
        "x = 15;"
        "function f(v) { x = v; }"
        "f(10); x",
        EXPECT_RESULT, Number::New(CcTest::isolate(), 10));
    for (int k = 0; k < 3; k++) {
      context.Check("f(18); x", EXPECT_RESULT,
                    Number::New(CcTest::isolate(), 18));
    }
    context.Check("%OptimizeFunctionOnNextCall(f); f(20); x", EXPECT_RESULT,
                  Number::New(CcTest::isolate(), 20));
    context.Check(
        "'use strict';"
        "let x = 5;"
        "f(8); x",
        EXPECT_RESULT, Number::New(CcTest::isolate(), 8));
    context.Check("global.x", EXPECT_RESULT,
                  Number::New(CcTest::isolate(), 20));
    for (int k = 0; k < 3; k++) {
      context.Check("f(13); x", EXPECT_RESULT,
                    Number::New(CcTest::isolate(), 13));
    }
    context.Check("global.x", EXPECT_RESULT,
                  Number::New(CcTest::isolate(), 20));
    context.Check("%OptimizeFunctionOnNextCall(f); f(41); x", EXPECT_RESULT,
                  Number::New(CcTest::isolate(), 41));
    context.Check("global.x", EXPECT_RESULT,
                  Number::New(CcTest::isolate(), 20));
  }
}


TEST(CrossScriptAssignmentToConst) {
  i::FLAG_allow_natives_syntax = true;

  HandleScope handle_scope(CcTest::isolate());

  {
    SimpleContext context;

    context.Check("function f() { x = 27; }", EXPECT_RESULT,
                  Undefined(CcTest::isolate()));
    context.Check("'use strict';const x = 1; x", EXPECT_RESULT,
                  Number::New(CcTest::isolate(), 1));
    context.Check("f();", EXPECT_EXCEPTION);
    context.Check("x", EXPECT_RESULT, Number::New(CcTest::isolate(), 1));
    context.Check("f();", EXPECT_EXCEPTION);
    context.Check("x", EXPECT_RESULT, Number::New(CcTest::isolate(), 1));
    context.Check("%OptimizeFunctionOnNextCall(f);f();", EXPECT_EXCEPTION);
    context.Check("x", EXPECT_RESULT, Number::New(CcTest::isolate(), 1));
  }
}


TEST(Regress425510) {
  i::FLAG_allow_natives_syntax = true;

  HandleScope handle_scope(CcTest::isolate());

  {
    SimpleContext context;

    context.Check("'use strict'; o; const o = 10", EXPECT_EXCEPTION);

    for (int i = 0; i < 100; i++) {
      context.Check("o.prototype", EXPECT_EXCEPTION);
    }
  }
}


TEST(Regress3941) {
  i::FLAG_allow_natives_syntax = true;

  HandleScope handle_scope(CcTest::isolate());

  {
    SimpleContext context;
    context.Check("function f() { x = 1; }", EXPECT_RESULT,
                  Undefined(CcTest::isolate()));
    context.Check("'use strict'; f(); let x = 2; x", EXPECT_EXCEPTION);
  }


  {
    // Train ICs.
    SimpleContext context;
    context.Check("function f() { x = 1; }", EXPECT_RESULT,
                  Undefined(CcTest::isolate()));
    for (int i = 0; i < 4; i++) {
      context.Check("f(); x", EXPECT_RESULT, Number::New(CcTest::isolate(), 1));
    }
    context.Check("'use strict'; f(); let x = 2; x", EXPECT_EXCEPTION);
  }


  {
    // Optimize.
    SimpleContext context;
    context.Check("function f() { x = 1; }", EXPECT_RESULT,
                  Undefined(CcTest::isolate()));
    for (int i = 0; i < 4; i++) {
      context.Check("f(); x", EXPECT_RESULT, Number::New(CcTest::isolate(), 1));
    }
    context.Check("%OptimizeFunctionOnNextCall(f); f(); x", EXPECT_RESULT,
                  Number::New(CcTest::isolate(), 1));

    context.Check("'use strict'; f(); let x = 2; x", EXPECT_EXCEPTION);
  }
}


TEST(Regress3941_Reads) {
  i::FLAG_allow_natives_syntax = true;

  HandleScope handle_scope(CcTest::isolate());

  {
    SimpleContext context;
    context.Check("function f() { return x; }", EXPECT_RESULT,
                  Undefined(CcTest::isolate()));
    context.Check("'use strict'; f(); let x = 2; x", EXPECT_EXCEPTION);
  }


  {
    // Train ICs.
    SimpleContext context;
    context.Check("function f() { return x; }", EXPECT_RESULT,
                  Undefined(CcTest::isolate()));
    for (int i = 0; i < 4; i++) {
      context.Check("f()", EXPECT_EXCEPTION);
    }
    context.Check("'use strict'; f(); let x = 2; x", EXPECT_EXCEPTION);
  }


  {
    // Optimize.
    SimpleContext context;
    context.Check("function f() { return x; }", EXPECT_RESULT,
                  Undefined(CcTest::isolate()));
    for (int i = 0; i < 4; i++) {
      context.Check("f()", EXPECT_EXCEPTION);
    }
    context.Check("%OptimizeFunctionOnNextCall(f);", EXPECT_RESULT,
                  Undefined(CcTest::isolate()));

    context.Check("'use strict'; f(); let x = 2; x", EXPECT_EXCEPTION);
  }
}

}  // namespace v8
