// Copyright 2013 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 "test/cctest/cctest.h"

using namespace v8::internal;


class HandleArray : public Malloced {
 public:
  static const unsigned kArraySize = 200;
  HandleArray() {}
  ~HandleArray() { Reset(); }
  void Reset() {
    for (unsigned i = 0; i < kArraySize; i++) {
      if (handles_[i].IsEmpty()) continue;
      handles_[i].Reset();
    }
  }
  v8::Persistent<v8::Value> handles_[kArraySize];
 private:
  DISALLOW_COPY_AND_ASSIGN(HandleArray);
};


// An aligned character array of size 1024.
class AlignedArray : public Malloced {
 public:
  static const unsigned kArraySize = 1024/sizeof(uint64_t);
  AlignedArray() { Reset(); }

  void Reset() {
    for (unsigned i = 0; i < kArraySize; i++) {
      data_[i] = 0;
    }
  }

  template<typename T>
  T As() { return reinterpret_cast<T>(data_); }

 private:
  uint64_t data_[kArraySize];
  DISALLOW_COPY_AND_ASSIGN(AlignedArray);
};


class DescriptorTestHelper {
 public:
  DescriptorTestHelper() :
      isolate_(NULL), array_(new AlignedArray), handle_array_(new HandleArray) {
    v8::V8::Initialize();
    isolate_ = CcTest::isolate();
  }
  v8::Isolate* isolate_;
  // Data objects.
  SmartPointer<AlignedArray> array_;
  SmartPointer<HandleArray> handle_array_;
 private:
  DISALLOW_COPY_AND_ASSIGN(DescriptorTestHelper);
};


static v8::Local<v8::ObjectTemplate> CreateConstructor(
    v8::Handle<v8::Context> context,
    const char* class_name,
    int internal_field,
    const char* descriptor_name = NULL,
    v8::Handle<v8::DeclaredAccessorDescriptor> descriptor =
        v8::Handle<v8::DeclaredAccessorDescriptor>()) {
  v8::Local<v8::FunctionTemplate> constructor =
      v8::FunctionTemplate::New(context->GetIsolate());
  v8::Local<v8::ObjectTemplate> obj_template = constructor->InstanceTemplate();
  // Setup object template.
  if (descriptor_name != NULL && !descriptor.IsEmpty()) {
    bool added_accessor =
        obj_template->SetDeclaredAccessor(v8_str(descriptor_name), descriptor);
    CHECK(added_accessor);
  }
  obj_template->SetInternalFieldCount((internal_field+1)*2 + 7);
  context->Global()->Set(v8_str(class_name), constructor->GetFunction());
  return obj_template;
}


static void VerifyRead(v8::Handle<v8::DeclaredAccessorDescriptor> descriptor,
                       int internal_field,
                       void* internal_object,
                       v8::Handle<v8::Value> expected_value) {
  LocalContext local_context;
  v8::HandleScope scope(local_context->GetIsolate());
  v8::Handle<v8::Context> context = local_context.local();
  CreateConstructor(context, "Accessible", internal_field, "x", descriptor);
  // Setup object.
  CompileRun("var accessible = new Accessible();");
  v8::Local<v8::Object> obj = v8::Local<v8::Object>::Cast(
      context->Global()->Get(v8_str("accessible")));
  obj->SetAlignedPointerInInternalField(internal_field, internal_object);
  bool added_accessor;
  added_accessor = obj->SetDeclaredAccessor(v8_str("y"), descriptor);
  CHECK(added_accessor);
  added_accessor = obj->SetDeclaredAccessor(v8_str("13"), descriptor);
  CHECK(added_accessor);
  // Test access from template getter.
  v8::Local<v8::Value> value;
  value = CompileRun("accessible.x;");
  CHECK_EQ(expected_value, value);
  value = CompileRun("accessible['x'];");
  CHECK_EQ(expected_value, value);
  // Test access from object getter.
  value = CompileRun("accessible.y;");
  CHECK_EQ(expected_value, value);
  value = CompileRun("accessible['y'];");
  CHECK_EQ(expected_value, value);
  value = CompileRun("accessible[13];");
  CHECK_EQ(expected_value, value);
  value = CompileRun("accessible['13'];");
  CHECK_EQ(expected_value, value);
}


static v8::Handle<v8::Value> Convert(int32_t value, v8::Isolate* isolate) {
  return v8::Integer::New(isolate, value);
}


static v8::Handle<v8::Value> Convert(float value, v8::Isolate* isolate) {
  return v8::Number::New(isolate, value);
}


static v8::Handle<v8::Value> Convert(double value, v8::Isolate* isolate) {
  return v8::Number::New(isolate, value);
}


typedef v8::ObjectOperationDescriptor OOD;

template<typename T>
static void TestPrimitiveValue(
    T value,
    v8::DeclaredAccessorDescriptorDataType data_type,
    DescriptorTestHelper* helper) {
  v8::HandleScope handle_scope(helper->isolate_);
  int index = 17;
  int internal_field = 6;
  v8::Handle<v8::DeclaredAccessorDescriptor> descriptor =
      OOD::NewInternalFieldDereference(helper->isolate_, internal_field)
      ->NewRawShift(helper->isolate_, static_cast<uint16_t>(index*sizeof(T)))
      ->NewPrimitiveValue(helper->isolate_, data_type, 0);
  v8::Handle<v8::Value> expected = Convert(value, helper->isolate_);
  helper->array_->Reset();
  helper->array_->As<T*>()[index] = value;
  VerifyRead(descriptor, internal_field, helper->array_.get(), expected);
}


TEST(PrimitiveValueRead) {
  DescriptorTestHelper helper;
  TestPrimitiveValue<int32_t>(203, v8::kDescriptorInt32Type, &helper);
  TestPrimitiveValue<float>(23.7f, v8::kDescriptorFloatType, &helper);
  TestPrimitiveValue<double>(23.7, v8::kDescriptorDoubleType, &helper);
}


template<typename T>
static void TestBitmaskCompare(T bitmask,
                               T compare_value,
                               DescriptorTestHelper* helper) {
  v8::HandleScope handle_scope(helper->isolate_);
  int index = 13;
  int internal_field = 4;
  v8::Handle<v8::RawOperationDescriptor> raw_descriptor =
      OOD::NewInternalFieldDereference(helper->isolate_, internal_field)
      ->NewRawShift(helper->isolate_, static_cast<uint16_t>(index*sizeof(T)));
  v8::Handle<v8::DeclaredAccessorDescriptor> descriptor;
  switch (sizeof(T)) {
    case 1:
      descriptor = raw_descriptor->NewBitmaskCompare8(
            helper->isolate_,
            static_cast<uint8_t>(bitmask),
            static_cast<uint8_t>(compare_value));
      break;
    case 2:
      descriptor = raw_descriptor->NewBitmaskCompare16(
          helper->isolate_,
          static_cast<uint16_t>(bitmask),
          static_cast<uint16_t>(compare_value));
      break;
    case 4:
      descriptor = raw_descriptor->NewBitmaskCompare32(
          helper->isolate_,
          static_cast<uint32_t>(bitmask),
          static_cast<uint32_t>(compare_value));
      break;
    default:
      CHECK(false);
      break;
  }
  AlignedArray* array = helper->array_.get();
  array->Reset();
  VerifyRead(descriptor, internal_field, array, v8::False(helper->isolate_));
  array->As<T*>()[index] = compare_value;
  VerifyRead(descriptor, internal_field, array, v8::True(helper->isolate_));
  helper->array_->As<T*>()[index] = compare_value & bitmask;
  VerifyRead(descriptor, internal_field, array, v8::True(helper->isolate_));
}


TEST(BitmaskCompareRead) {
  DescriptorTestHelper helper;
  TestBitmaskCompare<uint8_t>(0xf3, 0xa8, &helper);
  TestBitmaskCompare<uint16_t>(0xfefe, 0x7d42, &helper);
  TestBitmaskCompare<uint32_t>(0xfefeab18, 0x1234fdec, &helper);
}


TEST(PointerCompareRead) {
  DescriptorTestHelper helper;
  v8::HandleScope handle_scope(helper.isolate_);
  int index = 35;
  int internal_field = 3;
  void* ptr = helper.isolate_;
  v8::Handle<v8::DeclaredAccessorDescriptor> descriptor =
      OOD::NewInternalFieldDereference(helper.isolate_, internal_field)
      ->NewRawShift(helper.isolate_, static_cast<uint16_t>(index*sizeof(ptr)))
      ->NewPointerCompare(helper.isolate_, ptr);
  AlignedArray* array = helper.array_.get();
  VerifyRead(descriptor, internal_field, array, v8::False(helper.isolate_));
  array->As<uintptr_t*>()[index] = reinterpret_cast<uintptr_t>(ptr);
  VerifyRead(descriptor, internal_field, array, v8::True(helper.isolate_));
}


TEST(PointerDereferenceRead) {
  DescriptorTestHelper helper;
  v8::HandleScope handle_scope(helper.isolate_);
  int first_index = 13;
  int internal_field = 7;
  int second_index = 11;
  int pointed_to_index = 75;
  uint16_t expected = 0x1425;
  v8::Handle<v8::DeclaredAccessorDescriptor> descriptor =
      OOD::NewInternalFieldDereference(helper.isolate_, internal_field)
      ->NewRawShift(helper.isolate_, first_index*kPointerSize)
      ->NewRawDereference(helper.isolate_)
      ->NewRawShift(helper.isolate_,
                    static_cast<uint16_t>(second_index*sizeof(int16_t)))
      ->NewPrimitiveValue(helper.isolate_, v8::kDescriptorInt16Type, 0);
  AlignedArray* array = helper.array_.get();
  array->As<uintptr_t**>()[first_index] =
      &array->As<uintptr_t*>()[pointed_to_index];
  VerifyRead(descriptor, internal_field, array,
             v8::Integer::New(helper.isolate_, 0));
  second_index += pointed_to_index*sizeof(uintptr_t)/sizeof(uint16_t);
  array->As<uint16_t*>()[second_index] = expected;
  VerifyRead(descriptor, internal_field, array,
             v8::Integer::New(helper.isolate_, expected));
}


TEST(HandleDereferenceRead) {
  DescriptorTestHelper helper;
  v8::HandleScope handle_scope(helper.isolate_);
  int index = 13;
  int internal_field = 0;
  v8::Handle<v8::DeclaredAccessorDescriptor> descriptor =
      OOD::NewInternalFieldDereference(helper.isolate_, internal_field)
      ->NewRawShift(helper.isolate_, index*kPointerSize)
      ->NewHandleDereference(helper.isolate_);
  HandleArray* array = helper.handle_array_.get();
  v8::Handle<v8::String> expected = v8_str("whatever");
  array->handles_[index].Reset(helper.isolate_, expected);
  VerifyRead(descriptor, internal_field, array, expected);
}
