// Copyright 2020 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.

#if !defined(_WIN32) && !defined(_WIN64)
#include <unistd.h>  // NOLINT
#endif               // !defined(_WIN32) && !defined(_WIN64)

#include <locale.h>

#include <string>
#include <vector>

#include "include/libplatform/libplatform.h"
#include "include/v8.h"
#include "src/base/platform/platform.h"
#include "src/base/platform/time.h"
#include "src/base/small-vector.h"
#include "src/flags/flags.h"
#include "src/heap/read-only-heap.h"
#include "src/libplatform/default-platform.h"
#include "src/utils/utils.h"
#include "src/utils/vector.h"
#include "test/inspector/frontend-channel.h"
#include "test/inspector/isolate-data.h"
#include "test/inspector/task-runner.h"
#include "test/inspector/tasks.h"

namespace v8 {
namespace internal {
namespace {

base::SmallVector<TaskRunner*, 2> task_runners;

class UtilsExtension : public IsolateData::SetupGlobalTask {
 public:
  ~UtilsExtension() override = default;
  void Run(v8::Isolate* isolate,
           v8::Local<v8::ObjectTemplate> global) override {
    v8::Local<v8::ObjectTemplate> utils = v8::ObjectTemplate::New(isolate);
    auto Set = [isolate](v8::Local<v8::ObjectTemplate> tmpl, const char* str,
                         v8::Local<v8::Data> value) {
      tmpl->Set(ToV8String(isolate, str), value,
                static_cast<v8::PropertyAttribute>(
                    v8::PropertyAttribute::ReadOnly |
                    v8::PropertyAttribute::DontDelete));
    };
    Set(utils, "quit",
        v8::FunctionTemplate::New(isolate, &UtilsExtension::Quit));
    Set(utils, "compileAndRunWithOrigin",
        v8::FunctionTemplate::New(isolate,
                                  &UtilsExtension::CompileAndRunWithOrigin));
    Set(utils, "schedulePauseOnNextStatement",
        v8::FunctionTemplate::New(
            isolate, &UtilsExtension::SchedulePauseOnNextStatement));
    Set(utils, "cancelPauseOnNextStatement",
        v8::FunctionTemplate::New(isolate,
                                  &UtilsExtension::CancelPauseOnNextStatement));
    Set(utils, "createContextGroup",
        v8::FunctionTemplate::New(isolate,
                                  &UtilsExtension::CreateContextGroup));
    Set(utils, "resetContextGroup",
        v8::FunctionTemplate::New(isolate, &UtilsExtension::ResetContextGroup));
    Set(utils, "connectSession",
        v8::FunctionTemplate::New(isolate, &UtilsExtension::ConnectSession));
    Set(utils, "disconnectSession",
        v8::FunctionTemplate::New(isolate, &UtilsExtension::DisconnectSession));
    Set(utils, "sendMessageToBackend",
        v8::FunctionTemplate::New(isolate,
                                  &UtilsExtension::SendMessageToBackend));
    Set(global, "utils", utils);
  }

  static void set_backend_task_runner(TaskRunner* runner) {
    backend_runner_ = runner;
  }

  static void ClearAllSessions() { channels_.clear(); }

 private:
  static TaskRunner* backend_runner_;

  static void Quit(const v8::FunctionCallbackInfo<v8::Value>& args) {
    // Only terminate, so not join the threads here, since joining concurrently
    // from multiple threads can be undefined behaviour (see pthread_join).
    for (TaskRunner* task_runner : task_runners) task_runner->Terminate();
  }

  static void CompileAndRunWithOrigin(
      const v8::FunctionCallbackInfo<v8::Value>& args) {
    if (args.Length() != 5 || !args[0]->IsInt32() || !args[1]->IsString() ||
        !args[2]->IsString() || !args[3]->IsInt32() || !args[4]->IsInt32()) {
      return;
    }

    backend_runner_->Append(std::make_unique<ExecuteStringTask>(
        args.GetIsolate(), args[0].As<v8::Int32>()->Value(),
        ToVector(args.GetIsolate(), args[1].As<v8::String>()),
        args[2].As<v8::String>(), args[3].As<v8::Int32>(),
        args[4].As<v8::Int32>(), v8::Boolean::New(args.GetIsolate(), false)));
  }

  static void SchedulePauseOnNextStatement(
      const v8::FunctionCallbackInfo<v8::Value>& args) {
    if (args.Length() != 3 || !args[0]->IsInt32() || !args[1]->IsString() ||
        !args[2]->IsString()) {
      return;
    }
    std::vector<uint16_t> reason =
        ToVector(args.GetIsolate(), args[1].As<v8::String>());
    std::vector<uint16_t> details =
        ToVector(args.GetIsolate(), args[2].As<v8::String>());
    int context_group_id = args[0].As<v8::Int32>()->Value();
    RunSyncTask(backend_runner_,
                [&context_group_id, &reason, &details](IsolateData* data) {
                  data->SchedulePauseOnNextStatement(
                      context_group_id,
                      v8_inspector::StringView(reason.data(), reason.size()),
                      v8_inspector::StringView(details.data(), details.size()));
                });
  }

  static void CancelPauseOnNextStatement(
      const v8::FunctionCallbackInfo<v8::Value>& args) {
    if (args.Length() != 1 || !args[0]->IsInt32()) {
      return;
    }
    int context_group_id = args[0].As<v8::Int32>()->Value();
    RunSyncTask(backend_runner_, [&context_group_id](IsolateData* data) {
      data->CancelPauseOnNextStatement(context_group_id);
    });
  }

  static void CreateContextGroup(
      const v8::FunctionCallbackInfo<v8::Value>& args) {
    if (args.Length() != 0) {
      return;
    }
    int context_group_id = 0;
    RunSyncTask(backend_runner_, [&context_group_id](IsolateData* data) {
      context_group_id = data->CreateContextGroup();
    });
    args.GetReturnValue().Set(
        v8::Int32::New(args.GetIsolate(), context_group_id));
  }

  static void ResetContextGroup(
      const v8::FunctionCallbackInfo<v8::Value>& args) {
    if (args.Length() != 1 || !args[0]->IsInt32()) {
      return;
    }
    int context_group_id = args[0].As<v8::Int32>()->Value();
    RunSyncTask(backend_runner_, [&context_group_id](IsolateData* data) {
      data->ResetContextGroup(context_group_id);
    });
  }

  static void ConnectSession(const v8::FunctionCallbackInfo<v8::Value>& args) {
    if (args.Length() != 3 || !args[0]->IsInt32() || !args[1]->IsString() ||
        !args[2]->IsFunction()) {
      return;
    }
    v8::Local<v8::Context> context = args.GetIsolate()->GetCurrentContext();
    FrontendChannelImpl* channel = new FrontendChannelImpl(
        IsolateData::FromContext(context)->task_runner(),
        IsolateData::FromContext(context)->GetContextGroupId(context),
        args.GetIsolate(), args[2].As<v8::Function>());

    std::vector<uint8_t> state =
        ToBytes(args.GetIsolate(), args[1].As<v8::String>());
    int context_group_id = args[0].As<v8::Int32>()->Value();
    int session_id = 0;
    RunSyncTask(backend_runner_, [&context_group_id, &session_id, &channel,
                                  &state](IsolateData* data) {
      session_id = data->ConnectSession(
          context_group_id,
          v8_inspector::StringView(state.data(), state.size()), channel);
      channel->set_session_id(session_id);
    });

    channels_[session_id].reset(channel);
    args.GetReturnValue().Set(v8::Int32::New(args.GetIsolate(), session_id));
  }

  static void DisconnectSession(
      const v8::FunctionCallbackInfo<v8::Value>& args) {
    if (args.Length() != 1 || !args[0]->IsInt32()) {
      return;
    }
    int session_id = args[0].As<v8::Int32>()->Value();
    std::vector<uint8_t> state;
    RunSyncTask(backend_runner_, [&session_id, &state](IsolateData* data) {
      state = data->DisconnectSession(session_id);
    });
    channels_.erase(session_id);
    args.GetReturnValue().Set(ToV8String(args.GetIsolate(), state));
  }

  static void SendMessageToBackend(
      const v8::FunctionCallbackInfo<v8::Value>& args) {
    if (args.Length() != 2 || !args[0]->IsInt32() || !args[1]->IsString()) {
      return;
    }
    backend_runner_->Append(std::make_unique<SendMessageToBackendTask>(
        args[0].As<v8::Int32>()->Value(),
        ToVector(args.GetIsolate(), args[1].As<v8::String>())));
  }

  static std::map<int, std::unique_ptr<FrontendChannelImpl>> channels_;
};

TaskRunner* UtilsExtension::backend_runner_ = nullptr;
std::map<int, std::unique_ptr<FrontendChannelImpl>> UtilsExtension::channels_;

bool StrictAccessCheck(v8::Local<v8::Context> accessing_context,
                       v8::Local<v8::Object> accessed_object,
                       v8::Local<v8::Value> data) {
  CHECK(accessing_context.IsEmpty());
  return accessing_context.IsEmpty();
}

class InspectorExtension : public IsolateData::SetupGlobalTask {
 public:
  ~InspectorExtension() override = default;
  void Run(v8::Isolate* isolate,
           v8::Local<v8::ObjectTemplate> global) override {
    v8::Local<v8::ObjectTemplate> inspector = v8::ObjectTemplate::New(isolate);
    inspector->Set(ToV8String(isolate, "fireContextCreated"),
                   v8::FunctionTemplate::New(
                       isolate, &InspectorExtension::FireContextCreated));
    inspector->Set(ToV8String(isolate, "fireContextDestroyed"),
                   v8::FunctionTemplate::New(
                       isolate, &InspectorExtension::FireContextDestroyed));
    inspector->Set(
        ToV8String(isolate, "freeContext"),
        v8::FunctionTemplate::New(isolate, &InspectorExtension::FreeContext));
    inspector->Set(ToV8String(isolate, "addInspectedObject"),
                   v8::FunctionTemplate::New(
                       isolate, &InspectorExtension::AddInspectedObject));
    inspector->Set(ToV8String(isolate, "setMaxAsyncTaskStacks"),
                   v8::FunctionTemplate::New(
                       isolate, &InspectorExtension::SetMaxAsyncTaskStacks));
    inspector->Set(
        ToV8String(isolate, "dumpAsyncTaskStacksStateForTest"),
        v8::FunctionTemplate::New(
            isolate, &InspectorExtension::DumpAsyncTaskStacksStateForTest));
    inspector->Set(
        ToV8String(isolate, "breakProgram"),
        v8::FunctionTemplate::New(isolate, &InspectorExtension::BreakProgram));
    inspector->Set(
        ToV8String(isolate, "createObjectWithStrictCheck"),
        v8::FunctionTemplate::New(
            isolate, &InspectorExtension::CreateObjectWithStrictCheck));
    inspector->Set(ToV8String(isolate, "callWithScheduledBreak"),
                   v8::FunctionTemplate::New(
                       isolate, &InspectorExtension::CallWithScheduledBreak));
    inspector->Set(ToV8String(isolate, "allowAccessorFormatting"),
                   v8::FunctionTemplate::New(
                       isolate, &InspectorExtension::AllowAccessorFormatting));
    inspector->Set(
        ToV8String(isolate, "markObjectAsNotInspectable"),
        v8::FunctionTemplate::New(
            isolate, &InspectorExtension::MarkObjectAsNotInspectable));
    inspector->Set(ToV8String(isolate, "createObjectWithAccessor"),
                   v8::FunctionTemplate::New(
                       isolate, &InspectorExtension::CreateObjectWithAccessor));
    inspector->Set(ToV8String(isolate, "storeCurrentStackTrace"),
                   v8::FunctionTemplate::New(
                       isolate, &InspectorExtension::StoreCurrentStackTrace));
    inspector->Set(ToV8String(isolate, "externalAsyncTaskStarted"),
                   v8::FunctionTemplate::New(
                       isolate, &InspectorExtension::ExternalAsyncTaskStarted));
    inspector->Set(
        ToV8String(isolate, "externalAsyncTaskFinished"),
        v8::FunctionTemplate::New(
            isolate, &InspectorExtension::ExternalAsyncTaskFinished));
    inspector->Set(ToV8String(isolate, "scheduleWithAsyncStack"),
                   v8::FunctionTemplate::New(
                       isolate, &InspectorExtension::ScheduleWithAsyncStack));
    inspector->Set(
        ToV8String(isolate, "setAllowCodeGenerationFromStrings"),
        v8::FunctionTemplate::New(
            isolate, &InspectorExtension::SetAllowCodeGenerationFromStrings));
    inspector->Set(ToV8String(isolate, "setResourceNamePrefix"),
                   v8::FunctionTemplate::New(
                       isolate, &InspectorExtension::SetResourceNamePrefix));
    global->Set(ToV8String(isolate, "inspector"), inspector);
  }

 private:
  static void FireContextCreated(
      const v8::FunctionCallbackInfo<v8::Value>& args) {
    v8::Local<v8::Context> context = args.GetIsolate()->GetCurrentContext();
    IsolateData* data = IsolateData::FromContext(context);
    data->FireContextCreated(context, data->GetContextGroupId(context),
                             v8_inspector::StringView());
  }

  static void FireContextDestroyed(
      const v8::FunctionCallbackInfo<v8::Value>& args) {
    v8::Local<v8::Context> context = args.GetIsolate()->GetCurrentContext();
    IsolateData* data = IsolateData::FromContext(context);
    data->FireContextDestroyed(context);
  }

  static void FreeContext(const v8::FunctionCallbackInfo<v8::Value>& args) {
    v8::Local<v8::Context> context = args.GetIsolate()->GetCurrentContext();
    IsolateData* data = IsolateData::FromContext(context);
    data->FreeContext(context);
  }

  static void AddInspectedObject(
      const v8::FunctionCallbackInfo<v8::Value>& args) {
    if (args.Length() != 2 || !args[0]->IsInt32()) {
      return;
    }
    v8::Local<v8::Context> context = args.GetIsolate()->GetCurrentContext();
    IsolateData* data = IsolateData::FromContext(context);
    data->AddInspectedObject(args[0].As<v8::Int32>()->Value(), args[1]);
  }

  static void SetMaxAsyncTaskStacks(
      const v8::FunctionCallbackInfo<v8::Value>& args) {
    if (args.Length() != 1 || !args[0]->IsInt32()) {
      return;
    }
    IsolateData::FromContext(args.GetIsolate()->GetCurrentContext())
        ->SetMaxAsyncTaskStacksForTest(args[0].As<v8::Int32>()->Value());
  }

  static void DumpAsyncTaskStacksStateForTest(
      const v8::FunctionCallbackInfo<v8::Value>& args) {
    if (args.Length() != 0) {
      return;
    }
    IsolateData::FromContext(args.GetIsolate()->GetCurrentContext())
        ->DumpAsyncTaskStacksStateForTest();
  }

  static void BreakProgram(const v8::FunctionCallbackInfo<v8::Value>& args) {
    if (args.Length() != 2 || !args[0]->IsString() || !args[1]->IsString()) {
      return;
    }
    v8::Local<v8::Context> context = args.GetIsolate()->GetCurrentContext();
    IsolateData* data = IsolateData::FromContext(context);
    std::vector<uint16_t> reason =
        ToVector(args.GetIsolate(), args[0].As<v8::String>());
    v8_inspector::StringView reason_view(reason.data(), reason.size());
    std::vector<uint16_t> details =
        ToVector(args.GetIsolate(), args[1].As<v8::String>());
    v8_inspector::StringView details_view(details.data(), details.size());
    data->BreakProgram(data->GetContextGroupId(context), reason_view,
                       details_view);
  }

  static void CreateObjectWithStrictCheck(
      const v8::FunctionCallbackInfo<v8::Value>& args) {
    if (args.Length() != 0) {
      return;
    }
    v8::Local<v8::ObjectTemplate> templ =
        v8::ObjectTemplate::New(args.GetIsolate());
    templ->SetAccessCheckCallback(&StrictAccessCheck);
    args.GetReturnValue().Set(
        templ->NewInstance(args.GetIsolate()->GetCurrentContext())
            .ToLocalChecked());
  }

  static void CallWithScheduledBreak(
      const v8::FunctionCallbackInfo<v8::Value>& args) {
    if (args.Length() != 3 || !args[0]->IsFunction() || !args[1]->IsString() ||
        !args[2]->IsString()) {
      return;
    }
    std::vector<uint16_t> reason =
        ToVector(args.GetIsolate(), args[1].As<v8::String>());
    v8_inspector::StringView reason_view(reason.data(), reason.size());
    std::vector<uint16_t> details =
        ToVector(args.GetIsolate(), args[2].As<v8::String>());
    v8_inspector::StringView details_view(details.data(), details.size());
    v8::Local<v8::Context> context = args.GetIsolate()->GetCurrentContext();
    IsolateData* data = IsolateData::FromContext(context);
    int context_group_id = data->GetContextGroupId(context);
    data->SchedulePauseOnNextStatement(context_group_id, reason_view,
                                       details_view);
    v8::MaybeLocal<v8::Value> result;
    result = args[0].As<v8::Function>()->Call(context, context->Global(), 0,
                                              nullptr);
    data->CancelPauseOnNextStatement(context_group_id);
  }

  static void AllowAccessorFormatting(
      const v8::FunctionCallbackInfo<v8::Value>& args) {
    if (args.Length() != 1 || !args[0]->IsObject()) {
      return;
    }
    v8::Local<v8::Object> object = args[0].As<v8::Object>();
    v8::Isolate* isolate = args.GetIsolate();
    v8::Local<v8::Private> shouldFormatAccessorsPrivate = v8::Private::ForApi(
        isolate, ToV8String(isolate, "allowAccessorFormatting"));
    object
        ->SetPrivate(isolate->GetCurrentContext(), shouldFormatAccessorsPrivate,
                     v8::Null(isolate))
        .ToChecked();
  }

  static void MarkObjectAsNotInspectable(
      const v8::FunctionCallbackInfo<v8::Value>& args) {
    if (args.Length() != 1 || !args[0]->IsObject()) {
      return;
    }
    v8::Local<v8::Object> object = args[0].As<v8::Object>();
    v8::Isolate* isolate = args.GetIsolate();
    v8::Local<v8::Private> notInspectablePrivate =
        v8::Private::ForApi(isolate, ToV8String(isolate, "notInspectable"));
    object
        ->SetPrivate(isolate->GetCurrentContext(), notInspectablePrivate,
                     v8::True(isolate))
        .ToChecked();
  }

  static void CreateObjectWithAccessor(
      const v8::FunctionCallbackInfo<v8::Value>& args) {
    if (args.Length() != 2 || !args[0]->IsString() || !args[1]->IsBoolean()) {
      return;
    }
    v8::Isolate* isolate = args.GetIsolate();
    v8::Local<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate);
    if (args[1].As<v8::Boolean>()->Value()) {
      templ->SetAccessor(v8::Local<v8::String>::Cast(args[0]), AccessorGetter,
                         AccessorSetter);
    } else {
      templ->SetAccessor(v8::Local<v8::String>::Cast(args[0]), AccessorGetter);
    }
    args.GetReturnValue().Set(
        templ->NewInstance(isolate->GetCurrentContext()).ToLocalChecked());
  }

  static void AccessorGetter(v8::Local<v8::String> property,
                             const v8::PropertyCallbackInfo<v8::Value>& info) {
    v8::Isolate* isolate = info.GetIsolate();
    isolate->ThrowException(ToV8String(isolate, "Getter is called"));
  }

  static void AccessorSetter(v8::Local<v8::String> property,
                             v8::Local<v8::Value> value,
                             const v8::PropertyCallbackInfo<void>& info) {
    v8::Isolate* isolate = info.GetIsolate();
    isolate->ThrowException(ToV8String(isolate, "Setter is called"));
  }

  static void StoreCurrentStackTrace(
      const v8::FunctionCallbackInfo<v8::Value>& args) {
    if (args.Length() != 1 || !args[0]->IsString()) {
      return;
    }
    v8::Isolate* isolate = args.GetIsolate();
    v8::Local<v8::Context> context = isolate->GetCurrentContext();
    IsolateData* data = IsolateData::FromContext(context);
    std::vector<uint16_t> description =
        ToVector(isolate, args[0].As<v8::String>());
    v8_inspector::StringView description_view(description.data(),
                                              description.size());
    v8_inspector::V8StackTraceId id =
        data->StoreCurrentStackTrace(description_view);
    v8::Local<v8::ArrayBuffer> buffer =
        v8::ArrayBuffer::New(isolate, sizeof(id));
    *static_cast<v8_inspector::V8StackTraceId*>(
        buffer->GetBackingStore()->Data()) = id;
    args.GetReturnValue().Set(buffer);
  }

  static void ExternalAsyncTaskStarted(
      const v8::FunctionCallbackInfo<v8::Value>& args) {
    if (args.Length() != 1 || !args[0]->IsArrayBuffer()) {
      return;
    }
    v8::Local<v8::Context> context = args.GetIsolate()->GetCurrentContext();
    IsolateData* data = IsolateData::FromContext(context);
    v8_inspector::V8StackTraceId* id =
        static_cast<v8_inspector::V8StackTraceId*>(
            args[0].As<v8::ArrayBuffer>()->GetBackingStore()->Data());
    data->ExternalAsyncTaskStarted(*id);
  }

  static void ExternalAsyncTaskFinished(
      const v8::FunctionCallbackInfo<v8::Value>& args) {
    if (args.Length() != 1 || !args[0]->IsArrayBuffer()) {
      return;
    }
    v8::Local<v8::Context> context = args.GetIsolate()->GetCurrentContext();
    IsolateData* data = IsolateData::FromContext(context);
    v8_inspector::V8StackTraceId* id =
        static_cast<v8_inspector::V8StackTraceId*>(
            args[0].As<v8::ArrayBuffer>()->GetBackingStore()->Data());
    data->ExternalAsyncTaskFinished(*id);
  }

  static void ScheduleWithAsyncStack(
      const v8::FunctionCallbackInfo<v8::Value>& args) {
    if (args.Length() != 3 || !args[0]->IsFunction() || !args[1]->IsString() ||
        !args[2]->IsBoolean()) {
      return;
    }
    v8::Isolate* isolate = args.GetIsolate();
    v8::Local<v8::Context> context = isolate->GetCurrentContext();
    IsolateData* data = IsolateData::FromContext(context);
    int context_group_id = data->GetContextGroupId(context);
    bool with_empty_stack = args[2].As<v8::Boolean>()->Value();
    if (with_empty_stack) context->Exit();

    std::vector<uint16_t> task_name =
        ToVector(isolate, args[1].As<v8::String>());
    v8_inspector::StringView task_name_view(task_name.data(), task_name.size());

    RunAsyncTask(
        data->task_runner(), task_name_view,
        std::make_unique<SetTimeoutTask>(
            context_group_id, isolate, v8::Local<v8::Function>::Cast(args[0])));
    if (with_empty_stack) context->Enter();
  }

  static void SetAllowCodeGenerationFromStrings(
      const v8::FunctionCallbackInfo<v8::Value>& args) {
    if (args.Length() != 1 || !args[0]->IsBoolean()) {
      return;
    }
    args.GetIsolate()->GetCurrentContext()->AllowCodeGenerationFromStrings(
        args[0].As<v8::Boolean>()->Value());
  }

  static void SetResourceNamePrefix(
      const v8::FunctionCallbackInfo<v8::Value>& args) {
    if (args.Length() != 1 || !args[0]->IsString()) {
      return;
    }
    v8::Isolate* isolate = args.GetIsolate();
    v8::Local<v8::Context> context = isolate->GetCurrentContext();
    IsolateData* data = IsolateData::FromContext(context);
    data->SetResourceNamePrefix(v8::Local<v8::String>::Cast(args[0]));
  }
};

using CharVector = v8::internal::Vector<const char>;

constexpr auto kMaxExecutionSeconds = v8::base::TimeDelta::FromSeconds(2);

class Watchdog final : public base::Thread {
 public:
  explicit Watchdog(base::Semaphore* semaphore)
      : base::Thread(base::Thread::Options("InspectorFuzzerWatchdog")),
        semaphore_(semaphore) {
    CHECK(Start());
  }

 private:
  void Run() override {
    if (semaphore_->WaitFor(kMaxExecutionSeconds)) return;
    for (TaskRunner* task_runner : task_runners) task_runner->Terminate();
  }

  base::Semaphore* const semaphore_;
};

void FuzzInspector(const uint8_t* data, size_t size) {
  base::Semaphore ready_semaphore(0);

  IsolateData::SetupGlobalTasks frontend_extensions;
  frontend_extensions.emplace_back(new UtilsExtension());
  TaskRunner frontend_runner(std::move(frontend_extensions),
                             kDontCatchExceptions, &ready_semaphore, nullptr,
                             kNoInspector);
  ready_semaphore.Wait();

  int frontend_context_group_id = 0;
  RunSyncTask(&frontend_runner,
              [&frontend_context_group_id](IsolateData* data) {
                frontend_context_group_id = data->CreateContextGroup();
              });

  IsolateData::SetupGlobalTasks backend_extensions;
  backend_extensions.emplace_back(new SetTimeoutExtension());
  backend_extensions.emplace_back(new InspectorExtension());
  TaskRunner backend_runner(std::move(backend_extensions), kDontCatchExceptions,
                            &ready_semaphore, nullptr, kWithInspector);
  ready_semaphore.Wait();
  UtilsExtension::set_backend_task_runner(&backend_runner);

  task_runners = {&frontend_runner, &backend_runner};

  Watchdog watchdog(&ready_semaphore);

  frontend_runner.Append(std::make_unique<ExecuteStringTask>(
      std::string{reinterpret_cast<const char*>(data), size},
      frontend_context_group_id));

  frontend_runner.Join();
  backend_runner.Join();

  ready_semaphore.Signal();
  watchdog.Join();

  UtilsExtension::ClearAllSessions();

  // TaskRunners go out of scope here, which causes Isolate teardown and all
  // running background tasks to be properly joined.
}

}  //  namespace
}  // namespace internal
}  // namespace v8

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
  v8::internal::FuzzInspector(data, size);
  return 0;
}
