Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(179)

Side by Side Diff: test/inspector/inspector-test.cc

Issue 2890463004: [inspector] Refactor inspector test (Closed)
Patch Set: better crash fix Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « test/inspector/inspector-impl.cc ('k') | test/inspector/isolate-data.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #if !defined(_WIN32) && !defined(_WIN64) 5 #if !defined(_WIN32) && !defined(_WIN64)
6 #include <unistd.h> // NOLINT 6 #include <unistd.h> // NOLINT
7 #endif // !defined(_WIN32) && !defined(_WIN64) 7 #endif // !defined(_WIN32) && !defined(_WIN64)
8 8
9 #include <locale.h> 9 #include <locale.h>
10 10
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 v8::internal::Vector<uint16_t>::New(str->Length()); 44 v8::internal::Vector<uint16_t>::New(str->Length());
45 str->Write(buffer.start(), 0, str->Length()); 45 str->Write(buffer.start(), 0, str->Length());
46 return buffer; 46 return buffer;
47 } 47 }
48 48
49 v8::Local<v8::String> ToV8String(v8::Isolate* isolate, const char* str) { 49 v8::Local<v8::String> ToV8String(v8::Isolate* isolate, const char* str) {
50 return v8::String::NewFromUtf8(isolate, str, v8::NewStringType::kNormal) 50 return v8::String::NewFromUtf8(isolate, str, v8::NewStringType::kNormal)
51 .ToLocalChecked(); 51 .ToLocalChecked();
52 } 52 }
53 53
54 v8::internal::Vector<uint16_t> ToVector(
55 const v8_inspector::StringView& string) {
56 v8::internal::Vector<uint16_t> buffer =
57 v8::internal::Vector<uint16_t>::New(static_cast<int>(string.length()));
58 for (size_t i = 0; i < string.length(); i++) {
59 if (string.is8Bit())
60 buffer[i] = string.characters8()[i];
61 else
62 buffer[i] = string.characters16()[i];
63 }
64 return buffer;
65 }
66
67 class CreateContextGroupTask : public TaskRunner::Task {
68 public:
69 CreateContextGroupTask(v8::base::Semaphore* ready_semaphore,
70 int* context_group_id)
71 : ready_semaphore_(ready_semaphore),
72 context_group_id_(context_group_id) {}
73 virtual ~CreateContextGroupTask() = default;
74 bool is_inspector_task() final { return true; }
75
76 private:
77 void Run() override {
78 *context_group_id_ = data()->CreateContextGroup();
79 if (ready_semaphore_) ready_semaphore_->Signal();
80 }
81
82 v8::base::Semaphore* ready_semaphore_;
83 int* context_group_id_;
84 };
85
86 class ConnectSessionTask : public TaskRunner::Task {
87 public:
88 ConnectSessionTask(v8::base::Semaphore* ready_semaphore, int context_group_id,
89 const v8::internal::Vector<uint16_t>& state,
90 int* session_id)
91 : ready_semaphore_(ready_semaphore),
92 context_group_id_(context_group_id),
93 state_(state),
94 session_id_(session_id) {}
95 virtual ~ConnectSessionTask() = default;
96 bool is_inspector_task() final { return true; }
97
98 private:
99 void Run() override {
100 v8_inspector::StringView state(state_.start(), state_.length());
101 *session_id_ =
102 data()->inspector()->ConnectSession(context_group_id_, state);
103 if (ready_semaphore_) ready_semaphore_->Signal();
104 }
105
106 v8::base::Semaphore* ready_semaphore_;
107 int context_group_id_;
108 const v8::internal::Vector<uint16_t>& state_;
109 int* session_id_;
110 };
111
112 class DisconnectSessionTask : public TaskRunner::Task {
113 public:
114 DisconnectSessionTask(v8::base::Semaphore* ready_semaphore, int session_id,
115 v8::internal::Vector<uint16_t>* state)
116 : ready_semaphore_(ready_semaphore),
117 session_id_(session_id),
118 state_(state) {}
119 virtual ~DisconnectSessionTask() = default;
120 bool is_inspector_task() final { return true; }
121
122 private:
123 void Run() override {
124 std::unique_ptr<v8_inspector::StringBuffer> state =
125 data()->inspector()->DisconnectSession(session_id_);
126 *state_ = ToVector(state->string());
127 if (ready_semaphore_) ready_semaphore_->Signal();
128 }
129
130 v8::base::Semaphore* ready_semaphore_;
131 int session_id_;
132 v8::internal::Vector<uint16_t>* state_;
133 };
134
135 class SendMessageToBackendTask : public TaskRunner::Task {
136 public:
137 explicit SendMessageToBackendTask(
138 int session_id, const v8::internal::Vector<uint16_t>& message)
139 : session_id_(session_id), message_(message) {}
140 bool is_inspector_task() final { return true; }
141
142 private:
143 void Run() override {
144 v8_inspector::StringView message_view(message_.start(), message_.length());
145 data()->inspector()->SendMessage(session_id_, message_view);
146 }
147
148 int session_id_;
149 v8::internal::Vector<uint16_t> message_;
150 };
151
152 class SchedulePauseOnNextStatementTask : public TaskRunner::Task {
153 public:
154 SchedulePauseOnNextStatementTask(
155 v8::base::Semaphore* ready_semaphore, int context_group_id,
156 const v8::internal::Vector<uint16_t>& reason,
157 const v8::internal::Vector<uint16_t>& details)
158 : ready_semaphore_(ready_semaphore),
159 context_group_id_(context_group_id),
160 reason_(reason),
161 details_(details) {}
162 virtual ~SchedulePauseOnNextStatementTask() = default;
163 bool is_inspector_task() final { return true; }
164
165 private:
166 void Run() override {
167 v8_inspector::StringView reason(reason_.start(), reason_.length());
168 v8_inspector::StringView details(details_.start(), details_.length());
169 data()->inspector()->SchedulePauseOnNextStatement(context_group_id_, reason,
170 details);
171 if (ready_semaphore_) ready_semaphore_->Signal();
172 }
173
174 v8::base::Semaphore* ready_semaphore_;
175 int context_group_id_;
176 const v8::internal::Vector<uint16_t>& reason_;
177 const v8::internal::Vector<uint16_t>& details_;
178 };
179
180 class CancelPauseOnNextStatementTask : public TaskRunner::Task {
181 public:
182 CancelPauseOnNextStatementTask(v8::base::Semaphore* ready_semaphore,
183 int context_group_id)
184 : ready_semaphore_(ready_semaphore),
185 context_group_id_(context_group_id) {}
186 virtual ~CancelPauseOnNextStatementTask() = default;
187 bool is_inspector_task() final { return true; }
188
189 private:
190 void Run() override {
191 data()->inspector()->CancelPauseOnNextStatement(context_group_id_);
192 if (ready_semaphore_) ready_semaphore_->Signal();
193 }
194
195 v8::base::Semaphore* ready_semaphore_;
196 int context_group_id_;
197 };
198
199 class SendMessageToFrontendTask : public TaskRunner::Task {
200 public:
201 SendMessageToFrontendTask(int context_group_id, int session_id,
202 const v8::internal::Vector<uint16_t>& message)
203 : context_group_id_(context_group_id),
204 session_id_(session_id),
205 message_(message) {}
206 virtual ~SendMessageToFrontendTask() {}
207
208 bool is_inspector_task() final { return false; }
209
210 static void Register(int session_id, v8::Isolate* isolate,
211 v8::Local<v8::Function> dispatcher) {
212 dispatchers_[session_id].Reset(isolate, dispatcher);
213 }
214
215 static void Unregister(int session_id) { dispatchers_.erase(session_id); }
216
217 private:
218 void Run() override {
219 v8::MicrotasksScope microtasks_scope(isolate(),
220 v8::MicrotasksScope::kRunMicrotasks);
221 v8::HandleScope handle_scope(isolate());
222 v8::Local<v8::Context> context = data()->GetContext(context_group_id_);
223 v8::Context::Scope context_scope(context);
224
225 if (dispatchers_.find(session_id_) == dispatchers_.end()) return;
226 v8::Local<v8::Function> function = dispatchers_[session_id_].Get(isolate());
227 v8::Local<v8::Value> message =
228 v8::String::NewFromTwoByte(isolate(), message_.start(),
229 v8::NewStringType::kNormal,
230 static_cast<int>(message_.size()))
231 .ToLocalChecked();
232 v8::MaybeLocal<v8::Value> result;
233 result = function->Call(context, context->Global(), 1, &message);
234 }
235
236 static std::map<int, v8::Global<v8::Function>> dispatchers_;
237 int context_group_id_;
238 int session_id_;
239 v8::internal::Vector<uint16_t> message_;
240 };
241
242 std::map<int, v8::Global<v8::Function>> SendMessageToFrontendTask::dispatchers_;
243
54 class UtilsExtension : public IsolateData::SetupGlobalTask { 244 class UtilsExtension : public IsolateData::SetupGlobalTask {
55 public: 245 public:
56 ~UtilsExtension() override = default; 246 ~UtilsExtension() override = default;
57 void Run(v8::Isolate* isolate, 247 void Run(v8::Isolate* isolate,
58 v8::Local<v8::ObjectTemplate> global) override { 248 v8::Local<v8::ObjectTemplate> global) override {
59 v8::Local<v8::ObjectTemplate> utils = v8::ObjectTemplate::New(isolate); 249 v8::Local<v8::ObjectTemplate> utils = v8::ObjectTemplate::New(isolate);
60 utils->Set(ToV8String(isolate, "print"), 250 utils->Set(ToV8String(isolate, "print"),
61 v8::FunctionTemplate::New(isolate, &UtilsExtension::Print)); 251 v8::FunctionTemplate::New(isolate, &UtilsExtension::Print));
62 utils->Set(ToV8String(isolate, "quit"), 252 utils->Set(ToV8String(isolate, "quit"),
63 v8::FunctionTemplate::New(isolate, &UtilsExtension::Quit)); 253 v8::FunctionTemplate::New(isolate, &UtilsExtension::Quit));
(...skipping 11 matching lines...) Expand all
75 isolate, &UtilsExtension::SetCurrentTimeMSForTest)); 265 isolate, &UtilsExtension::SetCurrentTimeMSForTest));
76 utils->Set(ToV8String(isolate, "setMemoryInfoForTest"), 266 utils->Set(ToV8String(isolate, "setMemoryInfoForTest"),
77 v8::FunctionTemplate::New( 267 v8::FunctionTemplate::New(
78 isolate, &UtilsExtension::SetMemoryInfoForTest)); 268 isolate, &UtilsExtension::SetMemoryInfoForTest));
79 utils->Set(ToV8String(isolate, "schedulePauseOnNextStatement"), 269 utils->Set(ToV8String(isolate, "schedulePauseOnNextStatement"),
80 v8::FunctionTemplate::New( 270 v8::FunctionTemplate::New(
81 isolate, &UtilsExtension::SchedulePauseOnNextStatement)); 271 isolate, &UtilsExtension::SchedulePauseOnNextStatement));
82 utils->Set(ToV8String(isolate, "cancelPauseOnNextStatement"), 272 utils->Set(ToV8String(isolate, "cancelPauseOnNextStatement"),
83 v8::FunctionTemplate::New( 273 v8::FunctionTemplate::New(
84 isolate, &UtilsExtension::CancelPauseOnNextStatement)); 274 isolate, &UtilsExtension::CancelPauseOnNextStatement));
85 utils->Set(ToV8String(isolate, "reconnect"),
86 v8::FunctionTemplate::New(isolate, &UtilsExtension::Reconnect));
87 utils->Set(ToV8String(isolate, "disconnect"),
88 v8::FunctionTemplate::New(isolate, &UtilsExtension::Disconnect));
89 utils->Set(ToV8String(isolate, "setLogConsoleApiMessageCalls"), 275 utils->Set(ToV8String(isolate, "setLogConsoleApiMessageCalls"),
90 v8::FunctionTemplate::New( 276 v8::FunctionTemplate::New(
91 isolate, &UtilsExtension::SetLogConsoleApiMessageCalls)); 277 isolate, &UtilsExtension::SetLogConsoleApiMessageCalls));
92 utils->Set(ToV8String(isolate, "createContextGroup"), 278 utils->Set(ToV8String(isolate, "createContextGroup"),
93 v8::FunctionTemplate::New(isolate, 279 v8::FunctionTemplate::New(isolate,
94 &UtilsExtension::CreateContextGroup)); 280 &UtilsExtension::CreateContextGroup));
281 utils->Set(
282 ToV8String(isolate, "connectSession"),
283 v8::FunctionTemplate::New(isolate, &UtilsExtension::ConnectSession));
284 utils->Set(
285 ToV8String(isolate, "disconnectSession"),
286 v8::FunctionTemplate::New(isolate, &UtilsExtension::DisconnectSession));
287 utils->Set(ToV8String(isolate, "sendMessageToBackend"),
288 v8::FunctionTemplate::New(
289 isolate, &UtilsExtension::SendMessageToBackend));
95 global->Set(ToV8String(isolate, "utils"), utils); 290 global->Set(ToV8String(isolate, "utils"), utils);
96 } 291 }
97 292
98 static void set_backend_task_runner(TaskRunner* runner) { 293 static void set_backend_task_runner(TaskRunner* runner) {
99 backend_runner_ = runner; 294 backend_runner_ = runner;
100 } 295 }
101 296
102 static void set_inspector_client(InspectorClientImpl* client) {
103 inspector_client_ = client;
104 }
105
106 private: 297 private:
107 static TaskRunner* backend_runner_; 298 static TaskRunner* backend_runner_;
108 static InspectorClientImpl* inspector_client_;
109 299
110 static void Print(const v8::FunctionCallbackInfo<v8::Value>& args) { 300 static void Print(const v8::FunctionCallbackInfo<v8::Value>& args) {
111 for (int i = 0; i < args.Length(); i++) { 301 for (int i = 0; i < args.Length(); i++) {
112 v8::HandleScope handle_scope(args.GetIsolate()); 302 v8::HandleScope handle_scope(args.GetIsolate());
113 if (i != 0) { 303 if (i != 0) {
114 printf(" "); 304 printf(" ");
115 } 305 }
116 306
117 // Explicitly catch potential exceptions in toString(). 307 // Explicitly catch potential exceptions in toString().
118 v8::TryCatch try_catch(args.GetIsolate()); 308 v8::TryCatch try_catch(args.GetIsolate());
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 } 372 }
183 } 373 }
184 374
185 static void Load(const v8::FunctionCallbackInfo<v8::Value>& args) { 375 static void Load(const v8::FunctionCallbackInfo<v8::Value>& args) {
186 if (args.Length() != 1 || !args[0]->IsString()) { 376 if (args.Length() != 1 || !args[0]->IsString()) {
187 fprintf(stderr, "Internal error: load gets one string argument."); 377 fprintf(stderr, "Internal error: load gets one string argument.");
188 Exit(); 378 Exit();
189 } 379 }
190 v8::internal::Vector<const char> chars; 380 v8::internal::Vector<const char> chars;
191 v8::Isolate* isolate = args.GetIsolate(); 381 v8::Isolate* isolate = args.GetIsolate();
382 v8::Local<v8::Context> context = isolate->GetCurrentContext();
383 IsolateData* data = IsolateData::FromContext(context);
384 int context_group_id = data->GetContextGroupId(context);
192 if (ReadFile(isolate, args[0], &chars)) { 385 if (ReadFile(isolate, args[0], &chars)) {
193 ExecuteStringTask(chars).RunOnTaskRunner( 386 ExecuteStringTask(chars, context_group_id).RunOnIsolate(data);
194 IsolateData::FromContext(isolate->GetCurrentContext())
195 ->task_runner());
196 } 387 }
197 } 388 }
198 389
199 static void CompileAndRunWithOrigin( 390 static void CompileAndRunWithOrigin(
200 const v8::FunctionCallbackInfo<v8::Value>& args) { 391 const v8::FunctionCallbackInfo<v8::Value>& args) {
201 if (args.Length() != 5 || !args[0]->IsString() || !args[1]->IsString() || 392 if (args.Length() != 6 || !args[0]->IsInt32() || !args[1]->IsString() ||
202 !args[2]->IsInt32() || !args[3]->IsInt32() || !args[4]->IsBoolean()) { 393 !args[2]->IsString() || !args[3]->IsInt32() || !args[4]->IsInt32() ||
394 !args[5]->IsBoolean()) {
203 fprintf(stderr, 395 fprintf(stderr,
204 "Internal error: compileAndRunWithOrigin(source, name, line, " 396 "Internal error: compileAndRunWithOrigin(context_group_id, "
397 "source, name, line, "
205 "column, is_module)."); 398 "column, is_module).");
206 Exit(); 399 Exit();
207 } 400 }
208 401
209 backend_runner_->Append(new ExecuteStringTask( 402 backend_runner_->Append(new ExecuteStringTask(
210 ToVector(args[0].As<v8::String>()), args[1].As<v8::String>(), 403 nullptr, args[0].As<v8::Int32>()->Value(), nullptr,
211 args[2].As<v8::Int32>(), args[3].As<v8::Int32>(), 404 ToVector(args[1].As<v8::String>()), args[2].As<v8::String>(),
212 args[4].As<v8::Boolean>(), nullptr, nullptr)); 405 args[3].As<v8::Int32>(), args[4].As<v8::Int32>(),
406 args[5].As<v8::Boolean>()));
213 } 407 }
214 408
215 static void SetCurrentTimeMSForTest( 409 static void SetCurrentTimeMSForTest(
216 const v8::FunctionCallbackInfo<v8::Value>& args) { 410 const v8::FunctionCallbackInfo<v8::Value>& args) {
217 if (args.Length() != 1 || !args[0]->IsNumber()) { 411 if (args.Length() != 1 || !args[0]->IsNumber()) {
218 fprintf(stderr, "Internal error: setCurrentTimeMSForTest(time)."); 412 fprintf(stderr, "Internal error: setCurrentTimeMSForTest(time).");
219 Exit(); 413 Exit();
220 } 414 }
221 inspector_client_->setCurrentTimeMSForTest( 415 backend_runner_->data()->inspector()->SetCurrentTimeMSForTest(
222 args[0].As<v8::Number>()->Value()); 416 args[0].As<v8::Number>()->Value());
223 } 417 }
224 418
225 static void SetMemoryInfoForTest( 419 static void SetMemoryInfoForTest(
226 const v8::FunctionCallbackInfo<v8::Value>& args) { 420 const v8::FunctionCallbackInfo<v8::Value>& args) {
227 if (args.Length() != 1) { 421 if (args.Length() != 1) {
228 fprintf(stderr, "Internal error: setMemoryInfoForTest(value)."); 422 fprintf(stderr, "Internal error: setMemoryInfoForTest(value).");
229 Exit(); 423 Exit();
230 } 424 }
231 inspector_client_->setMemoryInfoForTest(args[0]); 425 backend_runner_->data()->inspector()->SetMemoryInfoForTest(args[0]);
232 } 426 }
233 427
234 static void SchedulePauseOnNextStatement( 428 static void SchedulePauseOnNextStatement(
235 const v8::FunctionCallbackInfo<v8::Value>& args) { 429 const v8::FunctionCallbackInfo<v8::Value>& args) {
236 if (args.Length() != 2 || !args[0]->IsString() || !args[1]->IsString()) { 430 if (args.Length() != 3 || !args[0]->IsInt32() || !args[1]->IsString() ||
237 fprintf( 431 !args[2]->IsString()) {
238 stderr, 432 fprintf(stderr,
239 "Internal error: schedulePauseOnNextStatement('reason', 'details')."); 433 "Internal error: schedulePauseOnNextStatement(context_group_id, "
434 "'reason', 'details').");
240 Exit(); 435 Exit();
241 } 436 }
242 v8::internal::Vector<uint16_t> reason = ToVector(args[0].As<v8::String>()); 437 v8::internal::Vector<uint16_t> reason = ToVector(args[1].As<v8::String>());
243 v8_inspector::StringView reason_view(reason.start(), reason.length()); 438 v8::internal::Vector<uint16_t> details = ToVector(args[2].As<v8::String>());
244 v8::internal::Vector<uint16_t> details = ToVector(args[1].As<v8::String>()); 439 v8::base::Semaphore ready_semaphore(0);
245 v8_inspector::StringView details_view(details.start(), details.length()); 440 backend_runner_->Append(new SchedulePauseOnNextStatementTask(
246 inspector_client_->session()->schedulePauseOnNextStatement(reason_view, 441 &ready_semaphore, args[0].As<v8::Int32>()->Value(), reason, details));
247 details_view); 442 ready_semaphore.Wait();
248 } 443 }
249 444
250 static void CancelPauseOnNextStatement( 445 static void CancelPauseOnNextStatement(
251 const v8::FunctionCallbackInfo<v8::Value>& args) { 446 const v8::FunctionCallbackInfo<v8::Value>& args) {
252 if (args.Length() != 0) { 447 if (args.Length() != 1 || !args[0]->IsInt32()) {
253 fprintf(stderr, "Internal error: cancelPauseOnNextStatement()."); 448 fprintf(stderr,
254 Exit(); 449 "Internal error: cancelPauseOnNextStatement(context_group_id).");
255 }
256 inspector_client_->session()->cancelPauseOnNextStatement();
257 }
258
259 static void Reconnect(const v8::FunctionCallbackInfo<v8::Value>& args) {
260 if (args.Length() != 0) {
261 fprintf(stderr, "Internal error: reconnect().");
262 Exit(); 450 Exit();
263 } 451 }
264 v8::base::Semaphore ready_semaphore(0); 452 v8::base::Semaphore ready_semaphore(0);
265 inspector_client_->scheduleReconnect(&ready_semaphore); 453 backend_runner_->Append(new CancelPauseOnNextStatementTask(
266 ready_semaphore.Wait(); 454 &ready_semaphore, args[0].As<v8::Int32>()->Value()));
267 }
268
269 static void Disconnect(const v8::FunctionCallbackInfo<v8::Value>& args) {
270 if (args.Length() != 0) {
271 fprintf(stderr, "Internal error: disconnect().");
272 Exit();
273 }
274 v8::base::Semaphore ready_semaphore(0);
275 inspector_client_->scheduleDisconnect(&ready_semaphore);
276 ready_semaphore.Wait(); 455 ready_semaphore.Wait();
277 } 456 }
278 457
279 static void SetLogConsoleApiMessageCalls( 458 static void SetLogConsoleApiMessageCalls(
280 const v8::FunctionCallbackInfo<v8::Value>& args) { 459 const v8::FunctionCallbackInfo<v8::Value>& args) {
281 if (args.Length() != 1 || !args[0]->IsBoolean()) { 460 if (args.Length() != 1 || !args[0]->IsBoolean()) {
282 fprintf(stderr, "Internal error: setLogConsoleApiMessageCalls(bool)."); 461 fprintf(stderr, "Internal error: setLogConsoleApiMessageCalls(bool).");
283 Exit(); 462 Exit();
284 } 463 }
285 inspector_client_->setLogConsoleApiMessageCalls( 464 backend_runner_->data()->inspector()->SetLogConsoleApiMessageCalls(
286 args[0].As<v8::Boolean>()->Value()); 465 args[0].As<v8::Boolean>()->Value());
287 } 466 }
288 467
289 static void CreateContextGroup( 468 static void CreateContextGroup(
290 const v8::FunctionCallbackInfo<v8::Value>& args); 469 const v8::FunctionCallbackInfo<v8::Value>& args) {
470 if (args.Length() != 0) {
471 fprintf(stderr, "Internal error: createContextGroup().");
472 Exit();
473 }
474 v8::base::Semaphore ready_semaphore(0);
475 int context_group_id = 0;
476 backend_runner_->Append(
477 new CreateContextGroupTask(&ready_semaphore, &context_group_id));
478 ready_semaphore.Wait();
479 args.GetReturnValue().Set(
480 v8::Int32::New(args.GetIsolate(), context_group_id));
481 }
482
483 static void ConnectSession(const v8::FunctionCallbackInfo<v8::Value>& args) {
484 if (args.Length() != 3 || !args[0]->IsInt32() || !args[1]->IsString() ||
485 !args[2]->IsFunction()) {
486 fprintf(stderr,
487 "Internal error: connectionSession(context_group_id, state, "
488 "dispatch).");
489 Exit();
490 }
491 v8::internal::Vector<uint16_t> state = ToVector(args[1].As<v8::String>());
492 v8::base::Semaphore ready_semaphore(0);
493 int session_id = 0;
494 backend_runner_->Append(new ConnectSessionTask(
495 &ready_semaphore, args[0].As<v8::Int32>()->Value(), state,
496 &session_id));
497 ready_semaphore.Wait();
498 SendMessageToFrontendTask::Register(session_id, args.GetIsolate(),
499 args[2].As<v8::Function>());
500 args.GetReturnValue().Set(v8::Int32::New(args.GetIsolate(), session_id));
501 }
502
503 static void DisconnectSession(
504 const v8::FunctionCallbackInfo<v8::Value>& args) {
505 if (args.Length() != 1 || !args[0]->IsInt32()) {
506 fprintf(stderr, "Internal error: disconnectionSession(session_id).");
507 Exit();
508 }
509 int session_id = args[0].As<v8::Int32>()->Value();
510 SendMessageToFrontendTask::Unregister(session_id);
511 v8::base::Semaphore ready_semaphore(0);
512 v8::internal::Vector<uint16_t> state;
513 backend_runner_->Append(
514 new DisconnectSessionTask(&ready_semaphore, session_id, &state));
515 ready_semaphore.Wait();
516 args.GetReturnValue().Set(
517 v8::String::NewFromTwoByte(args.GetIsolate(), state.start(),
518 v8::NewStringType::kNormal,
519 static_cast<int>(state.size()))
520 .ToLocalChecked());
521 }
522
523 static void SendMessageToBackend(
524 const v8::FunctionCallbackInfo<v8::Value>& args) {
525 if (args.Length() != 2 || !args[0]->IsInt32() || !args[1]->IsString()) {
526 fprintf(stderr,
527 "Internal error: sendMessageToBackend(session_id, message).");
528 Exit();
529 }
530 backend_runner_->Append(new SendMessageToBackendTask(
531 args[0].As<v8::Int32>()->Value(), ToVector(args[1].As<v8::String>())));
532 }
291 }; 533 };
292 534
293 TaskRunner* UtilsExtension::backend_runner_ = nullptr; 535 TaskRunner* UtilsExtension::backend_runner_ = nullptr;
294 InspectorClientImpl* UtilsExtension::inspector_client_ = nullptr;
295 536
296 class SetTimeoutTask : public AsyncTask { 537 class SetTimeoutTask : public AsyncTask {
297 public: 538 public:
298 SetTimeoutTask(v8::Isolate* isolate, v8::Local<v8::Function> function, 539 SetTimeoutTask(IsolateData* data, int context_group_id, const char* task_name,
299 const char* task_name, v8_inspector::V8Inspector* inspector) 540 v8::Local<v8::Function> function)
300 : AsyncTask(task_name, inspector), function_(isolate, function) {} 541 : AsyncTask(data, task_name),
542 function_(data->isolate(), function),
543 context_group_id_(context_group_id) {}
301 virtual ~SetTimeoutTask() {} 544 virtual ~SetTimeoutTask() {}
302 545
303 bool is_inspector_task() final { return false; } 546 bool is_inspector_task() final { return false; }
304 547
305 private: 548 private:
306 void AsyncRun() override { 549 void AsyncRun() override {
307 v8::MicrotasksScope microtasks_scope(isolate(), 550 v8::MicrotasksScope microtasks_scope(isolate(),
308 v8::MicrotasksScope::kRunMicrotasks); 551 v8::MicrotasksScope::kRunMicrotasks);
309 v8::HandleScope handle_scope(isolate()); 552 v8::HandleScope handle_scope(isolate());
310 v8::Local<v8::Context> context = default_context(); 553 v8::Local<v8::Context> context = data()->GetContext(context_group_id_);
311 v8::Context::Scope context_scope(context); 554 v8::Context::Scope context_scope(context);
312 555
313 v8::Local<v8::Function> function = function_.Get(isolate()); 556 v8::Local<v8::Function> function = function_.Get(isolate());
314 v8::MaybeLocal<v8::Value> result; 557 v8::MaybeLocal<v8::Value> result;
315 result = function->Call(context, context->Global(), 0, nullptr); 558 result = function->Call(context, context->Global(), 0, nullptr);
316 } 559 }
317 560
318 v8::Global<v8::Function> function_; 561 v8::Global<v8::Function> function_;
562 int context_group_id_;
319 }; 563 };
320 564
321 class SetTimeoutExtension : public IsolateData::SetupGlobalTask { 565 class SetTimeoutExtension : public IsolateData::SetupGlobalTask {
322 public: 566 public:
323 void Run(v8::Isolate* isolate, 567 void Run(v8::Isolate* isolate,
324 v8::Local<v8::ObjectTemplate> global) override { 568 v8::Local<v8::ObjectTemplate> global) override {
325 global->Set( 569 global->Set(
326 ToV8String(isolate, "setTimeout"), 570 ToV8String(isolate, "setTimeout"),
327 v8::FunctionTemplate::New(isolate, &SetTimeoutExtension::SetTimeout)); 571 v8::FunctionTemplate::New(isolate, &SetTimeoutExtension::SetTimeout));
328 } 572 }
329 573
330 private: 574 private:
331 static void SetTimeout(const v8::FunctionCallbackInfo<v8::Value>& args) { 575 static void SetTimeout(const v8::FunctionCallbackInfo<v8::Value>& args) {
332 if (args.Length() != 2 || !args[1]->IsNumber() || 576 if (args.Length() != 2 || !args[1]->IsNumber() ||
333 (!args[0]->IsFunction() && !args[0]->IsString()) || 577 (!args[0]->IsFunction() && !args[0]->IsString()) ||
334 args[1].As<v8::Number>()->Value() != 0.0) { 578 args[1].As<v8::Number>()->Value() != 0.0) {
335 fprintf(stderr, 579 fprintf(
336 "Internal error: only setTimeout(function, 0) is supported."); 580 stderr,
581 "Internal error: only setTimeout(function|code, 0) is supported.");
337 Exit(); 582 Exit();
338 } 583 }
339 v8::Isolate* isolate = args.GetIsolate(); 584 v8::Isolate* isolate = args.GetIsolate();
340 v8::Local<v8::Context> context = isolate->GetCurrentContext(); 585 v8::Local<v8::Context> context = isolate->GetCurrentContext();
586 IsolateData* data = IsolateData::FromContext(context);
587 int context_group_id = data->GetContextGroupId(context);
341 std::unique_ptr<TaskRunner::Task> task; 588 std::unique_ptr<TaskRunner::Task> task;
342 v8_inspector::V8Inspector* inspector =
343 InspectorClientImpl::InspectorFromContext(context);
344 if (args[0]->IsFunction()) { 589 if (args[0]->IsFunction()) {
345 task.reset(new SetTimeoutTask(isolate, 590 task.reset(new SetTimeoutTask(data, context_group_id, "setTimeout",
346 v8::Local<v8::Function>::Cast(args[0]), 591 v8::Local<v8::Function>::Cast(args[0])));
347 "setTimeout", inspector));
348 } else { 592 } else {
349 task.reset(new ExecuteStringTask( 593 task.reset(new ExecuteStringTask(
594 data, context_group_id, "setTimeout",
350 ToVector(args[0].As<v8::String>()), v8::String::Empty(isolate), 595 ToVector(args[0].As<v8::String>()), v8::String::Empty(isolate),
351 v8::Integer::New(isolate, 0), v8::Integer::New(isolate, 0), 596 v8::Integer::New(isolate, 0), v8::Integer::New(isolate, 0),
352 v8::Boolean::New(isolate, false), "setTimeout", inspector)); 597 v8::Boolean::New(isolate, false)));
353 } 598 }
354 IsolateData::FromContext(context)->task_runner()->Append(task.release()); 599 data->task_runner()->Append(task.release());
355 } 600 }
356 }; 601 };
357 602
358 bool StrictAccessCheck(v8::Local<v8::Context> accessing_context, 603 bool StrictAccessCheck(v8::Local<v8::Context> accessing_context,
359 v8::Local<v8::Object> accessed_object, 604 v8::Local<v8::Object> accessed_object,
360 v8::Local<v8::Value> data) { 605 v8::Local<v8::Value> data) {
361 CHECK(accessing_context.IsEmpty()); 606 CHECK(accessing_context.IsEmpty());
362 return accessing_context.IsEmpty(); 607 return accessing_context.IsEmpty();
363 } 608 }
364 609
365 class InspectorExtension : public IsolateData::SetupGlobalTask { 610 class InspectorExtension : public IsolateData::SetupGlobalTask {
366 public: 611 public:
367 ~InspectorExtension() override = default; 612 ~InspectorExtension() override = default;
368 void Run(v8::Isolate* isolate, 613 void Run(v8::Isolate* isolate,
369 v8::Local<v8::ObjectTemplate> global) override { 614 v8::Local<v8::ObjectTemplate> global) override {
370 v8::Local<v8::ObjectTemplate> inspector = v8::ObjectTemplate::New(isolate); 615 v8::Local<v8::ObjectTemplate> inspector = v8::ObjectTemplate::New(isolate);
371 inspector->Set( 616 inspector->Set(ToV8String(isolate, "fireContextCreated"),
372 ToV8String(isolate, "attachInspector"), 617 v8::FunctionTemplate::New(
373 v8::FunctionTemplate::New(isolate, &InspectorExtension::Attach)); 618 isolate, &InspectorExtension::FireContextCreated));
374 inspector->Set( 619 inspector->Set(ToV8String(isolate, "fireContextDestroyed"),
375 ToV8String(isolate, "detachInspector"), 620 v8::FunctionTemplate::New(
376 v8::FunctionTemplate::New(isolate, &InspectorExtension::Detach)); 621 isolate, &InspectorExtension::FireContextDestroyed));
377 inspector->Set(ToV8String(isolate, "setMaxAsyncTaskStacks"), 622 inspector->Set(ToV8String(isolate, "setMaxAsyncTaskStacks"),
378 v8::FunctionTemplate::New( 623 v8::FunctionTemplate::New(
379 isolate, &InspectorExtension::SetMaxAsyncTaskStacks)); 624 isolate, &InspectorExtension::SetMaxAsyncTaskStacks));
380 inspector->Set( 625 inspector->Set(
381 ToV8String(isolate, "dumpAsyncTaskStacksStateForTest"), 626 ToV8String(isolate, "dumpAsyncTaskStacksStateForTest"),
382 v8::FunctionTemplate::New( 627 v8::FunctionTemplate::New(
383 isolate, &InspectorExtension::DumpAsyncTaskStacksStateForTest)); 628 isolate, &InspectorExtension::DumpAsyncTaskStacksStateForTest));
384 inspector->Set( 629 inspector->Set(
385 ToV8String(isolate, "breakProgram"), 630 ToV8String(isolate, "breakProgram"),
386 v8::FunctionTemplate::New(isolate, &InspectorExtension::BreakProgram)); 631 v8::FunctionTemplate::New(isolate, &InspectorExtension::BreakProgram));
387 inspector->Set( 632 inspector->Set(
388 ToV8String(isolate, "createObjectWithStrictCheck"), 633 ToV8String(isolate, "createObjectWithStrictCheck"),
389 v8::FunctionTemplate::New( 634 v8::FunctionTemplate::New(
390 isolate, &InspectorExtension::CreateObjectWithStrictCheck)); 635 isolate, &InspectorExtension::CreateObjectWithStrictCheck));
391 inspector->Set(ToV8String(isolate, "callWithScheduledBreak"), 636 inspector->Set(ToV8String(isolate, "callWithScheduledBreak"),
392 v8::FunctionTemplate::New( 637 v8::FunctionTemplate::New(
393 isolate, &InspectorExtension::CallWithScheduledBreak)); 638 isolate, &InspectorExtension::CallWithScheduledBreak));
394 inspector->Set(ToV8String(isolate, "allowAccessorFormatting"), 639 inspector->Set(ToV8String(isolate, "allowAccessorFormatting"),
395 v8::FunctionTemplate::New( 640 v8::FunctionTemplate::New(
396 isolate, &InspectorExtension::AllowAccessorFormatting)); 641 isolate, &InspectorExtension::AllowAccessorFormatting));
397 global->Set(ToV8String(isolate, "inspector"), inspector); 642 global->Set(ToV8String(isolate, "inspector"), inspector);
398 } 643 }
399 644
400 private: 645 private:
401 static void Attach(const v8::FunctionCallbackInfo<v8::Value>& args) { 646 static void FireContextCreated(
402 v8::Isolate* isolate = args.GetIsolate(); 647 const v8::FunctionCallbackInfo<v8::Value>& args) {
403 v8::Local<v8::Context> context = isolate->GetCurrentContext(); 648 v8::Local<v8::Context> context = args.GetIsolate()->GetCurrentContext();
404 v8_inspector::V8Inspector* inspector = 649 IsolateData* data = IsolateData::FromContext(context);
405 InspectorClientImpl::InspectorFromContext(context); 650 data->inspector()->ContextCreated(context,
406 if (!inspector) { 651 data->GetContextGroupId(context));
407 fprintf(stderr, "Inspector client not found - cannot attach!");
408 Exit();
409 }
410 inspector->contextCreated(
411 v8_inspector::V8ContextInfo(context, 1, v8_inspector::StringView()));
412 } 652 }
413 653
414 static void Detach(const v8::FunctionCallbackInfo<v8::Value>& args) { 654 static void FireContextDestroyed(
415 v8::Isolate* isolate = args.GetIsolate(); 655 const v8::FunctionCallbackInfo<v8::Value>& args) {
416 v8::Local<v8::Context> context = isolate->GetCurrentContext(); 656 v8::Local<v8::Context> context = args.GetIsolate()->GetCurrentContext();
417 v8_inspector::V8Inspector* inspector = 657 IsolateData* data = IsolateData::FromContext(context);
418 InspectorClientImpl::InspectorFromContext(context); 658 data->inspector()->ContextDestroyed(context);
419 if (!inspector) {
420 fprintf(stderr, "Inspector client not found - cannot detach!");
421 Exit();
422 }
423 inspector->contextDestroyed(context);
424 } 659 }
425 660
426 static void SetMaxAsyncTaskStacks( 661 static void SetMaxAsyncTaskStacks(
427 const v8::FunctionCallbackInfo<v8::Value>& args) { 662 const v8::FunctionCallbackInfo<v8::Value>& args) {
428 if (args.Length() != 1 || !args[0]->IsInt32()) { 663 if (args.Length() != 1 || !args[0]->IsInt32()) {
429 fprintf(stderr, "Internal error: setMaxAsyncTaskStacks(max)."); 664 fprintf(stderr, "Internal error: setMaxAsyncTaskStacks(max).");
430 Exit(); 665 Exit();
431 } 666 }
432 v8_inspector::V8Inspector* inspector =
433 InspectorClientImpl::InspectorFromContext(
434 args.GetIsolate()->GetCurrentContext());
435 CHECK(inspector);
436 v8_inspector::SetMaxAsyncTaskStacksForTest( 667 v8_inspector::SetMaxAsyncTaskStacksForTest(
437 inspector, args[0].As<v8::Int32>()->Value()); 668 IsolateData::FromContext(args.GetIsolate()->GetCurrentContext())
669 ->inspector()
670 ->inspector(),
671 args[0].As<v8::Int32>()->Value());
438 } 672 }
439 673
440 static void DumpAsyncTaskStacksStateForTest( 674 static void DumpAsyncTaskStacksStateForTest(
441 const v8::FunctionCallbackInfo<v8::Value>& args) { 675 const v8::FunctionCallbackInfo<v8::Value>& args) {
442 if (args.Length() != 0) { 676 if (args.Length() != 0) {
443 fprintf(stderr, "Internal error: dumpAsyncTaskStacksStateForTest()."); 677 fprintf(stderr, "Internal error: dumpAsyncTaskStacksStateForTest().");
444 Exit(); 678 Exit();
445 } 679 }
446 v8_inspector::V8Inspector* inspector = 680 v8_inspector::DumpAsyncTaskStacksStateForTest(
447 InspectorClientImpl::InspectorFromContext( 681 IsolateData::FromContext(args.GetIsolate()->GetCurrentContext())
448 args.GetIsolate()->GetCurrentContext()); 682 ->inspector()
449 CHECK(inspector); 683 ->inspector());
450 v8_inspector::DumpAsyncTaskStacksStateForTest(inspector);
451 } 684 }
452 685
453 static void BreakProgram(const v8::FunctionCallbackInfo<v8::Value>& args) { 686 static void BreakProgram(const v8::FunctionCallbackInfo<v8::Value>& args) {
454 if (args.Length() != 2 || !args[0]->IsString() || !args[1]->IsString()) { 687 if (args.Length() != 2 || !args[0]->IsString() || !args[1]->IsString()) {
455 fprintf(stderr, "Internal error: breakProgram('reason', 'details')."); 688 fprintf(stderr, "Internal error: breakProgram('reason', 'details').");
456 Exit(); 689 Exit();
457 } 690 }
458 v8_inspector::V8InspectorSession* session = 691 v8::Local<v8::Context> context = args.GetIsolate()->GetCurrentContext();
459 InspectorClientImpl::SessionFromContext( 692 IsolateData* data = IsolateData::FromContext(context);
460 args.GetIsolate()->GetCurrentContext());
461 CHECK(session);
462
463 v8::internal::Vector<uint16_t> reason = ToVector(args[0].As<v8::String>()); 693 v8::internal::Vector<uint16_t> reason = ToVector(args[0].As<v8::String>());
464 v8_inspector::StringView reason_view(reason.start(), reason.length()); 694 v8_inspector::StringView reason_view(reason.start(), reason.length());
465 v8::internal::Vector<uint16_t> details = ToVector(args[1].As<v8::String>()); 695 v8::internal::Vector<uint16_t> details = ToVector(args[1].As<v8::String>());
466 v8_inspector::StringView details_view(details.start(), details.length()); 696 v8_inspector::StringView details_view(details.start(), details.length());
467 session->breakProgram(reason_view, details_view); 697 data->inspector()->BreakProgram(data->GetContextGroupId(context),
698 reason_view, details_view);
468 } 699 }
469 700
470 static void CreateObjectWithStrictCheck( 701 static void CreateObjectWithStrictCheck(
471 const v8::FunctionCallbackInfo<v8::Value>& args) { 702 const v8::FunctionCallbackInfo<v8::Value>& args) {
472 if (args.Length() != 0) { 703 if (args.Length() != 0) {
473 fprintf(stderr, "Internal error: createObjectWithStrictCheck()."); 704 fprintf(stderr, "Internal error: createObjectWithStrictCheck().");
474 Exit(); 705 Exit();
475 } 706 }
476 v8::Local<v8::ObjectTemplate> templ = 707 v8::Local<v8::ObjectTemplate> templ =
477 v8::ObjectTemplate::New(args.GetIsolate()); 708 v8::ObjectTemplate::New(args.GetIsolate());
478 templ->SetAccessCheckCallback(&StrictAccessCheck); 709 templ->SetAccessCheckCallback(&StrictAccessCheck);
479 args.GetReturnValue().Set( 710 args.GetReturnValue().Set(
480 templ->NewInstance(args.GetIsolate()->GetCurrentContext()) 711 templ->NewInstance(args.GetIsolate()->GetCurrentContext())
481 .ToLocalChecked()); 712 .ToLocalChecked());
482 } 713 }
483 714
484 static void CallWithScheduledBreak( 715 static void CallWithScheduledBreak(
485 const v8::FunctionCallbackInfo<v8::Value>& args) { 716 const v8::FunctionCallbackInfo<v8::Value>& args) {
486 if (args.Length() != 3 || !args[0]->IsFunction() || !args[1]->IsString() || 717 if (args.Length() != 3 || !args[0]->IsFunction() || !args[1]->IsString() ||
487 !args[2]->IsString()) { 718 !args[2]->IsString()) {
488 fprintf(stderr, "Internal error: breakProgram('reason', 'details')."); 719 fprintf(stderr,
720 "Internal error: callWithScheduledBreak('reason', 'details').");
489 Exit(); 721 Exit();
490 } 722 }
491 v8_inspector::V8InspectorSession* session =
492 InspectorClientImpl::SessionFromContext(
493 args.GetIsolate()->GetCurrentContext());
494 CHECK(session);
495
496 v8::internal::Vector<uint16_t> reason = ToVector(args[1].As<v8::String>()); 723 v8::internal::Vector<uint16_t> reason = ToVector(args[1].As<v8::String>());
497 v8_inspector::StringView reason_view(reason.start(), reason.length()); 724 v8_inspector::StringView reason_view(reason.start(), reason.length());
498 v8::internal::Vector<uint16_t> details = ToVector(args[2].As<v8::String>()); 725 v8::internal::Vector<uint16_t> details = ToVector(args[2].As<v8::String>());
499 v8_inspector::StringView details_view(details.start(), details.length()); 726 v8_inspector::StringView details_view(details.start(), details.length());
500 session->schedulePauseOnNextStatement(reason_view, details_view);
501 v8::Local<v8::Context> context = args.GetIsolate()->GetCurrentContext(); 727 v8::Local<v8::Context> context = args.GetIsolate()->GetCurrentContext();
728 IsolateData* data = IsolateData::FromContext(context);
729 int context_group_id = data->GetContextGroupId(context);
730 data->inspector()->SchedulePauseOnNextStatement(context_group_id,
731 reason_view, details_view);
502 v8::MaybeLocal<v8::Value> result; 732 v8::MaybeLocal<v8::Value> result;
503 result = args[0].As<v8::Function>()->Call(context, context->Global(), 0, 733 result = args[0].As<v8::Function>()->Call(context, context->Global(), 0,
504 nullptr); 734 nullptr);
505 session->cancelPauseOnNextStatement(); 735 data->inspector()->CancelPauseOnNextStatement(context_group_id);
506 } 736 }
507 737
508 static void AllowAccessorFormatting( 738 static void AllowAccessorFormatting(
509 const v8::FunctionCallbackInfo<v8::Value>& args) { 739 const v8::FunctionCallbackInfo<v8::Value>& args) {
510 if (args.Length() != 1 || !args[0]->IsObject()) { 740 if (args.Length() != 1 || !args[0]->IsObject()) {
511 fprintf(stderr, "Internal error: allowAccessorFormatting('object')."); 741 fprintf(stderr, "Internal error: allowAccessorFormatting('object').");
512 Exit(); 742 Exit();
513 } 743 }
514 v8::Local<v8::Object> object = args[0].As<v8::Object>(); 744 v8::Local<v8::Object> object = args[0].As<v8::Object>();
515 v8::Isolate* isolate = args.GetIsolate(); 745 v8::Isolate* isolate = args.GetIsolate();
516 v8::Local<v8::Private> shouldFormatAccessorsPrivate = v8::Private::ForApi( 746 v8::Local<v8::Private> shouldFormatAccessorsPrivate = v8::Private::ForApi(
517 isolate, v8::String::NewFromUtf8(isolate, "allowAccessorFormatting", 747 isolate, v8::String::NewFromUtf8(isolate, "allowAccessorFormatting",
518 v8::NewStringType::kNormal) 748 v8::NewStringType::kNormal)
519 .ToLocalChecked()); 749 .ToLocalChecked());
520 object 750 object
521 ->SetPrivate(isolate->GetCurrentContext(), shouldFormatAccessorsPrivate, 751 ->SetPrivate(isolate->GetCurrentContext(), shouldFormatAccessorsPrivate,
522 v8::Null(isolate)) 752 v8::Null(isolate))
523 .ToChecked(); 753 .ToChecked();
524 } 754 }
525 }; 755 };
526 756
527 void UtilsExtension::CreateContextGroup(
528 const v8::FunctionCallbackInfo<v8::Value>& args) {
529 if (args.Length() != 0) {
530 fprintf(stderr, "Internal error: createContextGroup().");
531 Exit();
532 }
533 v8::base::Semaphore ready_semaphore(0);
534 int context_group_id = 0;
535 IsolateData::SetupGlobalTasks setup_global;
536 setup_global.emplace_back(new SetTimeoutExtension());
537 setup_global.emplace_back(new InspectorExtension());
538 inspector_client_->scheduleCreateContextGroup(
539 std::move(setup_global), &ready_semaphore, &context_group_id);
540 ready_semaphore.Wait();
541 args.GetReturnValue().Set(
542 v8::Int32::New(args.GetIsolate(), context_group_id));
543 }
544
545 v8::Local<v8::String> ToString(v8::Isolate* isolate,
546 const v8_inspector::StringView& string) {
547 if (string.is8Bit())
548 return v8::String::NewFromOneByte(isolate, string.characters8(),
549 v8::NewStringType::kNormal,
550 static_cast<int>(string.length()))
551 .ToLocalChecked();
552 else
553 return v8::String::NewFromTwoByte(isolate, string.characters16(),
554 v8::NewStringType::kNormal,
555 static_cast<int>(string.length()))
556 .ToLocalChecked();
557 }
558
559 class FrontendChannelImpl : public InspectorClientImpl::FrontendChannel { 757 class FrontendChannelImpl : public InspectorClientImpl::FrontendChannel {
560 public: 758 public:
561 explicit FrontendChannelImpl(TaskRunner* frontend_task_runner) 759 FrontendChannelImpl(TaskRunner* frontend_task_runner, int context_group_id)
562 : frontend_task_runner_(frontend_task_runner) {} 760 : frontend_task_runner_(frontend_task_runner),
761 context_group_id_(context_group_id) {}
563 virtual ~FrontendChannelImpl() {} 762 virtual ~FrontendChannelImpl() {}
564 763
565 void SendMessageToFrontend(const v8_inspector::StringView& message) final { 764 void SendMessageToFrontend(int session_id,
566 v8::Isolate* isolate = v8::Isolate::GetCurrent(); 765 const v8_inspector::StringView& message) final {
567 v8::HandleScope scope(v8::Isolate::GetCurrent()); 766 frontend_task_runner_->Append(new SendMessageToFrontendTask(
568 767 context_group_id_, session_id, ToVector(message)));
569 v8::Local<v8::String> prefix =
570 v8::String::NewFromUtf8(isolate, "InspectorTest._dispatchMessage(",
571 v8::NewStringType::kInternalized)
572 .ToLocalChecked();
573 v8::Local<v8::String> message_string = ToString(isolate, message);
574 v8::Local<v8::String> suffix =
575 v8::String::NewFromUtf8(isolate, ")", v8::NewStringType::kInternalized)
576 .ToLocalChecked();
577
578 v8::Local<v8::String> result = v8::String::Concat(prefix, message_string);
579 result = v8::String::Concat(result, suffix);
580
581 frontend_task_runner_->Append(new ExecuteStringTask(
582 ToVector(result), v8::String::Empty(isolate),
583 v8::Integer::New(isolate, 0), v8::Integer::New(isolate, 0),
584 v8::Boolean::New(isolate, false), nullptr, nullptr));
585 } 768 }
586 769
587 private: 770 private:
588 TaskRunner* frontend_task_runner_; 771 TaskRunner* frontend_task_runner_;
772 int context_group_id_;
589 }; 773 };
590 774
591 } // namespace 775 } // namespace
592 776
593 int main(int argc, char* argv[]) { 777 int main(int argc, char* argv[]) {
594 v8::V8::InitializeICUDefaultLocation(argv[0]); 778 v8::V8::InitializeICUDefaultLocation(argv[0]);
595 v8::Platform* platform = v8::platform::CreateDefaultPlatform(); 779 v8::Platform* platform = v8::platform::CreateDefaultPlatform();
596 v8::V8::InitializePlatform(platform); 780 v8::V8::InitializePlatform(platform);
597 v8::V8::SetFlagsFromCommandLine(&argc, argv, true); 781 v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
598 v8::V8::InitializeExternalStartupData(argv[0]); 782 v8::V8::InitializeExternalStartupData(argv[0]);
599 v8::V8::Initialize(); 783 v8::V8::Initialize();
600 784
601 v8::base::Semaphore ready_semaphore(0); 785 v8::base::Semaphore ready_semaphore(0);
602 786
603 v8::StartupData startup_data = {nullptr, 0}; 787 v8::StartupData startup_data = {nullptr, 0};
604 for (int i = 1; i < argc; ++i) { 788 for (int i = 1; i < argc; ++i) {
605 if (strcmp(argv[i], "--embed") == 0) { 789 if (strcmp(argv[i], "--embed") == 0) {
606 argv[i++] = nullptr; 790 argv[i++] = nullptr;
607 printf("Embedding script '%s'\n", argv[i]); 791 printf("Embedding script '%s'\n", argv[i]);
608 startup_data = v8::V8::CreateSnapshotDataBlob(argv[i]); 792 startup_data = v8::V8::CreateSnapshotDataBlob(argv[i]);
609 argv[i] = nullptr; 793 argv[i] = nullptr;
610 } 794 }
611 } 795 }
612 796
797 IsolateData::SetupGlobalTasks frontend_extensions;
798 frontend_extensions.emplace_back(new UtilsExtension());
799 TaskRunner frontend_runner(std::move(frontend_extensions), true,
800 &ready_semaphore, nullptr, nullptr);
801 ready_semaphore.Wait();
802
803 int frontend_context_group_id = 0;
804 frontend_runner.Append(
805 new CreateContextGroupTask(&ready_semaphore, &frontend_context_group_id));
806 ready_semaphore.Wait();
807
613 IsolateData::SetupGlobalTasks backend_extensions; 808 IsolateData::SetupGlobalTasks backend_extensions;
614 backend_extensions.emplace_back(new SetTimeoutExtension()); 809 backend_extensions.emplace_back(new SetTimeoutExtension());
615 backend_extensions.emplace_back(new InspectorExtension()); 810 backend_extensions.emplace_back(new InspectorExtension());
616 TaskRunner backend_runner(std::move(backend_extensions), false, 811 FrontendChannelImpl frontend_channel(&frontend_runner,
617 &ready_semaphore, 812 frontend_context_group_id);
618 startup_data.data ? &startup_data : nullptr); 813 TaskRunner backend_runner(
814 std::move(backend_extensions), false, &ready_semaphore,
815 startup_data.data ? &startup_data : nullptr, &frontend_channel);
619 ready_semaphore.Wait(); 816 ready_semaphore.Wait();
620 SendMessageToBackendExtension::set_backend_task_runner(&backend_runner);
621 UtilsExtension::set_backend_task_runner(&backend_runner); 817 UtilsExtension::set_backend_task_runner(&backend_runner);
622 818
623 IsolateData::SetupGlobalTasks frontend_extensions;
624 frontend_extensions.emplace_back(new UtilsExtension());
625 frontend_extensions.emplace_back(new SendMessageToBackendExtension());
626 TaskRunner frontend_runner(std::move(frontend_extensions), true,
627 &ready_semaphore, nullptr);
628 ready_semaphore.Wait();
629
630 FrontendChannelImpl frontend_channel(&frontend_runner);
631 InspectorClientImpl inspector_client(&backend_runner, &frontend_channel,
632 &ready_semaphore);
633 ready_semaphore.Wait();
634 UtilsExtension::set_inspector_client(&inspector_client);
635
636 task_runners.push_back(&frontend_runner); 819 task_runners.push_back(&frontend_runner);
637 task_runners.push_back(&backend_runner); 820 task_runners.push_back(&backend_runner);
638 821
639 for (int i = 1; i < argc; ++i) { 822 for (int i = 1; i < argc; ++i) {
640 // Ignore unknown flags. 823 // Ignore unknown flags.
641 if (argv[i] == nullptr || argv[i][0] == '-') continue; 824 if (argv[i] == nullptr || argv[i][0] == '-') continue;
642 825
643 bool exists = false; 826 bool exists = false;
644 v8::internal::Vector<const char> chars = 827 v8::internal::Vector<const char> chars =
645 v8::internal::ReadFile(argv[i], &exists, true); 828 v8::internal::ReadFile(argv[i], &exists, true);
646 if (!exists) { 829 if (!exists) {
647 fprintf(stderr, "Internal error: script file doesn't exists: %s\n", 830 fprintf(stderr, "Internal error: script file doesn't exists: %s\n",
648 argv[i]); 831 argv[i]);
649 Exit(); 832 Exit();
650 } 833 }
651 frontend_runner.Append(new ExecuteStringTask(chars)); 834 frontend_runner.Append(
835 new ExecuteStringTask(chars, frontend_context_group_id));
652 } 836 }
653 837
654 frontend_runner.Join(); 838 frontend_runner.Join();
655 backend_runner.Join(); 839 backend_runner.Join();
656 840
657 delete startup_data.data; 841 delete startup_data.data;
658 return 0; 842 return 0;
659 } 843 }
OLDNEW
« no previous file with comments | « test/inspector/inspector-impl.cc ('k') | test/inspector/isolate-data.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698