// Copyright 2017 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 "include/v8.h"
#include "src/api.h"
#include "src/objects-inl.h"
#include "test/unittests/test-utils.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace v8 {
namespace {

using ObjectTest = TestWithContext;

void accessor_name_getter_callback(Local<Name>,
                                   const PropertyCallbackInfo<Value>&) {}

TEST_F(ObjectTest, SetAccessorWhenUnconfigurablePropAlreadyDefined) {
  TryCatch try_catch(isolate());

  Local<Object> global = context()->Global();
  Local<String> property_name =
      String::NewFromUtf8(isolate(), "foo", NewStringType::kNormal)
          .ToLocalChecked();

  PropertyDescriptor prop_desc;
  prop_desc.set_configurable(false);
  global->DefineProperty(context(), property_name, prop_desc).ToChecked();

  Maybe<bool> result = global->SetAccessor(context(), property_name,
                                           accessor_name_getter_callback);
  ASSERT_TRUE(result.IsJust());
  ASSERT_FALSE(result.FromJust());
  ASSERT_FALSE(try_catch.HasCaught());
}

using LapContextTest = TestWithIsolate;

// TODO(yukishiino): Enable this unittest once
// PropertyAccessInfo::accessor_holder() gets supported.  Currently we're using
// PropertyAccessInfo::holder(), which doesn't return the accessor holder.
TEST_F(LapContextTest, DISABLED_CurrentContextInLazyAccessorOnPrototype) {
  // The receiver object is created in |receiver_context|, but its prototype
  // object is created in |prototype_context|, and the property is accessed
  // from |caller_context|.
  Local<Context> receiver_context = Context::New(isolate());
  Local<Context> prototype_context = Context::New(isolate());
  Local<Context> caller_context = Context::New(isolate());

  static int call_count;  // The number of calls of the accessor callback.
  call_count = 0;

  Local<FunctionTemplate> function_template = FunctionTemplate::New(isolate());
  Local<Signature> signature = Signature::New(isolate(), function_template);
  Local<String> property_key =
      String::NewFromUtf8(isolate(), "property", NewStringType::kNormal)
          .ToLocalChecked();
  Local<FunctionTemplate> get_or_set = FunctionTemplate::New(
      isolate(),
      [](const FunctionCallbackInfo<Value>& info) {
        ++call_count;
        Local<Context> prototype_context = *reinterpret_cast<Local<Context>*>(
            info.Data().As<External>()->Value());
        EXPECT_EQ(prototype_context, info.GetIsolate()->GetCurrentContext());
      },
      External::New(isolate(), &prototype_context), signature);
  function_template->PrototypeTemplate()->SetAccessorProperty(
      property_key, get_or_set, get_or_set);

  // |object| is created in |receiver_context|, and |prototype| is created
  // in |prototype_context|.  And then, object.__proto__ = prototype.
  Local<Function> interface_for_receiver =
      function_template->GetFunction(receiver_context).ToLocalChecked();
  Local<Function> interface_for_prototype =
      function_template->GetFunction(prototype_context).ToLocalChecked();
  Local<String> prototype_key =
      String::NewFromUtf8(isolate(), "prototype", NewStringType::kNormal)
          .ToLocalChecked();
  Local<Object> prototype =
      interface_for_prototype->Get(caller_context, prototype_key)
          .ToLocalChecked()
          .As<Object>();
  Local<Object> object =
      interface_for_receiver->NewInstance(receiver_context).ToLocalChecked();
  object->SetPrototype(caller_context, prototype).ToChecked();
  EXPECT_EQ(receiver_context, object->CreationContext());
  EXPECT_EQ(prototype_context, prototype->CreationContext());

  EXPECT_EQ(0, call_count);
  object->Get(caller_context, property_key).ToLocalChecked();
  EXPECT_EQ(1, call_count);
  object->Set(caller_context, property_key, Null(isolate())).ToChecked();
  EXPECT_EQ(2, call_count);

  // Test with a compiled version.
  Local<String> object_key =
      String::NewFromUtf8(isolate(), "object", NewStringType::kNormal)
          .ToLocalChecked();
  caller_context->Global()->Set(caller_context, object_key, object).ToChecked();
  const char script[] =
      "function f() { object.property; object.property = 0; } "
      "f(); f(); "
      "%OptimizeFunctionOnNextCall(f); "
      "f();";
  Context::Scope scope(caller_context);
  internal::FLAG_allow_natives_syntax = true;
  Script::Compile(
      caller_context,
      String::NewFromUtf8(isolate(), script, v8::NewStringType::kNormal)
          .ToLocalChecked())
      .ToLocalChecked()
      ->Run(caller_context)
      .ToLocalChecked();
  EXPECT_EQ(8, call_count);
}

TEST_F(LapContextTest, CurrentContextInLazyAccessorOnPlatformObject) {
  Local<Context> receiver_context = Context::New(isolate());
  Local<Context> caller_context = Context::New(isolate());

  static int call_count;  // The number of calls of the accessor callback.
  call_count = 0;

  Local<FunctionTemplate> function_template = FunctionTemplate::New(isolate());
  Local<Signature> signature = Signature::New(isolate(), function_template);
  Local<String> property_key =
      String::NewFromUtf8(isolate(), "property", NewStringType::kNormal)
          .ToLocalChecked();
  Local<FunctionTemplate> get_or_set = FunctionTemplate::New(
      isolate(),
      [](const FunctionCallbackInfo<Value>& info) {
        ++call_count;
        Local<Context> receiver_context = *reinterpret_cast<Local<Context>*>(
            info.Data().As<External>()->Value());
        EXPECT_EQ(receiver_context, info.GetIsolate()->GetCurrentContext());
      },
      External::New(isolate(), &receiver_context), signature);
  function_template->InstanceTemplate()->SetAccessorProperty(
      property_key, get_or_set, get_or_set);

  Local<Function> interface =
      function_template->GetFunction(receiver_context).ToLocalChecked();
  Local<Object> object =
      interface->NewInstance(receiver_context).ToLocalChecked();

  EXPECT_EQ(0, call_count);
  object->Get(caller_context, property_key).ToLocalChecked();
  EXPECT_EQ(1, call_count);
  object->Set(caller_context, property_key, Null(isolate())).ToChecked();
  EXPECT_EQ(2, call_count);

  // Test with a compiled version.
  Local<String> object_key =
      String::NewFromUtf8(isolate(), "object", NewStringType::kNormal)
          .ToLocalChecked();
  caller_context->Global()->Set(caller_context, object_key, object).ToChecked();
  const char script[] =
      "function f() { object.property; object.property = 0; } "
      "f(); f(); "
      "%OptimizeFunctionOnNextCall(f); "
      "f();";
  Context::Scope scope(caller_context);
  internal::FLAG_allow_natives_syntax = true;
  Script::Compile(
      caller_context,
      String::NewFromUtf8(isolate(), script, v8::NewStringType::kNormal)
          .ToLocalChecked())
      .ToLocalChecked()
      ->Run(caller_context)
      .ToLocalChecked();
  EXPECT_EQ(8, call_count);
}

TEST_F(LapContextTest, CurrentContextInLazyAccessorOnInterface) {
  Local<Context> interface_context = Context::New(isolate());
  Local<Context> caller_context = Context::New(isolate());

  static int call_count;  // The number of calls of the accessor callback.
  call_count = 0;

  Local<FunctionTemplate> function_template = FunctionTemplate::New(isolate());
  Local<String> property_key =
      String::NewFromUtf8(isolate(), "property", NewStringType::kNormal)
          .ToLocalChecked();
  Local<FunctionTemplate> get_or_set = FunctionTemplate::New(
      isolate(),
      [](const FunctionCallbackInfo<Value>& info) {
        ++call_count;
        Local<Context> interface_context = *reinterpret_cast<Local<Context>*>(
            info.Data().As<External>()->Value());
        EXPECT_EQ(interface_context, info.GetIsolate()->GetCurrentContext());
      },
      External::New(isolate(), &interface_context), Local<Signature>());
  function_template->SetAccessorProperty(property_key, get_or_set, get_or_set);

  Local<Function> interface =
      function_template->GetFunction(interface_context).ToLocalChecked();

  EXPECT_EQ(0, call_count);
  interface->Get(caller_context, property_key).ToLocalChecked();
  EXPECT_EQ(1, call_count);
  interface->Set(caller_context, property_key, Null(isolate())).ToChecked();
  EXPECT_EQ(2, call_count);

  // Test with a compiled version.
  Local<String> interface_key =
      String::NewFromUtf8(isolate(), "Interface", NewStringType::kNormal)
          .ToLocalChecked();
  caller_context->Global()
      ->Set(caller_context, interface_key, interface)
      .ToChecked();
  const char script[] =
      "function f() { Interface.property; Interface.property = 0; } "
      "f(); f(); "
      "%OptimizeFunctionOnNextCall(f); "
      "f();";
  Context::Scope scope(caller_context);
  internal::FLAG_allow_natives_syntax = true;
  Script::Compile(
      caller_context,
      String::NewFromUtf8(isolate(), script, v8::NewStringType::kNormal)
          .ToLocalChecked())
      .ToLocalChecked()
      ->Run(caller_context)
      .ToLocalChecked();
  EXPECT_EQ(8, call_count);
}

}  // namespace
}  // namespace v8
