// 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;


// 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();
  }
}
