Index: test/inspector/inspector-test.cc |
diff --git a/test/inspector/inspector-test.cc b/test/inspector/inspector-test.cc |
index f8e96ed90b2dbdf838e19490a68c66b244e64c70..2e105c54d90121aa1309ab3d9450f2397a647844 100644 |
--- a/test/inspector/inspector-test.cc |
+++ b/test/inspector/inspector-test.cc |
@@ -51,6 +51,196 @@ 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 SendMessageToFrontendTask : public TaskRunner::Task { |
+ public: |
+ SendMessageToFrontendTask(int context_group_id, int session_id, |
+ const v8::internal::Vector<uint16_t>& message) |
+ : context_group_id_(context_group_id), |
+ session_id_(session_id), |
+ message_(message) {} |
+ virtual ~SendMessageToFrontendTask() {} |
+ |
+ bool is_inspector_task() final { return false; } |
+ |
+ static void Register(int session_id, v8::Isolate* isolate, |
+ v8::Local<v8::Function> dispatcher) { |
+ dispatchers_[session_id].Reset(isolate, dispatcher); |
+ } |
+ |
+ static void Unregister(int session_id) { dispatchers_.erase(session_id); } |
+ |
+ private: |
+ void Run() override { |
+ v8::MicrotasksScope microtasks_scope(isolate(), |
+ v8::MicrotasksScope::kRunMicrotasks); |
+ v8::HandleScope handle_scope(isolate()); |
+ v8::Local<v8::Context> context = data()->GetContext(context_group_id_); |
+ v8::Context::Scope context_scope(context); |
+ |
+ if (dispatchers_.find(session_id_) == dispatchers_.end()) return; |
+ v8::Local<v8::Function> function = dispatchers_[session_id_].Get(isolate()); |
+ v8::Local<v8::Value> message = |
+ v8::String::NewFromTwoByte(isolate(), message_.start(), |
+ v8::NewStringType::kNormal, |
+ static_cast<int>(message_.size())) |
+ .ToLocalChecked(); |
+ v8::MaybeLocal<v8::Value> result; |
+ result = function->Call(context, context->Global(), 1, &message); |
+ } |
+ |
+ static std::map<int, v8::Global<v8::Function>> dispatchers_; |
+ int context_group_id_; |
+ int session_id_; |
+ v8::internal::Vector<uint16_t> message_; |
+}; |
+ |
+std::map<int, v8::Global<v8::Function>> SendMessageToFrontendTask::dispatchers_; |
+ |
class UtilsExtension : public IsolateData::SetupGlobalTask { |
public: |
~UtilsExtension() override = default; |
@@ -82,16 +272,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 +294,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 +379,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 +412,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 +422,125 @@ 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(); |
} |
- inspector_client_->session()->cancelPauseOnNextStatement(); |
+ v8::base::Semaphore ready_semaphore(0); |
+ backend_runner_->Append(new CancelPauseOnNextStatementTask( |
+ &ready_semaphore, args[0].As<v8::Int32>()->Value())); |
+ ready_semaphore.Wait(); |
} |
- static void Reconnect(const v8::FunctionCallbackInfo<v8::Value>& args) { |
+ static void SetLogConsoleApiMessageCalls( |
+ const v8::FunctionCallbackInfo<v8::Value>& args) { |
+ if (args.Length() != 1 || !args[0]->IsBoolean()) { |
+ fprintf(stderr, "Internal error: setLogConsoleApiMessageCalls(bool)."); |
+ Exit(); |
+ } |
+ backend_runner_->data()->inspector()->SetLogConsoleApiMessageCalls( |
+ args[0].As<v8::Boolean>()->Value()); |
+ } |
+ |
+ 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() != 3 || !args[0]->IsInt32() || !args[1]->IsString() || |
+ !args[2]->IsFunction()) { |
+ fprintf(stderr, |
+ "Internal error: connectionSession(context_group_id, state, " |
+ "dispatch)."); |
Exit(); |
} |
+ v8::internal::Vector<uint16_t> 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(); |
+ SendMessageToFrontendTask::Register(session_id, args.GetIsolate(), |
+ args[2].As<v8::Function>()); |
+ 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()); |
+ int session_id = args[0].As<v8::Int32>()->Value(); |
+ SendMessageToFrontendTask::Unregister(session_id); |
+ v8::base::Semaphore ready_semaphore(0); |
+ v8::internal::Vector<uint16_t> state; |
+ backend_runner_->Append( |
+ new DisconnectSessionTask(&ready_semaphore, session_id, &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 +550,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 +559,7 @@ class SetTimeoutTask : public AsyncTask { |
} |
v8::Global<v8::Function> function_; |
+ int context_group_id_; |
}; |
class SetTimeoutExtension : public IsolateData::SetupGlobalTask { |
@@ -332,26 +576,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 +613,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 +643,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 +664,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 +677,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 +688,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 +716,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,68 +754,22 @@ 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()) |
- return v8::String::NewFromOneByte(isolate, string.characters8(), |
- v8::NewStringType::kNormal, |
- static_cast<int>(string.length())) |
- .ToLocalChecked(); |
- else |
- return v8::String::NewFromTwoByte(isolate, string.characters16(), |
- v8::NewStringType::kNormal, |
- static_cast<int>(string.length())) |
- .ToLocalChecked(); |
-} |
- |
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 { |
- v8::Isolate* isolate = v8::Isolate::GetCurrent(); |
- v8::HandleScope scope(v8::Isolate::GetCurrent()); |
- |
- v8::Local<v8::String> prefix = |
- v8::String::NewFromUtf8(isolate, "InspectorTest._dispatchMessage(", |
- v8::NewStringType::kInternalized) |
- .ToLocalChecked(); |
- v8::Local<v8::String> message_string = ToString(isolate, message); |
- v8::Local<v8::String> suffix = |
- v8::String::NewFromUtf8(isolate, ")", v8::NewStringType::kInternalized) |
- .ToLocalChecked(); |
- |
- v8::Local<v8::String> result = v8::String::Concat(prefix, 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)); |
+ void SendMessageToFrontend(int session_id, |
+ const v8_inspector::StringView& message) final { |
+ frontend_task_runner_->Append(new SendMessageToFrontendTask( |
+ context_group_id_, session_id, ToVector(message))); |
} |
private: |
TaskRunner* frontend_task_runner_; |
+ int context_group_id_; |
}; |
} // namespace |
@@ -610,28 +794,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 +831,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(); |