// Copyright 2016 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 "test/fuzzer/fuzzer-support.h"

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

#include "include/libplatform/libplatform.h"

#include "src/flags.h"

namespace v8_fuzzer {

namespace {

FuzzerSupport* g_fuzzer_support = nullptr;

void DeleteFuzzerSupport() {
  if (g_fuzzer_support) {
    delete g_fuzzer_support;
    g_fuzzer_support = nullptr;
  }
}

}  // namespace

class FuzzerSupport::ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
 public:
  virtual void* Allocate(size_t length) {
    void* data = AllocateUninitialized(length);
    return data == NULL ? data : memset(data, 0, length);
  }
  virtual void* AllocateUninitialized(size_t length) { return malloc(length); }
  virtual void Free(void* data, size_t) { free(data); }
};

FuzzerSupport::FuzzerSupport(int* argc, char*** argv) {
  v8::internal::FLAG_expose_gc = true;
  v8::V8::SetFlagsFromCommandLine(argc, *argv, true);
  v8::V8::InitializeICU();
  v8::V8::InitializeExternalStartupData((*argv)[0]);
  platform_ = v8::platform::CreateDefaultPlatform();
  v8::V8::InitializePlatform(platform_);
  v8::V8::Initialize();

  allocator_ = new ArrayBufferAllocator;
  v8::Isolate::CreateParams create_params;
  create_params.array_buffer_allocator = allocator_;
  isolate_ = v8::Isolate::New(create_params);

  {
    v8::Isolate::Scope isolate_scope(isolate_);
    v8::HandleScope handle_scope(isolate_);
    context_.Reset(isolate_, v8::Context::New(isolate_));
  }
}

FuzzerSupport::~FuzzerSupport() {
  {
    v8::Isolate::Scope isolate_scope(isolate_);
    while (v8::platform::PumpMessageLoop(platform_, isolate_)) /* empty */
      ;

    v8::HandleScope handle_scope(isolate_);
    context_.Reset();
  }

  isolate_->LowMemoryNotification();
  isolate_->Dispose();
  isolate_ = nullptr;

  delete allocator_;
  allocator_ = nullptr;

  v8::V8::Dispose();
  v8::V8::ShutdownPlatform();

  delete platform_;
  platform_ = nullptr;
}

// static
FuzzerSupport* FuzzerSupport::Get() { return g_fuzzer_support; }

v8::Isolate* FuzzerSupport::GetIsolate() { return isolate_; }

v8::Local<v8::Context> FuzzerSupport::GetContext() {
  v8::Isolate::Scope isolate_scope(isolate_);
  v8::EscapableHandleScope handle_scope(isolate_);
  v8::Local<v8::Context> context =
      v8::Local<v8::Context>::New(isolate_, context_);
  return handle_scope.Escape(context);
}

}  // namespace v8_fuzzer

extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) {
  v8_fuzzer::g_fuzzer_support = new v8_fuzzer::FuzzerSupport(argc, argv);
  atexit(&v8_fuzzer::DeleteFuzzerSupport);
  return 0;
}
