// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "test/cctest/cctest.h"

#include "include/v8.h"
#include "src/api/api.h"
#include "src/objects/objects-inl.h"

namespace i = v8::internal;

// The goal is to avoid the callback.
static void UnreachableCallback(
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  UNREACHABLE();
}

TEST(CachedAccessor) {
  // TurboFan support for fast accessors is not implemented; turbofanned
  // code uses the slow accessor which breaks this test's expectations.
  v8::internal::FLAG_always_opt = false;
  LocalContext env;
  v8::Isolate* isolate = env->GetIsolate();
  v8::HandleScope scope(isolate);

  // Create 'foo' class, with a hidden property.
  v8::Local<v8::ObjectTemplate> foo = v8::ObjectTemplate::New(isolate);

  v8::Local<v8::Private> priv =
      v8::Private::ForApi(isolate, v8_str("Foo#draft"));

  foo->SetAccessorProperty(v8_str("draft"), v8::FunctionTemplate::NewWithCache(
                                                isolate, UnreachableCallback,
                                                priv, v8::Local<v8::Value>()));

  // Create 'obj', instance of 'foo'.
  v8::Local<v8::Object> obj = foo->NewInstance(env.local()).ToLocalChecked();

  // Install the private property on the instance.
  CHECK(obj->SetPrivate(isolate->GetCurrentContext(), priv,
                        v8::Undefined(isolate))
            .FromJust());

  CHECK(env->Global()->Set(env.local(), v8_str("obj"), obj).FromJust());

  // Access cached accessor.
  ExpectUndefined("obj.draft");

  // Set hidden property.
  CHECK(obj->SetPrivate(isolate->GetCurrentContext(), priv,
                        v8_str("Shhh, I'm private!"))
            .FromJust());

  ExpectString("obj.draft", "Shhh, I'm private!");

  // Stress the accessor to use the IC.
  ExpectString(
      "var result = '';"
      "for (var i = 0; i < 10; ++i) { "
      "  result = obj.draft; "
      "} "
      "result; ",
      "Shhh, I'm private!");
}

TEST(CachedAccessorTurboFan) {
  i::FLAG_allow_natives_syntax = true;
  // v8::internal::FLAG_always_opt = false;
  LocalContext env;
  v8::Isolate* isolate = env->GetIsolate();
  v8::HandleScope scope(isolate);

  // Create 'foo' class, with a hidden property.
  v8::Local<v8::ObjectTemplate> foo = v8::ObjectTemplate::New(isolate);
  v8::Local<v8::Private> priv =
      v8::Private::ForApi(isolate, v8_str("Foo#draft"));

  // Install the private property on the template.
  // foo->SetPrivate(priv, v8::Undefined(isolate));

  foo->SetAccessorProperty(v8_str("draft"), v8::FunctionTemplate::NewWithCache(
                                                isolate, UnreachableCallback,
                                                priv, v8::Local<v8::Value>()));

  // Create 'obj', instance of 'foo'.
  v8::Local<v8::Object> obj = foo->NewInstance(env.local()).ToLocalChecked();

  // Install the private property on the instance.
  CHECK(obj->SetPrivate(isolate->GetCurrentContext(), priv,
                        v8::Undefined(isolate))
            .FromJust());

  CHECK(env->Global()->Set(env.local(), v8_str("obj"), obj).FromJust());

  // Access surrogate accessor.
  ExpectUndefined("obj.draft");

  // Set hidden property.
  CHECK(obj->SetPrivate(env.local(), priv, v8::Integer::New(isolate, 123))
            .FromJust());

  // Test ICs.
  CompileRun(
      "function f() {"
      "  var x;"
      "  for (var i = 0; i < 100; i++) {"
      "    x = obj.draft;"
      "  }"
      "  return x;"
      "};"
      "%PrepareFunctionForOptimization(f);");

  ExpectInt32("f()", 123);

  // Reset hidden property.
  CHECK(obj->SetPrivate(env.local(), priv, v8::Integer::New(isolate, 456))
            .FromJust());

  // Test TurboFan.
  CompileRun("%OptimizeFunctionOnNextCall(f);");

  ExpectInt32("f()", 456);

  CHECK(obj->SetPrivate(env.local(), priv, v8::Integer::New(isolate, 456))
            .FromJust());
  // Test non-global ICs.
  CompileRun(
      "function g() {"
      "  var x = obj;"
      "  var r = 0;"
      "  for (var i = 0; i < 100; i++) {"
      "    r = x.draft;"
      "  }"
      "  return r;"
      "};"
      "%PrepareFunctionForOptimization(g);");

  ExpectInt32("g()", 456);

  // Reset hidden property.
  CHECK(obj->SetPrivate(env.local(), priv, v8::Integer::New(isolate, 789))
            .FromJust());

  // Test non-global access in TurboFan.
  CompileRun("%OptimizeFunctionOnNextCall(g);");

  ExpectInt32("g()", 789);
}

TEST(CachedAccessorOnGlobalObject) {
  i::FLAG_allow_natives_syntax = true;
  LocalContext env;
  v8::Isolate* isolate = env->GetIsolate();
  v8::HandleScope scope(isolate);

  v8::Local<v8::FunctionTemplate> templ =
      v8::FunctionTemplate::New(CcTest::isolate());
  v8::Local<v8::ObjectTemplate> object_template = templ->InstanceTemplate();
  v8::Local<v8::Private> priv =
      v8::Private::ForApi(isolate, v8_str("Foo#draft"));

  object_template->SetAccessorProperty(
      v8_str("draft"),
      v8::FunctionTemplate::NewWithCache(isolate, UnreachableCallback, priv,
                                         v8::Local<v8::Value>()));

  v8::Local<v8::Context> ctx =
      v8::Context::New(CcTest::isolate(), nullptr, object_template);
  v8::Local<v8::Object> obj = ctx->Global();

  // Install the private property on the instance.
  CHECK(obj->SetPrivate(isolate->GetCurrentContext(), priv,
                        v8::Undefined(isolate))
            .FromJust());

  {
    v8::Context::Scope context_scope(ctx);

    // Access surrogate accessor.
    ExpectUndefined("draft");

    // Set hidden property.
    CHECK(obj->SetPrivate(env.local(), priv, v8::Integer::New(isolate, 123))
              .FromJust());

    // Test ICs.
    CompileRun(
        "function f() {"
        "  var x;"
        "  for (var i = 0; i < 100; i++) {"
        "    x = draft;"
        "  }"
        "  return x;"
        "}"
        "%PrepareFunctionForOptimization(f);");

    ExpectInt32("f()", 123);

    // Reset hidden property.
    CHECK(obj->SetPrivate(env.local(), priv, v8::Integer::New(isolate, 456))
              .FromJust());

    // Test TurboFan.
    CompileRun("%OptimizeFunctionOnNextCall(f);");

    ExpectInt32("f()", 456);

    CHECK(obj->SetPrivate(env.local(), priv, v8::Integer::New(isolate, 456))
              .FromJust());
    // Test non-global ICs.
    CompileRun(
        "var x = this;"
        "function g() {"
        "  var r = 0;"
        "  for (var i = 0; i < 100; i++) {"
        "    r = x.draft;"
        "  }"
        "  return r;"
        "}"
        "%PrepareFunctionForOptimization(g);");

    ExpectInt32("g()", 456);

    // Reset hidden property.
    CHECK(obj->SetPrivate(env.local(), priv, v8::Integer::New(isolate, 789))
              .FromJust());

    // Test non-global access in TurboFan.
    CompileRun("%OptimizeFunctionOnNextCall(g);");

    ExpectInt32("g()", 789);
  }
}

namespace {

// Getter return value should be non-null to trigger lazy property paths.
static void Getter(v8::Local<v8::Name> name,
                   const v8::PropertyCallbackInfo<v8::Value>& info) {
  info.GetReturnValue().Set(v8_str("return value"));
}

static void StringGetter(v8::Local<v8::String> name,
                         const v8::PropertyCallbackInfo<v8::Value>& info) {}

static int set_accessor_call_count = 0;

static void Setter(v8::Local<v8::Name> name, v8::Local<v8::Value> value,
                   const v8::PropertyCallbackInfo<void>& info) {
  set_accessor_call_count++;
}
}  // namespace

// Re-declaration of non-configurable accessors should throw.
TEST(RedeclareAccessor) {
  v8::HandleScope scope(CcTest::isolate());
  LocalContext env;

  v8::Local<v8::FunctionTemplate> templ =
      v8::FunctionTemplate::New(CcTest::isolate());

  v8::Local<v8::ObjectTemplate> object_template = templ->InstanceTemplate();
  object_template->SetAccessor(
      v8_str("foo"), nullptr, Setter, v8::Local<v8::Value>(),
      v8::AccessControl::DEFAULT, v8::PropertyAttribute::DontDelete);

  v8::Local<v8::Context> ctx =
      v8::Context::New(CcTest::isolate(), nullptr, object_template);

  // Declare function.
  v8::Local<v8::String> code = v8_str("function foo() {};");

  v8::TryCatch try_catch(CcTest::isolate());
  v8::Script::Compile(ctx, code).ToLocalChecked()->Run(ctx).IsEmpty();
  CHECK(try_catch.HasCaught());
}

// Accessors can be whitelisted as side-effect-free via SetAccessor.
TEST(AccessorSetHasNoSideEffect) {
  LocalContext env;
  v8::Isolate* isolate = env->GetIsolate();
  v8::HandleScope scope(isolate);
  v8::Local<v8::Context> context = isolate->GetCurrentContext();

  v8::Local<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate);
  v8::Local<v8::Object> obj = templ->NewInstance(env.local()).ToLocalChecked();
  CHECK(env->Global()->Set(env.local(), v8_str("obj"), obj).FromJust());
  obj->SetAccessor(context, v8_str("foo"), Getter).ToChecked();
  CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo"), true).IsEmpty());

  obj->SetAccessor(context, v8_str("foo"), Getter, nullptr,
                   v8::MaybeLocal<v8::Value>(), v8::AccessControl::DEFAULT,
                   v8::PropertyAttribute::None,
                   v8::SideEffectType::kHasNoSideEffect)
      .ToChecked();
  v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo"), true).ToLocalChecked();

  // Check that setter is not whitelisted.
  v8::TryCatch try_catch(isolate);
  CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo = 1"), true)
            .IsEmpty());
  CHECK(try_catch.HasCaught());
  CHECK_NE(1, v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo"), false)
                  .ToLocalChecked()
                  ->Int32Value(env.local())
                  .FromJust());
  CHECK_EQ(0, set_accessor_call_count);
}

// Set accessors can be whitelisted as side-effect-free via SetAccessor.
TEST(SetAccessorSetSideEffectReceiverCheck1) {
  LocalContext env;
  v8::Isolate* isolate = env->GetIsolate();
  v8::HandleScope scope(isolate);

  v8::Local<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate);
  v8::Local<v8::Object> obj = templ->NewInstance(env.local()).ToLocalChecked();
  CHECK(env->Global()->Set(env.local(), v8_str("obj"), obj).FromJust());
  obj->SetAccessor(env.local(), v8_str("foo"), Getter, Setter,
                   v8::MaybeLocal<v8::Value>(), v8::AccessControl::DEFAULT,
                   v8::PropertyAttribute::None,
                   v8::SideEffectType::kHasNoSideEffect,
                   v8::SideEffectType::kHasSideEffectToReceiver)
      .ToChecked();
  CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo"), true)
            .ToLocalChecked()
            ->Equals(env.local(), v8_str("return value"))
            .FromJust());
  v8::TryCatch try_catch(isolate);
  CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo = 1"), true)
            .IsEmpty());
  CHECK(try_catch.HasCaught());
  CHECK_EQ(0, set_accessor_call_count);
}

static void ConstructCallback(const v8::FunctionCallbackInfo<v8::Value>& info) {
}

TEST(SetAccessorSetSideEffectReceiverCheck2) {
  LocalContext env;
  v8::Isolate* isolate = env->GetIsolate();
  v8::HandleScope scope(isolate);
  i::FLAG_enable_one_shot_optimization = false;

  v8::Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(
      isolate, ConstructCallback, v8::Local<v8::Value>(),
      v8::Local<v8::Signature>(), 0, v8::ConstructorBehavior::kAllow,
      v8::SideEffectType::kHasNoSideEffect);
  templ->InstanceTemplate()->SetAccessor(
      v8_str("bar"), Getter, Setter, v8::Local<v8::Value>(),
      v8::AccessControl::DEFAULT, v8::PropertyAttribute::None,
      v8::Local<v8::AccessorSignature>(),
      v8::SideEffectType::kHasSideEffectToReceiver,
      v8::SideEffectType::kHasSideEffectToReceiver);
  CHECK(env->Global()
            ->Set(env.local(), v8_str("f"),
                  templ->GetFunction(env.local()).ToLocalChecked())
            .FromJust());
  CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("new f().bar"), true)
            .ToLocalChecked()
            ->Equals(env.local(), v8_str("return value"))
            .FromJust());
  v8::debug::EvaluateGlobal(isolate, v8_str("new f().bar = 1"), true)
      .ToLocalChecked();
  CHECK_EQ(1, set_accessor_call_count);
}

// Accessors can be whitelisted as side-effect-free via SetNativeDataProperty.
TEST(AccessorSetNativeDataPropertyHasNoSideEffect) {
  LocalContext env;
  v8::Isolate* isolate = env->GetIsolate();
  v8::HandleScope scope(isolate);
  v8::Local<v8::Context> context = isolate->GetCurrentContext();

  v8::Local<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate);
  v8::Local<v8::Object> obj = templ->NewInstance(env.local()).ToLocalChecked();
  CHECK(env->Global()->Set(env.local(), v8_str("obj"), obj).FromJust());
  obj->SetNativeDataProperty(context, v8_str("foo"), Getter).ToChecked();
  CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo"), true).IsEmpty());

  obj->SetNativeDataProperty(
         context, v8_str("foo"), Getter, nullptr, v8::Local<v8::Value>(),
         v8::PropertyAttribute::None, v8::SideEffectType::kHasNoSideEffect)
      .ToChecked();
  v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo"), true).ToLocalChecked();

  // Check that setter is not whitelisted.
  v8::TryCatch try_catch(isolate);
  CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo = 1"), true)
            .IsEmpty());
  CHECK(try_catch.HasCaught());
  CHECK_NE(1, v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo"), false)
                  .ToLocalChecked()
                  ->Int32Value(env.local())
                  .FromJust());
}

// Accessors can be whitelisted as side-effect-free via SetLazyDataProperty.
TEST(AccessorSetLazyDataPropertyHasNoSideEffect) {
  LocalContext env;
  v8::Isolate* isolate = env->GetIsolate();
  v8::HandleScope scope(isolate);
  v8::Local<v8::Context> context = isolate->GetCurrentContext();

  v8::Local<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate);
  v8::Local<v8::Object> obj = templ->NewInstance(env.local()).ToLocalChecked();
  CHECK(env->Global()->Set(env.local(), v8_str("obj"), obj).FromJust());
  obj->SetLazyDataProperty(context, v8_str("foo"), Getter).ToChecked();
  CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo"), true).IsEmpty());

  obj->SetLazyDataProperty(context, v8_str("foo"), Getter,
                           v8::Local<v8::Value>(), v8::PropertyAttribute::None,
                           v8::SideEffectType::kHasNoSideEffect)
      .ToChecked();
  v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo"), true).ToLocalChecked();

  // Check that setter is not whitelisted.
  v8::TryCatch try_catch(isolate);
  CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo = 1"), true)
            .IsEmpty());
  CHECK(try_catch.HasCaught());
  CHECK_NE(1, v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo"), false)
                  .ToLocalChecked()
                  ->Int32Value(env.local())
                  .FromJust());
}

TEST(ObjectTemplateSetAccessorHasNoSideEffect) {
  LocalContext env;
  v8::Isolate* isolate = env->GetIsolate();
  v8::HandleScope scope(isolate);

  v8::Local<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate);
  templ->SetAccessor(v8_str("foo"), StringGetter);
  templ->SetAccessor(
      v8_str("foo2"), StringGetter, nullptr, v8::Local<v8::Value>(),
      v8::AccessControl::DEFAULT, v8::PropertyAttribute::None,
      v8::Local<v8::AccessorSignature>(), v8::SideEffectType::kHasNoSideEffect);
  v8::Local<v8::Object> obj = templ->NewInstance(env.local()).ToLocalChecked();
  CHECK(env->Global()->Set(env.local(), v8_str("obj"), obj).FromJust());

  CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo"), true).IsEmpty());
  v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo2"), true).ToLocalChecked();

  // Check that setter is not whitelisted.
  v8::TryCatch try_catch(isolate);
  CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo2 = 1"), true)
            .IsEmpty());
  CHECK(try_catch.HasCaught());
  CHECK_NE(1, v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo2"), false)
                  .ToLocalChecked()
                  ->Int32Value(env.local())
                  .FromJust());
}

TEST(ObjectTemplateSetNativePropertyHasNoSideEffect) {
  LocalContext env;
  v8::Isolate* isolate = env->GetIsolate();
  v8::HandleScope scope(isolate);

  v8::Local<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate);
  templ->SetNativeDataProperty(v8_str("foo"), Getter);
  templ->SetNativeDataProperty(
      v8_str("foo2"), Getter, nullptr, v8::Local<v8::Value>(),
      v8::PropertyAttribute::None, v8::Local<v8::AccessorSignature>(),
      v8::AccessControl::DEFAULT, v8::SideEffectType::kHasNoSideEffect);
  v8::Local<v8::Object> obj = templ->NewInstance(env.local()).ToLocalChecked();
  CHECK(env->Global()->Set(env.local(), v8_str("obj"), obj).FromJust());

  CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo"), true).IsEmpty());
  v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo2"), true).ToLocalChecked();

  // Check that setter is not whitelisted.
  v8::TryCatch try_catch(isolate);
  CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo2 = 1"), true)
            .IsEmpty());
  CHECK(try_catch.HasCaught());
  CHECK_NE(1, v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo2"), false)
                  .ToLocalChecked()
                  ->Int32Value(env.local())
                  .FromJust());
}

TEST(ObjectTemplateSetLazyPropertyHasNoSideEffect) {
  LocalContext env;
  v8::Isolate* isolate = env->GetIsolate();
  v8::HandleScope scope(isolate);

  v8::Local<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate);
  templ->SetLazyDataProperty(v8_str("foo"), Getter);
  templ->SetLazyDataProperty(v8_str("foo2"), Getter, v8::Local<v8::Value>(),
                             v8::PropertyAttribute::None,
                             v8::SideEffectType::kHasNoSideEffect);
  v8::Local<v8::Object> obj = templ->NewInstance(env.local()).ToLocalChecked();
  CHECK(env->Global()->Set(env.local(), v8_str("obj"), obj).FromJust());

  CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo"), true).IsEmpty());
  v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo2"), true).ToLocalChecked();

  // Check that setter is not whitelisted.
  v8::TryCatch try_catch(isolate);
  CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo2 = 1"), true)
            .IsEmpty());
  CHECK(try_catch.HasCaught());
  CHECK_NE(1, v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo2"), false)
                  .ToLocalChecked()
                  ->Int32Value(env.local())
                  .FromJust());
}
