| Index: test/inspector/inspector-test.cc
|
| diff --git a/test/inspector/inspector-test.cc b/test/inspector/inspector-test.cc
|
| index f8e96ed90b2dbdf838e19490a68c66b244e64c70..21c1254e557960031f574ba25e1689b27e4ba2b3 100644
|
| --- a/test/inspector/inspector-test.cc
|
| +++ b/test/inspector/inspector-test.cc
|
| @@ -12,6 +12,7 @@
|
| #include "include/v8.h"
|
|
|
| #include "src/base/platform/platform.h"
|
| +#include "src/conversions.h"
|
| #include "src/flags.h"
|
| #include "src/inspector/test-interface.h"
|
| #include "src/utils.h"
|
| @@ -51,6 +52,151 @@ v8::Local<v8::String> ToV8String(v8::Isolate* isolate, const char* str) {
|
| .ToLocalChecked();
|
| }
|
|
|
| +v8::internal::Vector<uint16_t> ToVector(
|
| + const v8_inspector::StringView& string) {
|
| + v8::internal::Vector<uint16_t> buffer =
|
| + v8::internal::Vector<uint16_t>::New(static_cast<int>(string.length()));
|
| + for (size_t i = 0; i < string.length(); i++) {
|
| + if (string.is8Bit())
|
| + buffer[i] = string.characters8()[i];
|
| + else
|
| + buffer[i] = string.characters16()[i];
|
| + }
|
| + return buffer;
|
| +}
|
| +
|
| +class CreateContextGroupTask : public TaskRunner::Task {
|
| + public:
|
| + CreateContextGroupTask(v8::base::Semaphore* ready_semaphore,
|
| + int* context_group_id)
|
| + : ready_semaphore_(ready_semaphore),
|
| + context_group_id_(context_group_id) {}
|
| + virtual ~CreateContextGroupTask() = default;
|
| + bool is_inspector_task() final { return true; }
|
| +
|
| + private:
|
| + void Run() override {
|
| + *context_group_id_ = data()->CreateContextGroup();
|
| + if (ready_semaphore_) ready_semaphore_->Signal();
|
| + }
|
| +
|
| + v8::base::Semaphore* ready_semaphore_;
|
| + int* context_group_id_;
|
| +};
|
| +
|
| +class ConnectSessionTask : public TaskRunner::Task {
|
| + public:
|
| + ConnectSessionTask(v8::base::Semaphore* ready_semaphore, int context_group_id,
|
| + const v8::internal::Vector<uint16_t>& state,
|
| + int* session_id)
|
| + : ready_semaphore_(ready_semaphore),
|
| + context_group_id_(context_group_id),
|
| + state_(state),
|
| + session_id_(session_id) {}
|
| + virtual ~ConnectSessionTask() = default;
|
| + bool is_inspector_task() final { return true; }
|
| +
|
| + private:
|
| + void Run() override {
|
| + v8_inspector::StringView state(state_.start(), state_.length());
|
| + *session_id_ =
|
| + data()->inspector()->ConnectSession(context_group_id_, state);
|
| + if (ready_semaphore_) ready_semaphore_->Signal();
|
| + }
|
| +
|
| + v8::base::Semaphore* ready_semaphore_;
|
| + int context_group_id_;
|
| + const v8::internal::Vector<uint16_t>& state_;
|
| + int* session_id_;
|
| +};
|
| +
|
| +class DisconnectSessionTask : public TaskRunner::Task {
|
| + public:
|
| + DisconnectSessionTask(v8::base::Semaphore* ready_semaphore, int session_id,
|
| + v8::internal::Vector<uint16_t>* state)
|
| + : ready_semaphore_(ready_semaphore),
|
| + session_id_(session_id),
|
| + state_(state) {}
|
| + virtual ~DisconnectSessionTask() = default;
|
| + bool is_inspector_task() final { return true; }
|
| +
|
| + private:
|
| + void Run() override {
|
| + std::unique_ptr<v8_inspector::StringBuffer> state =
|
| + data()->inspector()->DisconnectSession(session_id_);
|
| + *state_ = ToVector(state->string());
|
| + if (ready_semaphore_) ready_semaphore_->Signal();
|
| + }
|
| +
|
| + v8::base::Semaphore* ready_semaphore_;
|
| + int session_id_;
|
| + v8::internal::Vector<uint16_t>* state_;
|
| +};
|
| +
|
| +class SendMessageToBackendTask : public TaskRunner::Task {
|
| + public:
|
| + explicit SendMessageToBackendTask(
|
| + int session_id, const v8::internal::Vector<uint16_t>& message)
|
| + : session_id_(session_id), message_(message) {}
|
| + bool is_inspector_task() final { return true; }
|
| +
|
| + private:
|
| + void Run() override {
|
| + v8_inspector::StringView message_view(message_.start(), message_.length());
|
| + data()->inspector()->SendMessage(session_id_, message_view);
|
| + }
|
| +
|
| + int session_id_;
|
| + v8::internal::Vector<uint16_t> message_;
|
| +};
|
| +
|
| +class SchedulePauseOnNextStatementTask : public TaskRunner::Task {
|
| + public:
|
| + SchedulePauseOnNextStatementTask(
|
| + v8::base::Semaphore* ready_semaphore, int context_group_id,
|
| + const v8::internal::Vector<uint16_t>& reason,
|
| + const v8::internal::Vector<uint16_t>& details)
|
| + : ready_semaphore_(ready_semaphore),
|
| + context_group_id_(context_group_id),
|
| + reason_(reason),
|
| + details_(details) {}
|
| + virtual ~SchedulePauseOnNextStatementTask() = default;
|
| + bool is_inspector_task() final { return true; }
|
| +
|
| + private:
|
| + void Run() override {
|
| + v8_inspector::StringView reason(reason_.start(), reason_.length());
|
| + v8_inspector::StringView details(details_.start(), details_.length());
|
| + data()->inspector()->SchedulePauseOnNextStatement(context_group_id_, reason,
|
| + details);
|
| + if (ready_semaphore_) ready_semaphore_->Signal();
|
| + }
|
| +
|
| + v8::base::Semaphore* ready_semaphore_;
|
| + int context_group_id_;
|
| + const v8::internal::Vector<uint16_t>& reason_;
|
| + const v8::internal::Vector<uint16_t>& details_;
|
| +};
|
| +
|
| +class CancelPauseOnNextStatementTask : public TaskRunner::Task {
|
| + public:
|
| + CancelPauseOnNextStatementTask(v8::base::Semaphore* ready_semaphore,
|
| + int context_group_id)
|
| + : ready_semaphore_(ready_semaphore),
|
| + context_group_id_(context_group_id) {}
|
| + virtual ~CancelPauseOnNextStatementTask() = default;
|
| + bool is_inspector_task() final { return true; }
|
| +
|
| + private:
|
| + void Run() override {
|
| + data()->inspector()->CancelPauseOnNextStatement(context_group_id_);
|
| + if (ready_semaphore_) ready_semaphore_->Signal();
|
| + }
|
| +
|
| + v8::base::Semaphore* ready_semaphore_;
|
| + int context_group_id_;
|
| +};
|
| +
|
| class UtilsExtension : public IsolateData::SetupGlobalTask {
|
| public:
|
| ~UtilsExtension() override = default;
|
| @@ -82,16 +228,21 @@ class UtilsExtension : public IsolateData::SetupGlobalTask {
|
| utils->Set(ToV8String(isolate, "cancelPauseOnNextStatement"),
|
| v8::FunctionTemplate::New(
|
| isolate, &UtilsExtension::CancelPauseOnNextStatement));
|
| - utils->Set(ToV8String(isolate, "reconnect"),
|
| - v8::FunctionTemplate::New(isolate, &UtilsExtension::Reconnect));
|
| - utils->Set(ToV8String(isolate, "disconnect"),
|
| - v8::FunctionTemplate::New(isolate, &UtilsExtension::Disconnect));
|
| utils->Set(ToV8String(isolate, "setLogConsoleApiMessageCalls"),
|
| v8::FunctionTemplate::New(
|
| isolate, &UtilsExtension::SetLogConsoleApiMessageCalls));
|
| utils->Set(ToV8String(isolate, "createContextGroup"),
|
| v8::FunctionTemplate::New(isolate,
|
| &UtilsExtension::CreateContextGroup));
|
| + utils->Set(
|
| + ToV8String(isolate, "connectSession"),
|
| + v8::FunctionTemplate::New(isolate, &UtilsExtension::ConnectSession));
|
| + utils->Set(
|
| + ToV8String(isolate, "disconnectSession"),
|
| + v8::FunctionTemplate::New(isolate, &UtilsExtension::DisconnectSession));
|
| + utils->Set(ToV8String(isolate, "sendMessageToBackend"),
|
| + v8::FunctionTemplate::New(
|
| + isolate, &UtilsExtension::SendMessageToBackend));
|
| global->Set(ToV8String(isolate, "utils"), utils);
|
| }
|
|
|
| @@ -99,13 +250,8 @@ class UtilsExtension : public IsolateData::SetupGlobalTask {
|
| backend_runner_ = runner;
|
| }
|
|
|
| - static void set_inspector_client(InspectorClientImpl* client) {
|
| - inspector_client_ = client;
|
| - }
|
| -
|
| private:
|
| static TaskRunner* backend_runner_;
|
| - static InspectorClientImpl* inspector_client_;
|
|
|
| static void Print(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| for (int i = 0; i < args.Length(); i++) {
|
| @@ -189,27 +335,31 @@ class UtilsExtension : public IsolateData::SetupGlobalTask {
|
| }
|
| v8::internal::Vector<const char> chars;
|
| v8::Isolate* isolate = args.GetIsolate();
|
| + v8::Local<v8::Context> context = isolate->GetCurrentContext();
|
| + IsolateData* data = IsolateData::FromContext(context);
|
| + int context_group_id = data->GetContextGroupId(context);
|
| if (ReadFile(isolate, args[0], &chars)) {
|
| - ExecuteStringTask(chars).RunOnTaskRunner(
|
| - IsolateData::FromContext(isolate->GetCurrentContext())
|
| - ->task_runner());
|
| + ExecuteStringTask(chars, context_group_id).RunOnIsolate(data);
|
| }
|
| }
|
|
|
| static void CompileAndRunWithOrigin(
|
| const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| - if (args.Length() != 5 || !args[0]->IsString() || !args[1]->IsString() ||
|
| - !args[2]->IsInt32() || !args[3]->IsInt32() || !args[4]->IsBoolean()) {
|
| + if (args.Length() != 6 || !args[0]->IsInt32() || !args[1]->IsString() ||
|
| + !args[2]->IsString() || !args[3]->IsInt32() || !args[4]->IsInt32() ||
|
| + !args[5]->IsBoolean()) {
|
| fprintf(stderr,
|
| - "Internal error: compileAndRunWithOrigin(source, name, line, "
|
| + "Internal error: compileAndRunWithOrigin(context_group_id, "
|
| + "source, name, line, "
|
| "column, is_module).");
|
| Exit();
|
| }
|
|
|
| backend_runner_->Append(new ExecuteStringTask(
|
| - ToVector(args[0].As<v8::String>()), args[1].As<v8::String>(),
|
| - args[2].As<v8::Int32>(), args[3].As<v8::Int32>(),
|
| - args[4].As<v8::Boolean>(), nullptr, nullptr));
|
| + nullptr, args[0].As<v8::Int32>()->Value(), nullptr,
|
| + ToVector(args[1].As<v8::String>()), args[2].As<v8::String>(),
|
| + args[3].As<v8::Int32>(), args[4].As<v8::Int32>(),
|
| + args[5].As<v8::Boolean>()));
|
| }
|
|
|
| static void SetCurrentTimeMSForTest(
|
| @@ -218,7 +368,7 @@ class UtilsExtension : public IsolateData::SetupGlobalTask {
|
| fprintf(stderr, "Internal error: setCurrentTimeMSForTest(time).");
|
| Exit();
|
| }
|
| - inspector_client_->setCurrentTimeMSForTest(
|
| + backend_runner_->data()->inspector()->SetCurrentTimeMSForTest(
|
| args[0].As<v8::Number>()->Value());
|
| }
|
|
|
| @@ -228,76 +378,121 @@ class UtilsExtension : public IsolateData::SetupGlobalTask {
|
| fprintf(stderr, "Internal error: setMemoryInfoForTest(value).");
|
| Exit();
|
| }
|
| - inspector_client_->setMemoryInfoForTest(args[0]);
|
| + backend_runner_->data()->inspector()->SetMemoryInfoForTest(args[0]);
|
| }
|
|
|
| static void SchedulePauseOnNextStatement(
|
| const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| - if (args.Length() != 2 || !args[0]->IsString() || !args[1]->IsString()) {
|
| - fprintf(
|
| - stderr,
|
| - "Internal error: schedulePauseOnNextStatement('reason', 'details').");
|
| + if (args.Length() != 3 || !args[0]->IsInt32() || !args[1]->IsString() ||
|
| + !args[2]->IsString()) {
|
| + fprintf(stderr,
|
| + "Internal error: schedulePauseOnNextStatement(context_group_id, "
|
| + "'reason', 'details').");
|
| Exit();
|
| }
|
| - v8::internal::Vector<uint16_t> reason = ToVector(args[0].As<v8::String>());
|
| - v8_inspector::StringView reason_view(reason.start(), reason.length());
|
| - v8::internal::Vector<uint16_t> details = ToVector(args[1].As<v8::String>());
|
| - v8_inspector::StringView details_view(details.start(), details.length());
|
| - inspector_client_->session()->schedulePauseOnNextStatement(reason_view,
|
| - details_view);
|
| + v8::internal::Vector<uint16_t> reason = ToVector(args[1].As<v8::String>());
|
| + v8::internal::Vector<uint16_t> details = ToVector(args[2].As<v8::String>());
|
| + v8::base::Semaphore ready_semaphore(0);
|
| + backend_runner_->Append(new SchedulePauseOnNextStatementTask(
|
| + &ready_semaphore, args[0].As<v8::Int32>()->Value(), reason, details));
|
| + ready_semaphore.Wait();
|
| }
|
|
|
| static void CancelPauseOnNextStatement(
|
| const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| - if (args.Length() != 0) {
|
| - fprintf(stderr, "Internal error: cancelPauseOnNextStatement().");
|
| + if (args.Length() != 1 || !args[0]->IsInt32()) {
|
| + fprintf(stderr,
|
| + "Internal error: cancelPauseOnNextStatement(context_group_id).");
|
| + Exit();
|
| + }
|
| + v8::base::Semaphore ready_semaphore(0);
|
| + backend_runner_->Append(new CancelPauseOnNextStatementTask(
|
| + &ready_semaphore, args[0].As<v8::Int32>()->Value()));
|
| + ready_semaphore.Wait();
|
| + }
|
| +
|
| + static void SetLogConsoleApiMessageCalls(
|
| + const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| + if (args.Length() != 1 || !args[0]->IsBoolean()) {
|
| + fprintf(stderr, "Internal error: setLogConsoleApiMessageCalls(bool).");
|
| Exit();
|
| }
|
| - inspector_client_->session()->cancelPauseOnNextStatement();
|
| + backend_runner_->data()->inspector()->SetLogConsoleApiMessageCalls(
|
| + args[0].As<v8::Boolean>()->Value());
|
| }
|
|
|
| - static void Reconnect(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| + static void CreateContextGroup(
|
| + const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| if (args.Length() != 0) {
|
| - fprintf(stderr, "Internal error: reconnect().");
|
| + fprintf(stderr, "Internal error: createContextGroup().");
|
| Exit();
|
| }
|
| v8::base::Semaphore ready_semaphore(0);
|
| - inspector_client_->scheduleReconnect(&ready_semaphore);
|
| + int context_group_id = 0;
|
| + backend_runner_->Append(
|
| + new CreateContextGroupTask(&ready_semaphore, &context_group_id));
|
| ready_semaphore.Wait();
|
| + args.GetReturnValue().Set(
|
| + v8::Int32::New(args.GetIsolate(), context_group_id));
|
| }
|
|
|
| - static void Disconnect(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| - if (args.Length() != 0) {
|
| - fprintf(stderr, "Internal error: disconnect().");
|
| + static void ConnectSession(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| + if (args.Length() > 2 || !args[0]->IsInt32() ||
|
| + (args.Length() == 2 && !args[1]->IsString())) {
|
| + fprintf(stderr,
|
| + "Internal error: connectionSession(context_group_id, state=).");
|
| Exit();
|
| }
|
| + v8::internal::Vector<uint16_t> state;
|
| + if (args.Length() == 2) state = ToVector(args[1].As<v8::String>());
|
| v8::base::Semaphore ready_semaphore(0);
|
| - inspector_client_->scheduleDisconnect(&ready_semaphore);
|
| + int session_id = 0;
|
| + backend_runner_->Append(new ConnectSessionTask(
|
| + &ready_semaphore, args[0].As<v8::Int32>()->Value(), state,
|
| + &session_id));
|
| ready_semaphore.Wait();
|
| + args.GetReturnValue().Set(v8::Int32::New(args.GetIsolate(), session_id));
|
| }
|
|
|
| - static void SetLogConsoleApiMessageCalls(
|
| + static void DisconnectSession(
|
| const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| - if (args.Length() != 1 || !args[0]->IsBoolean()) {
|
| - fprintf(stderr, "Internal error: setLogConsoleApiMessageCalls(bool).");
|
| + if (args.Length() != 1 || !args[0]->IsInt32()) {
|
| + fprintf(stderr, "Internal error: disconnectionSession(session_id).");
|
| Exit();
|
| }
|
| - inspector_client_->setLogConsoleApiMessageCalls(
|
| - args[0].As<v8::Boolean>()->Value());
|
| + v8::base::Semaphore ready_semaphore(0);
|
| + v8::internal::Vector<uint16_t> state;
|
| + backend_runner_->Append(new DisconnectSessionTask(
|
| + &ready_semaphore, args[0].As<v8::Int32>()->Value(), &state));
|
| + ready_semaphore.Wait();
|
| + args.GetReturnValue().Set(
|
| + v8::String::NewFromTwoByte(args.GetIsolate(), state.start(),
|
| + v8::NewStringType::kNormal,
|
| + static_cast<int>(state.size()))
|
| + .ToLocalChecked());
|
| }
|
|
|
| - static void CreateContextGroup(
|
| - const v8::FunctionCallbackInfo<v8::Value>& args);
|
| + static void SendMessageToBackend(
|
| + const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| + if (args.Length() != 2 || !args[0]->IsInt32() || !args[1]->IsString()) {
|
| + fprintf(stderr,
|
| + "Internal error: sendMessageToBackend(session_id, message).");
|
| + Exit();
|
| + }
|
| + backend_runner_->Append(new SendMessageToBackendTask(
|
| + args[0].As<v8::Int32>()->Value(), ToVector(args[1].As<v8::String>())));
|
| + }
|
| };
|
|
|
| TaskRunner* UtilsExtension::backend_runner_ = nullptr;
|
| -InspectorClientImpl* UtilsExtension::inspector_client_ = nullptr;
|
|
|
| class SetTimeoutTask : public AsyncTask {
|
| public:
|
| - SetTimeoutTask(v8::Isolate* isolate, v8::Local<v8::Function> function,
|
| - const char* task_name, v8_inspector::V8Inspector* inspector)
|
| - : AsyncTask(task_name, inspector), function_(isolate, function) {}
|
| + SetTimeoutTask(IsolateData* data, int context_group_id, const char* task_name,
|
| + v8::Local<v8::Function> function)
|
| + : AsyncTask(data, task_name),
|
| + function_(data->isolate(), function),
|
| + context_group_id_(context_group_id) {}
|
| virtual ~SetTimeoutTask() {}
|
|
|
| bool is_inspector_task() final { return false; }
|
| @@ -307,7 +502,7 @@ class SetTimeoutTask : public AsyncTask {
|
| v8::MicrotasksScope microtasks_scope(isolate(),
|
| v8::MicrotasksScope::kRunMicrotasks);
|
| v8::HandleScope handle_scope(isolate());
|
| - v8::Local<v8::Context> context = default_context();
|
| + v8::Local<v8::Context> context = data()->GetContext(context_group_id_);
|
| v8::Context::Scope context_scope(context);
|
|
|
| v8::Local<v8::Function> function = function_.Get(isolate());
|
| @@ -316,6 +511,7 @@ class SetTimeoutTask : public AsyncTask {
|
| }
|
|
|
| v8::Global<v8::Function> function_;
|
| + int context_group_id_;
|
| };
|
|
|
| class SetTimeoutExtension : public IsolateData::SetupGlobalTask {
|
| @@ -332,26 +528,27 @@ class SetTimeoutExtension : public IsolateData::SetupGlobalTask {
|
| if (args.Length() != 2 || !args[1]->IsNumber() ||
|
| (!args[0]->IsFunction() && !args[0]->IsString()) ||
|
| args[1].As<v8::Number>()->Value() != 0.0) {
|
| - fprintf(stderr,
|
| - "Internal error: only setTimeout(function, 0) is supported.");
|
| + fprintf(
|
| + stderr,
|
| + "Internal error: only setTimeout(function|code, 0) is supported.");
|
| Exit();
|
| }
|
| v8::Isolate* isolate = args.GetIsolate();
|
| v8::Local<v8::Context> context = isolate->GetCurrentContext();
|
| + IsolateData* data = IsolateData::FromContext(context);
|
| + int context_group_id = data->GetContextGroupId(context);
|
| std::unique_ptr<TaskRunner::Task> task;
|
| - v8_inspector::V8Inspector* inspector =
|
| - InspectorClientImpl::InspectorFromContext(context);
|
| if (args[0]->IsFunction()) {
|
| - task.reset(new SetTimeoutTask(isolate,
|
| - v8::Local<v8::Function>::Cast(args[0]),
|
| - "setTimeout", inspector));
|
| + task.reset(new SetTimeoutTask(data, context_group_id, "setTimeout",
|
| + v8::Local<v8::Function>::Cast(args[0])));
|
| } else {
|
| task.reset(new ExecuteStringTask(
|
| + data, context_group_id, "setTimeout",
|
| ToVector(args[0].As<v8::String>()), v8::String::Empty(isolate),
|
| v8::Integer::New(isolate, 0), v8::Integer::New(isolate, 0),
|
| - v8::Boolean::New(isolate, false), "setTimeout", inspector));
|
| + v8::Boolean::New(isolate, false)));
|
| }
|
| - IsolateData::FromContext(context)->task_runner()->Append(task.release());
|
| + data->task_runner()->Append(task.release());
|
| }
|
| };
|
|
|
| @@ -368,12 +565,12 @@ class InspectorExtension : public IsolateData::SetupGlobalTask {
|
| void Run(v8::Isolate* isolate,
|
| v8::Local<v8::ObjectTemplate> global) override {
|
| v8::Local<v8::ObjectTemplate> inspector = v8::ObjectTemplate::New(isolate);
|
| - inspector->Set(
|
| - ToV8String(isolate, "attachInspector"),
|
| - v8::FunctionTemplate::New(isolate, &InspectorExtension::Attach));
|
| - inspector->Set(
|
| - ToV8String(isolate, "detachInspector"),
|
| - v8::FunctionTemplate::New(isolate, &InspectorExtension::Detach));
|
| + 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, "setMaxAsyncTaskStacks"),
|
| v8::FunctionTemplate::New(
|
| isolate, &InspectorExtension::SetMaxAsyncTaskStacks));
|
| @@ -398,29 +595,19 @@ class InspectorExtension : public IsolateData::SetupGlobalTask {
|
| }
|
|
|
| private:
|
| - static void Attach(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| - v8::Isolate* isolate = args.GetIsolate();
|
| - v8::Local<v8::Context> context = isolate->GetCurrentContext();
|
| - v8_inspector::V8Inspector* inspector =
|
| - InspectorClientImpl::InspectorFromContext(context);
|
| - if (!inspector) {
|
| - fprintf(stderr, "Inspector client not found - cannot attach!");
|
| - Exit();
|
| - }
|
| - inspector->contextCreated(
|
| - v8_inspector::V8ContextInfo(context, 1, v8_inspector::StringView()));
|
| + static void FireContextCreated(
|
| + const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| + v8::Local<v8::Context> context = args.GetIsolate()->GetCurrentContext();
|
| + IsolateData* data = IsolateData::FromContext(context);
|
| + data->inspector()->ContextCreated(context,
|
| + data->GetContextGroupId(context));
|
| }
|
|
|
| - static void Detach(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| - v8::Isolate* isolate = args.GetIsolate();
|
| - v8::Local<v8::Context> context = isolate->GetCurrentContext();
|
| - v8_inspector::V8Inspector* inspector =
|
| - InspectorClientImpl::InspectorFromContext(context);
|
| - if (!inspector) {
|
| - fprintf(stderr, "Inspector client not found - cannot detach!");
|
| - Exit();
|
| - }
|
| - inspector->contextDestroyed(context);
|
| + static void FireContextDestroyed(
|
| + const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| + v8::Local<v8::Context> context = args.GetIsolate()->GetCurrentContext();
|
| + IsolateData* data = IsolateData::FromContext(context);
|
| + data->inspector()->ContextDestroyed(context);
|
| }
|
|
|
| static void SetMaxAsyncTaskStacks(
|
| @@ -429,12 +616,11 @@ class InspectorExtension : public IsolateData::SetupGlobalTask {
|
| fprintf(stderr, "Internal error: setMaxAsyncTaskStacks(max).");
|
| Exit();
|
| }
|
| - v8_inspector::V8Inspector* inspector =
|
| - InspectorClientImpl::InspectorFromContext(
|
| - args.GetIsolate()->GetCurrentContext());
|
| - CHECK(inspector);
|
| v8_inspector::SetMaxAsyncTaskStacksForTest(
|
| - inspector, args[0].As<v8::Int32>()->Value());
|
| + IsolateData::FromContext(args.GetIsolate()->GetCurrentContext())
|
| + ->inspector()
|
| + ->inspector(),
|
| + args[0].As<v8::Int32>()->Value());
|
| }
|
|
|
| static void DumpAsyncTaskStacksStateForTest(
|
| @@ -443,11 +629,10 @@ class InspectorExtension : public IsolateData::SetupGlobalTask {
|
| fprintf(stderr, "Internal error: dumpAsyncTaskStacksStateForTest().");
|
| Exit();
|
| }
|
| - v8_inspector::V8Inspector* inspector =
|
| - InspectorClientImpl::InspectorFromContext(
|
| - args.GetIsolate()->GetCurrentContext());
|
| - CHECK(inspector);
|
| - v8_inspector::DumpAsyncTaskStacksStateForTest(inspector);
|
| + v8_inspector::DumpAsyncTaskStacksStateForTest(
|
| + IsolateData::FromContext(args.GetIsolate()->GetCurrentContext())
|
| + ->inspector()
|
| + ->inspector());
|
| }
|
|
|
| static void BreakProgram(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| @@ -455,16 +640,14 @@ class InspectorExtension : public IsolateData::SetupGlobalTask {
|
| fprintf(stderr, "Internal error: breakProgram('reason', 'details').");
|
| Exit();
|
| }
|
| - v8_inspector::V8InspectorSession* session =
|
| - InspectorClientImpl::SessionFromContext(
|
| - args.GetIsolate()->GetCurrentContext());
|
| - CHECK(session);
|
| -
|
| + v8::Local<v8::Context> context = args.GetIsolate()->GetCurrentContext();
|
| + IsolateData* data = IsolateData::FromContext(context);
|
| v8::internal::Vector<uint16_t> reason = ToVector(args[0].As<v8::String>());
|
| v8_inspector::StringView reason_view(reason.start(), reason.length());
|
| v8::internal::Vector<uint16_t> details = ToVector(args[1].As<v8::String>());
|
| v8_inspector::StringView details_view(details.start(), details.length());
|
| - session->breakProgram(reason_view, details_view);
|
| + data->inspector()->BreakProgram(data->GetContextGroupId(context),
|
| + reason_view, details_view);
|
| }
|
|
|
| static void CreateObjectWithStrictCheck(
|
| @@ -485,24 +668,23 @@ class InspectorExtension : public IsolateData::SetupGlobalTask {
|
| const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| if (args.Length() != 3 || !args[0]->IsFunction() || !args[1]->IsString() ||
|
| !args[2]->IsString()) {
|
| - fprintf(stderr, "Internal error: breakProgram('reason', 'details').");
|
| + fprintf(stderr,
|
| + "Internal error: callWithScheduledBreak('reason', 'details').");
|
| Exit();
|
| }
|
| - v8_inspector::V8InspectorSession* session =
|
| - InspectorClientImpl::SessionFromContext(
|
| - args.GetIsolate()->GetCurrentContext());
|
| - CHECK(session);
|
| -
|
| v8::internal::Vector<uint16_t> reason = ToVector(args[1].As<v8::String>());
|
| v8_inspector::StringView reason_view(reason.start(), reason.length());
|
| v8::internal::Vector<uint16_t> details = ToVector(args[2].As<v8::String>());
|
| v8_inspector::StringView details_view(details.start(), details.length());
|
| - session->schedulePauseOnNextStatement(reason_view, details_view);
|
| v8::Local<v8::Context> context = args.GetIsolate()->GetCurrentContext();
|
| + IsolateData* data = IsolateData::FromContext(context);
|
| + int context_group_id = data->GetContextGroupId(context);
|
| + data->inspector()->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);
|
| - session->cancelPauseOnNextStatement();
|
| + data->inspector()->CancelPauseOnNextStatement(context_group_id);
|
| }
|
|
|
| static void AllowAccessorFormatting(
|
| @@ -524,24 +706,6 @@ class InspectorExtension : public IsolateData::SetupGlobalTask {
|
| }
|
| };
|
|
|
| -void UtilsExtension::CreateContextGroup(
|
| - const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| - if (args.Length() != 0) {
|
| - fprintf(stderr, "Internal error: createContextGroup().");
|
| - Exit();
|
| - }
|
| - v8::base::Semaphore ready_semaphore(0);
|
| - int context_group_id = 0;
|
| - IsolateData::SetupGlobalTasks setup_global;
|
| - setup_global.emplace_back(new SetTimeoutExtension());
|
| - setup_global.emplace_back(new InspectorExtension());
|
| - inspector_client_->scheduleCreateContextGroup(
|
| - std::move(setup_global), &ready_semaphore, &context_group_id);
|
| - ready_semaphore.Wait();
|
| - args.GetReturnValue().Set(
|
| - v8::Int32::New(args.GetIsolate(), context_group_id));
|
| -}
|
| -
|
| v8::Local<v8::String> ToString(v8::Isolate* isolate,
|
| const v8_inspector::StringView& string) {
|
| if (string.is8Bit())
|
| @@ -558,11 +722,13 @@ v8::Local<v8::String> ToString(v8::Isolate* isolate,
|
|
|
| class FrontendChannelImpl : public InspectorClientImpl::FrontendChannel {
|
| public:
|
| - explicit FrontendChannelImpl(TaskRunner* frontend_task_runner)
|
| - : frontend_task_runner_(frontend_task_runner) {}
|
| + FrontendChannelImpl(TaskRunner* frontend_task_runner, int context_group_id)
|
| + : frontend_task_runner_(frontend_task_runner),
|
| + context_group_id_(context_group_id) {}
|
| virtual ~FrontendChannelImpl() {}
|
|
|
| - void SendMessageToFrontend(const v8_inspector::StringView& message) final {
|
| + void SendMessageToFrontend(int session_id,
|
| + const v8_inspector::StringView& message) final {
|
| v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
| v8::HandleScope scope(v8::Isolate::GetCurrent());
|
|
|
| @@ -571,21 +737,30 @@ class FrontendChannelImpl : public InspectorClientImpl::FrontendChannel {
|
| v8::NewStringType::kInternalized)
|
| .ToLocalChecked();
|
| v8::Local<v8::String> message_string = ToString(isolate, message);
|
| + v8::internal::Vector<char> session = v8::internal::Vector<char>::New(50);
|
| + v8::Local<v8::String> session_string =
|
| + ToV8String(isolate, v8::internal::IntToCString(session_id, session));
|
| + v8::Local<v8::String> comma =
|
| + v8::String::NewFromUtf8(isolate, ",", v8::NewStringType::kInternalized)
|
| + .ToLocalChecked();
|
| v8::Local<v8::String> suffix =
|
| v8::String::NewFromUtf8(isolate, ")", v8::NewStringType::kInternalized)
|
| .ToLocalChecked();
|
|
|
| - v8::Local<v8::String> result = v8::String::Concat(prefix, message_string);
|
| + v8::Local<v8::String> result = v8::String::Concat(prefix, session_string);
|
| + result = v8::String::Concat(result, comma);
|
| + result = v8::String::Concat(result, message_string);
|
| result = v8::String::Concat(result, suffix);
|
|
|
| frontend_task_runner_->Append(new ExecuteStringTask(
|
| - ToVector(result), v8::String::Empty(isolate),
|
| - v8::Integer::New(isolate, 0), v8::Integer::New(isolate, 0),
|
| - v8::Boolean::New(isolate, false), nullptr, nullptr));
|
| + nullptr, context_group_id_, nullptr, ToVector(result),
|
| + v8::String::Empty(isolate), v8::Integer::New(isolate, 0),
|
| + v8::Integer::New(isolate, 0), v8::Boolean::New(isolate, false)));
|
| }
|
|
|
| private:
|
| TaskRunner* frontend_task_runner_;
|
| + int context_group_id_;
|
| };
|
|
|
| } // namespace
|
| @@ -610,28 +785,27 @@ int main(int argc, char* argv[]) {
|
| }
|
| }
|
|
|
| - IsolateData::SetupGlobalTasks backend_extensions;
|
| - backend_extensions.emplace_back(new SetTimeoutExtension());
|
| - backend_extensions.emplace_back(new InspectorExtension());
|
| - TaskRunner backend_runner(std::move(backend_extensions), false,
|
| - &ready_semaphore,
|
| - startup_data.data ? &startup_data : nullptr);
|
| - ready_semaphore.Wait();
|
| - SendMessageToBackendExtension::set_backend_task_runner(&backend_runner);
|
| - UtilsExtension::set_backend_task_runner(&backend_runner);
|
| -
|
| IsolateData::SetupGlobalTasks frontend_extensions;
|
| frontend_extensions.emplace_back(new UtilsExtension());
|
| - frontend_extensions.emplace_back(new SendMessageToBackendExtension());
|
| TaskRunner frontend_runner(std::move(frontend_extensions), true,
|
| - &ready_semaphore, nullptr);
|
| + &ready_semaphore, nullptr, nullptr);
|
| + ready_semaphore.Wait();
|
| +
|
| + int frontend_context_group_id = 0;
|
| + frontend_runner.Append(
|
| + new CreateContextGroupTask(&ready_semaphore, &frontend_context_group_id));
|
| ready_semaphore.Wait();
|
|
|
| - FrontendChannelImpl frontend_channel(&frontend_runner);
|
| - InspectorClientImpl inspector_client(&backend_runner, &frontend_channel,
|
| - &ready_semaphore);
|
| + IsolateData::SetupGlobalTasks backend_extensions;
|
| + backend_extensions.emplace_back(new SetTimeoutExtension());
|
| + backend_extensions.emplace_back(new InspectorExtension());
|
| + FrontendChannelImpl frontend_channel(&frontend_runner,
|
| + frontend_context_group_id);
|
| + TaskRunner backend_runner(
|
| + std::move(backend_extensions), false, &ready_semaphore,
|
| + startup_data.data ? &startup_data : nullptr, &frontend_channel);
|
| ready_semaphore.Wait();
|
| - UtilsExtension::set_inspector_client(&inspector_client);
|
| + UtilsExtension::set_backend_task_runner(&backend_runner);
|
|
|
| task_runners.push_back(&frontend_runner);
|
| task_runners.push_back(&backend_runner);
|
| @@ -648,7 +822,8 @@ int main(int argc, char* argv[]) {
|
| argv[i]);
|
| Exit();
|
| }
|
| - frontend_runner.Append(new ExecuteStringTask(chars));
|
| + frontend_runner.Append(
|
| + new ExecuteStringTask(chars, frontend_context_group_id));
|
| }
|
|
|
| frontend_runner.Join();
|
|
|