// Copyright 2007-2011 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 <limits.h>

#include "v8.h"

#include "api.h"
#include "isolate.h"
#include "compilation-cache.h"
#include "execution.h"
#include "snapshot.h"
#include "platform.h"
#include "utils.h"
#include "cctest.h"
#include "parser.h"
#include "unicode-inl.h"

using ::v8::AccessorInfo;
using ::v8::Context;
using ::v8::Extension;
using ::v8::Function;
using ::v8::HandleScope;
using ::v8::Local;
using ::v8::Object;
using ::v8::ObjectTemplate;
using ::v8::Persistent;
using ::v8::Script;
using ::v8::String;
using ::v8::Value;
using ::v8::V8;

namespace i = ::i;




// Migrating an isolate
class KangarooThread : public v8::internal::Thread {
 public:
  KangarooThread(v8::Isolate* isolate,
                 v8::Handle<v8::Context> context, int value)
      : Thread("KangarooThread"),
        isolate_(isolate), context_(context), value_(value) {
  }

  void Run() {
    {
      v8::Locker locker(isolate_);
      v8::Isolate::Scope isolate_scope(isolate_);
      CHECK_EQ(isolate_, v8::internal::Isolate::Current());
      v8::HandleScope scope;
      v8::Context::Scope context_scope(context_);
      Local<Value> v = CompileRun("getValue()");
      CHECK(v->IsNumber());
      CHECK_EQ(30, static_cast<int>(v->NumberValue()));
    }
    {
      v8::Locker locker(isolate_);
      v8::Isolate::Scope isolate_scope(isolate_);
      v8::Context::Scope context_scope(context_);
      v8::HandleScope scope;
      Local<Value> v = CompileRun("getValue()");
      CHECK(v->IsNumber());
      CHECK_EQ(30, static_cast<int>(v->NumberValue()));
    }
    isolate_->Dispose();
  }

 private:
  v8::Isolate* isolate_;
  Persistent<v8::Context> context_;
  int value_;
};

// Migrates an isolate from one thread to another
TEST(KangarooIsolates) {
  v8::Isolate* isolate = v8::Isolate::New();
  Persistent<v8::Context> context;
  {
    v8::Locker locker(isolate);
    v8::Isolate::Scope isolate_scope(isolate);
    v8::HandleScope handle_scope;
    context = v8::Context::New();
    v8::Context::Scope context_scope(context);
    CHECK_EQ(isolate, v8::internal::Isolate::Current());
    CompileRun("function getValue() { return 30; }");
  }
  KangarooThread thread1(isolate, context, 1);
  thread1.Start();
  thread1.Join();
}

static void CalcFibAndCheck() {
  Local<Value> v = CompileRun("function fib(n) {"
                              "  if (n <= 2) return 1;"
                              "  return fib(n-1) + fib(n-2);"
                              "}"
                              "fib(10)");
  CHECK(v->IsNumber());
  CHECK_EQ(55, static_cast<int>(v->NumberValue()));
}

class JoinableThread {
 public:
  explicit JoinableThread(const char* name)
    : name_(name),
      semaphore_(i::OS::CreateSemaphore(0)),
      thread_(this) {
  }

  virtual ~JoinableThread() {
    delete semaphore_;
  }

  void Start() {
    thread_.Start();
  }

  void Join() {
    semaphore_->Wait();
  }

  virtual void Run() = 0;
 private:
  class ThreadWithSemaphore : public i::Thread {
   public:
    explicit ThreadWithSemaphore(JoinableThread* joinable_thread)
      : Thread(joinable_thread->name_),
        joinable_thread_(joinable_thread) {
    }

    virtual void Run() {
      joinable_thread_->Run();
      joinable_thread_->semaphore_->Signal();
    }

   private:
    JoinableThread* joinable_thread_;
  };

  const char* name_;
  i::Semaphore* semaphore_;
  ThreadWithSemaphore thread_;

  friend class ThreadWithSemaphore;

  DISALLOW_COPY_AND_ASSIGN(JoinableThread);
};


class IsolateLockingThreadWithLocalContext : public JoinableThread {
 public:
  explicit IsolateLockingThreadWithLocalContext(v8::Isolate* isolate)
    : JoinableThread("IsolateLockingThread"),
      isolate_(isolate) {
  }

  virtual void Run() {
    v8::Locker locker(isolate_);
    v8::Isolate::Scope isolate_scope(isolate_);
    v8::HandleScope handle_scope;
    LocalContext local_context;
    CHECK_EQ(isolate_, v8::internal::Isolate::Current());
    CalcFibAndCheck();
  }
 private:
  v8::Isolate* isolate_;
};

static void StartJoinAndDeleteThreads(const i::List<JoinableThread*>& threads) {
  for (int i = 0; i < threads.length(); i++) {
    threads[i]->Start();
  }
  for (int i = 0; i < threads.length(); i++) {
    threads[i]->Join();
  }
  for (int i = 0; i < threads.length(); i++) {
    delete threads[i];
  }
}


// Run many threads all locking on the same isolate
TEST(IsolateLockingStress) {
  const int kNThreads = 100;
  i::List<JoinableThread*> threads(kNThreads);
  v8::Isolate* isolate = v8::Isolate::New();
  for (int i = 0; i < kNThreads; i++) {
    threads.Add(new IsolateLockingThreadWithLocalContext(isolate));
  }
  StartJoinAndDeleteThreads(threads);
  isolate->Dispose();
}

class IsolateNonlockingThread : public JoinableThread {
 public:
  explicit IsolateNonlockingThread()
    : JoinableThread("IsolateNonlockingThread") {
  }

  virtual void Run() {
    v8::Isolate* isolate = v8::Isolate::New();
    {
      v8::Isolate::Scope isolate_scope(isolate);
      v8::HandleScope handle_scope;
      v8::Handle<v8::Context> context = v8::Context::New();
      v8::Context::Scope context_scope(context);
      CHECK_EQ(isolate, v8::internal::Isolate::Current());
      CalcFibAndCheck();
    }
    isolate->Dispose();
  }
 private:
};

// Run many threads each accessing its own isolate without locking
TEST(MultithreadedParallelIsolates) {
#ifdef V8_TARGET_ARCH_ARM
  const int kNThreads = 10;
#else
  const int kNThreads = 50;
#endif
  i::List<JoinableThread*> threads(kNThreads);
  for (int i = 0; i < kNThreads; i++) {
    threads.Add(new IsolateNonlockingThread());
  }
  StartJoinAndDeleteThreads(threads);
}


class IsolateNestedLockingThread : public JoinableThread {
 public:
  explicit IsolateNestedLockingThread(v8::Isolate* isolate)
    : JoinableThread("IsolateNestedLocking"), isolate_(isolate) {
  }
  virtual void Run() {
    v8::Locker lock(isolate_);
    v8::Isolate::Scope isolate_scope(isolate_);
    v8::HandleScope handle_scope;
    LocalContext local_context;
    {
      v8::Locker another_lock(isolate_);
      CalcFibAndCheck();
    }
    {
      v8::Locker another_lock(isolate_);
      CalcFibAndCheck();
    }
  }
 private:
  v8::Isolate* isolate_;
};

// Run  many threads with nested locks
TEST(IsolateNestedLocking) {
  const int kNThreads = 100;
  v8::Isolate* isolate = v8::Isolate::New();
  i::List<JoinableThread*> threads(kNThreads);
  for (int i = 0; i < kNThreads; i++) {
    threads.Add(new IsolateNestedLockingThread(isolate));
  }
  StartJoinAndDeleteThreads(threads);
}


class SeparateIsolatesLocksNonexclusiveThread : public JoinableThread {
 public:
  SeparateIsolatesLocksNonexclusiveThread(v8::Isolate* isolate1,
                                          v8::Isolate* isolate2)
    : JoinableThread("SeparateIsolatesLocksNonexclusiveThread"),
      isolate1_(isolate1), isolate2_(isolate2) {
  }

  virtual void Run() {
    v8::Locker lock(isolate1_);
    v8::Isolate::Scope isolate_scope(isolate1_);
    v8::HandleScope handle_scope;
    LocalContext local_context;

    IsolateLockingThreadWithLocalContext threadB(isolate2_);
    threadB.Start();
    CalcFibAndCheck();
    threadB.Join();
  }
 private:
  v8::Isolate* isolate1_;
  v8::Isolate* isolate2_;
};

// Run parallel threads that lock and access different isolates in parallel
TEST(SeparateIsolatesLocksNonexclusive) {
#ifdef V8_TARGET_ARCH_ARM
  const int kNThreads = 50;
#else
  const int kNThreads = 100;
#endif
  v8::Isolate* isolate1 = v8::Isolate::New();
  v8::Isolate* isolate2 = v8::Isolate::New();
  i::List<JoinableThread*> threads(kNThreads);
  for (int i = 0; i < kNThreads; i++) {
    threads.Add(new SeparateIsolatesLocksNonexclusiveThread(isolate1,
                                                             isolate2));
  }
  StartJoinAndDeleteThreads(threads);
  isolate2->Dispose();
  isolate1->Dispose();
}

class LockIsolateAndCalculateFibSharedContextThread : public JoinableThread {
 public:
  explicit LockIsolateAndCalculateFibSharedContextThread(
      v8::Isolate* isolate, v8::Handle<v8::Context> context)
    : JoinableThread("LockIsolateAndCalculateFibThread"),
      isolate_(isolate),
      context_(context) {
  }

  virtual void Run() {
    v8::Locker lock(isolate_);
    v8::Isolate::Scope isolate_scope(isolate_);
    HandleScope handle_scope;
    v8::Context::Scope context_scope(context_);
    CalcFibAndCheck();
  }
 private:
  v8::Isolate* isolate_;
  Persistent<v8::Context> context_;
};

class LockerUnlockerThread : public JoinableThread {
 public:
  explicit LockerUnlockerThread(v8::Isolate* isolate)
    : JoinableThread("LockerUnlockerThread"),
      isolate_(isolate) {
  }

  virtual void Run() {
    v8::Locker lock(isolate_);
    v8::Isolate::Scope isolate_scope(isolate_);
    v8::HandleScope handle_scope;
    v8::Handle<v8::Context> context = v8::Context::New();
    {
      v8::Context::Scope context_scope(context);
      CalcFibAndCheck();
    }
    {
      isolate_->Exit();
      v8::Unlocker unlocker(isolate_);
      LockIsolateAndCalculateFibSharedContextThread thread(isolate_, context);
      thread.Start();
      thread.Join();
    }
    isolate_->Enter();
    {
      v8::Context::Scope context_scope(context);
      CalcFibAndCheck();
    }
  }
 private:
  v8::Isolate* isolate_;
};

// Use unlocker inside of a Locker, multiple threads.
TEST(LockerUnlocker) {
#ifdef V8_TARGET_ARCH_ARM
  const int kNThreads = 50;
#else
  const int kNThreads = 100;
#endif
  i::List<JoinableThread*> threads(kNThreads);
  v8::Isolate* isolate = v8::Isolate::New();
  for (int i = 0; i < kNThreads; i++) {
    threads.Add(new LockerUnlockerThread(isolate));
  }
  StartJoinAndDeleteThreads(threads);
  isolate->Dispose();
}

class LockTwiceAndUnlockThread : public JoinableThread {
 public:
  explicit LockTwiceAndUnlockThread(v8::Isolate* isolate)
    : JoinableThread("LockTwiceAndUnlockThread"),
      isolate_(isolate) {
  }

  virtual void Run() {
    v8::Locker lock(isolate_);
    v8::Isolate::Scope isolate_scope(isolate_);
    v8::HandleScope handle_scope;
    v8::Handle<v8::Context> context = v8::Context::New();
    {
      v8::Context::Scope context_scope(context);
      CalcFibAndCheck();
    }
    {
      v8::Locker second_lock(isolate_);
      {
        isolate_->Exit();
        v8::Unlocker unlocker(isolate_);
        LockIsolateAndCalculateFibSharedContextThread thread(isolate_, context);
        thread.Start();
        thread.Join();
      }
    }
    isolate_->Enter();
    {
      v8::Context::Scope context_scope(context);
      CalcFibAndCheck();
    }
  }
 private:
  v8::Isolate* isolate_;
};

// Use Unlocker inside two Lockers.
TEST(LockTwiceAndUnlock) {
#ifdef V8_TARGET_ARCH_ARM
  const int kNThreads = 50;
#else
  const int kNThreads = 100;
#endif
  i::List<JoinableThread*> threads(kNThreads);
  v8::Isolate* isolate = v8::Isolate::New();
  for (int i = 0; i < kNThreads; i++) {
    threads.Add(new LockTwiceAndUnlockThread(isolate));
  }
  StartJoinAndDeleteThreads(threads);
  isolate->Dispose();
}

class LockAndUnlockDifferentIsolatesThread : public JoinableThread {
 public:
  LockAndUnlockDifferentIsolatesThread(v8::Isolate* isolate1,
                                       v8::Isolate* isolate2)
    : JoinableThread("LockAndUnlockDifferentIsolatesThread"),
      isolate1_(isolate1),
      isolate2_(isolate2) {
  }

  virtual void Run() {
    Persistent<v8::Context> context1;
    Persistent<v8::Context> context2;
    v8::Locker lock1(isolate1_);
    CHECK(v8::Locker::IsLocked(isolate1_));
    CHECK(!v8::Locker::IsLocked(isolate2_));
    {
      v8::Isolate::Scope isolate_scope(isolate1_);
      v8::HandleScope handle_scope;
      context1 = v8::Context::New();
      {
        v8::Context::Scope context_scope(context1);
        CalcFibAndCheck();
      }
    }
    v8::Locker lock2(isolate2_);
    CHECK(v8::Locker::IsLocked(isolate1_));
    CHECK(v8::Locker::IsLocked(isolate2_));
    {
      v8::Isolate::Scope isolate_scope(isolate2_);
      v8::HandleScope handle_scope;
      context2 = v8::Context::New();
      {
        v8::Context::Scope context_scope(context2);
        CalcFibAndCheck();
      }
    }
    {
      v8::Unlocker unlock1(isolate1_);
      CHECK(!v8::Locker::IsLocked(isolate1_));
      CHECK(v8::Locker::IsLocked(isolate2_));
      v8::Isolate::Scope isolate_scope(isolate2_);
      v8::HandleScope handle_scope;
      v8::Context::Scope context_scope(context2);
      LockIsolateAndCalculateFibSharedContextThread thread(isolate1_, context1);
      thread.Start();
      CalcFibAndCheck();
      thread.Join();
    }
  }
 private:
  v8::Isolate* isolate1_;
  v8::Isolate* isolate2_;
};

// Lock two isolates and unlock one of them.
TEST(LockAndUnlockDifferentIsolates) {
  v8::Isolate* isolate1 = v8::Isolate::New();
  v8::Isolate* isolate2 = v8::Isolate::New();
  LockAndUnlockDifferentIsolatesThread thread(isolate1, isolate2);
  thread.Start();
  thread.Join();
  isolate2->Dispose();
  isolate1->Dispose();
}

class LockUnlockLockThread : public JoinableThread {
 public:
  LockUnlockLockThread(v8::Isolate* isolate, v8::Handle<v8::Context> context)
    : JoinableThread("LockUnlockLockThread"),
      isolate_(isolate),
      context_(context) {
  }

  virtual void Run() {
    v8::Locker lock1(isolate_);
    CHECK(v8::Locker::IsLocked(isolate_));
    CHECK(!v8::Locker::IsLocked());
    {
      v8::Isolate::Scope isolate_scope(isolate_);
      v8::HandleScope handle_scope;
      v8::Context::Scope context_scope(context_);
      CalcFibAndCheck();
    }
    {
      v8::Unlocker unlock1(isolate_);
      CHECK(!v8::Locker::IsLocked(isolate_));
      CHECK(!v8::Locker::IsLocked());
      {
        v8::Locker lock2(isolate_);
        v8::Isolate::Scope isolate_scope(isolate_);
        v8::HandleScope handle_scope;
        CHECK(v8::Locker::IsLocked(isolate_));
        CHECK(!v8::Locker::IsLocked());
        v8::Context::Scope context_scope(context_);
        CalcFibAndCheck();
      }
    }
  }

 private:
  v8::Isolate* isolate_;
  v8::Persistent<v8::Context> context_;
};

// Locker inside an Unlocker inside a Locker.
TEST(LockUnlockLockMultithreaded) {
  const int kNThreads = 100;
  v8::Isolate* isolate = v8::Isolate::New();
  Persistent<v8::Context> context;
  {
    v8::Locker locker_(isolate);
    v8::Isolate::Scope isolate_scope(isolate);
    v8::HandleScope handle_scope;
    context = v8::Context::New();
  }
  i::List<JoinableThread*> threads(kNThreads);
  for (int i = 0; i < kNThreads; i++) {
    threads.Add(new LockUnlockLockThread(isolate, context));
  }
  StartJoinAndDeleteThreads(threads);
}

class LockUnlockLockDefaultIsolateThread : public JoinableThread {
 public:
  explicit LockUnlockLockDefaultIsolateThread(v8::Handle<v8::Context> context)
    : JoinableThread("LockUnlockLockDefaultIsolateThread"),
      context_(context) {
  }

  virtual void Run() {
    v8::Locker lock1;
    {
      v8::HandleScope handle_scope;
      v8::Context::Scope context_scope(context_);
      CalcFibAndCheck();
    }
    {
      v8::Unlocker unlock1;
      {
        v8::Locker lock2;
        v8::HandleScope handle_scope;
        v8::Context::Scope context_scope(context_);
        CalcFibAndCheck();
      }
    }
  }

 private:
  v8::Persistent<v8::Context> context_;
};

// Locker inside an Unlocker inside a Locker for default isolate.
TEST(LockUnlockLockDefaultIsolateMultithreaded) {
  const int kNThreads = 100;
  Persistent<v8::Context> context;
  {
    v8::Locker locker_;
    v8::HandleScope handle_scope;
    context = v8::Context::New();
  }
  i::List<JoinableThread*> threads(kNThreads);
  for (int i = 0; i < kNThreads; i++) {
    threads.Add(new LockUnlockLockDefaultIsolateThread(context));
  }
  StartJoinAndDeleteThreads(threads);
}


TEST(Regress1433) {
  for (int i = 0; i < 10; i++) {
    v8::Isolate* isolate = v8::Isolate::New();
    {
      v8::Locker lock(isolate);
      v8::Isolate::Scope isolate_scope(isolate);
      v8::HandleScope handle_scope;
      v8::Persistent<Context> context = v8::Context::New();
      v8::Context::Scope context_scope(context);
      v8::Handle<String> source = v8::String::New("1+1");
      v8::Handle<Script> script = v8::Script::Compile(source);
      v8::Handle<Value> result = script->Run();
      v8::String::AsciiValue ascii(result);
      context.Dispose();
    }
    isolate->Dispose();
  }
}
