// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "gin/public/isolate_holder.h"

#include <stddef.h>
#include <stdlib.h>
#include <string.h>

#include <memory>
#include <utility>

#include "base/check_op.h"
#include "base/system/sys_info.h"
#include "base/task/current_thread.h"
#include "base/task/single_thread_task_runner.h"
#include "build/build_config.h"
#include "gin/debug_impl.h"
#include "gin/function_template.h"
#include "gin/per_isolate_data.h"
#include "gin/v8_initializer.h"
#include "gin/v8_isolate_memory_dump_provider.h"
#include "gin/v8_shared_memory_dump_provider.h"
#include "v8/include/v8-isolate.h"
#include "v8/include/v8-snapshot.h"

namespace gin {

namespace {
v8::ArrayBuffer::Allocator* g_array_buffer_allocator = nullptr;
const intptr_t* g_reference_table = nullptr;
v8::FatalErrorCallback g_fatal_error_callback = nullptr;
v8::OOMErrorCallback g_oom_error_callback = nullptr;

std::unique_ptr<v8::Isolate::CreateParams> getModifiedIsolateParams(
    std::unique_ptr<v8::Isolate::CreateParams> params,
    IsolateHolder::AllowAtomicsWaitMode atomics_wait_mode,
    v8::CreateHistogramCallback create_histogram_callback,
    v8::AddHistogramSampleCallback add_histogram_sample_callback) {
  params->create_histogram_callback = create_histogram_callback;
  params->add_histogram_sample_callback = add_histogram_sample_callback;
  params->allow_atomics_wait =
      atomics_wait_mode ==
      IsolateHolder::AllowAtomicsWaitMode::kAllowAtomicsWait;
  params->array_buffer_allocator = g_array_buffer_allocator;
  return params;
}
}  // namespace

IsolateHolder::IsolateHolder(
    scoped_refptr<base::SingleThreadTaskRunner> task_runner,
    IsolateType isolate_type)
    : IsolateHolder(std::move(task_runner),
                    AccessMode::kSingleThread,
                    isolate_type) {}

IsolateHolder::IsolateHolder(
    scoped_refptr<base::SingleThreadTaskRunner> task_runner,
    AccessMode access_mode,
    IsolateType isolate_type)
    : IsolateHolder(std::move(task_runner),
                    access_mode,
                    kAllowAtomicsWait,
                    isolate_type,
                    IsolateCreationMode::kNormal) {}

IsolateHolder::IsolateHolder(
    scoped_refptr<base::SingleThreadTaskRunner> task_runner,
    AccessMode access_mode,
    AllowAtomicsWaitMode atomics_wait_mode,
    IsolateType isolate_type,
    IsolateCreationMode isolate_creation_mode,
    v8::CreateHistogramCallback create_histogram_callback,
    v8::AddHistogramSampleCallback add_histogram_sample_callback)
    : IsolateHolder(task_runner,
                    access_mode,
                    isolate_type,
                    getModifiedIsolateParams(getDefaultIsolateParams(),
                                             atomics_wait_mode,
                                             create_histogram_callback,
                                             add_histogram_sample_callback),
                    isolate_creation_mode) {}

IsolateHolder::IsolateHolder(
    scoped_refptr<base::SingleThreadTaskRunner> task_runner,
    AccessMode access_mode,
    IsolateType isolate_type,
    std::unique_ptr<v8::Isolate::CreateParams> params,
    IsolateCreationMode isolate_creation_mode)
    : access_mode_(access_mode), isolate_type_(isolate_type) {
  CHECK(Initialized())
      << "You need to invoke gin::IsolateHolder::Initialize first";

  DCHECK(task_runner);
  DCHECK(task_runner->BelongsToCurrentThread());

  v8::ArrayBuffer::Allocator* allocator = params->array_buffer_allocator;
  DCHECK(allocator);

  isolate_ = v8::Isolate::Allocate();
  isolate_data_ = std::make_unique<PerIsolateData>(isolate_, allocator,
                                                   access_mode_, task_runner);
  //  TODO(https://crbug.com/1347092): Refactor such that caller need not
  //  provide params when creating a snapshot.
  if (isolate_creation_mode == IsolateCreationMode::kCreateSnapshot) {
    // This branch is called when creating a V8 snapshot for Blink.
    // Note SnapshotCreator calls isolate->Enter() in its construction.
    snapshot_creator_ =
        std::make_unique<v8::SnapshotCreator>(isolate_, g_reference_table);
    DCHECK_EQ(isolate_, snapshot_creator_->GetIsolate());
  } else {
    v8::Isolate::Initialize(isolate_, *params);
  }

  // This will attempt register the shared memory dump provider for every
  // IsolateHolder, but only the first registration will have any effect.
  gin::V8SharedMemoryDumpProvider::Register();

  isolate_memory_dump_provider_ =
      std::make_unique<V8IsolateMemoryDumpProvider>(this, task_runner);
}

IsolateHolder::~IsolateHolder() {
  isolate_memory_dump_provider_.reset();
  // Calling Isolate::Dispose makes sure all threads which might access
  // PerIsolateData are finished.
  isolate_->Dispose();
  isolate_data_.reset();
  isolate_ = nullptr;
}

// static
void IsolateHolder::Initialize(ScriptMode mode,
                               v8::ArrayBuffer::Allocator* allocator,
                               const intptr_t* reference_table,
                               const std::string js_command_line_flags,
                               v8::FatalErrorCallback fatal_error_callback,
                               v8::OOMErrorCallback oom_error_callback) {
  CHECK(allocator);
  V8Initializer::Initialize(mode, js_command_line_flags, oom_error_callback);
  g_array_buffer_allocator = allocator;
  g_reference_table = reference_table;
  g_fatal_error_callback = fatal_error_callback;
  g_oom_error_callback = oom_error_callback;
}

// static
bool IsolateHolder::Initialized() {
  return g_array_buffer_allocator;
}

// static
std::unique_ptr<v8::Isolate::CreateParams>
IsolateHolder::getDefaultIsolateParams() {
  CHECK(Initialized())
      << "You need to invoke gin::IsolateHolder::Initialize first";
  // TODO(https://crbug.com/v8/13092): Remove usage of unique_ptr once V8
  // supports the move constructor on CreateParams.
  std::unique_ptr<v8::Isolate::CreateParams> params =
      std::make_unique<v8::Isolate::CreateParams>();
  params->code_event_handler = DebugImpl::GetJitCodeEventHandler();
  params->constraints.ConfigureDefaults(base::SysInfo::AmountOfPhysicalMemory(),
                                        base::SysInfo::AmountOfVirtualMemory());
  params->array_buffer_allocator = g_array_buffer_allocator;
  params->allow_atomics_wait = true;
  params->external_references = g_reference_table;
  params->only_terminate_in_safe_scope = true;
  params->embedder_wrapper_type_index = kWrapperInfoIndex;
  params->embedder_wrapper_object_index = kEncodedValueIndex;
  params->fatal_error_callback = g_fatal_error_callback;
  params->oom_error_callback = g_oom_error_callback;
  return params;
}

void IsolateHolder::EnableIdleTasks(
    std::unique_ptr<V8IdleTaskRunner> idle_task_runner) {
  DCHECK(isolate_data_.get());
  isolate_data_->EnableIdleTasks(std::move(idle_task_runner));
}

}  // namespace gin
