OLD | NEW |
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 |
11 #include "include/libplatform/libplatform.h" | 11 #include "include/libplatform/libplatform.h" |
12 #include "include/v8.h" | 12 #include "include/v8.h" |
13 | 13 |
14 #include "src/base/platform/platform.h" | 14 #include "src/base/platform/platform.h" |
15 #include "src/flags.h" | 15 #include "src/flags.h" |
16 #include "src/inspector/test-interface.h" | |
17 #include "src/utils.h" | 16 #include "src/utils.h" |
18 #include "src/vector.h" | 17 #include "src/vector.h" |
19 | 18 |
20 #include "test/inspector/isolate-data.h" | 19 #include "test/inspector/isolate-data.h" |
21 #include "test/inspector/task-runner.h" | 20 #include "test/inspector/task-runner.h" |
22 | 21 |
23 namespace { | 22 namespace { |
24 | 23 |
25 std::vector<TaskRunner*> task_runners; | 24 std::vector<TaskRunner*> task_runners; |
26 | 25 |
(...skipping 17 matching lines...) Expand all Loading... |
44 v8::internal::Vector<uint16_t>::New(str->Length()); | 43 v8::internal::Vector<uint16_t>::New(str->Length()); |
45 str->Write(buffer.start(), 0, str->Length()); | 44 str->Write(buffer.start(), 0, str->Length()); |
46 return buffer; | 45 return buffer; |
47 } | 46 } |
48 | 47 |
49 v8::Local<v8::String> ToV8String(v8::Isolate* isolate, const char* str) { | 48 v8::Local<v8::String> ToV8String(v8::Isolate* isolate, const char* str) { |
50 return v8::String::NewFromUtf8(isolate, str, v8::NewStringType::kNormal) | 49 return v8::String::NewFromUtf8(isolate, str, v8::NewStringType::kNormal) |
51 .ToLocalChecked(); | 50 .ToLocalChecked(); |
52 } | 51 } |
53 | 52 |
| 53 v8::Local<v8::String> ToV8String(v8::Isolate* isolate, const char* str, |
| 54 int length) { |
| 55 return v8::String::NewFromUtf8(isolate, str, v8::NewStringType::kNormal, |
| 56 length) |
| 57 .ToLocalChecked(); |
| 58 } |
| 59 |
| 60 v8::Local<v8::String> ToV8String(v8::Isolate* isolate, |
| 61 const v8::internal::Vector<uint16_t>& buffer) { |
| 62 return v8::String::NewFromTwoByte(isolate, buffer.start(), |
| 63 v8::NewStringType::kNormal, buffer.length()) |
| 64 .ToLocalChecked(); |
| 65 } |
| 66 |
54 v8::internal::Vector<uint16_t> ToVector( | 67 v8::internal::Vector<uint16_t> ToVector( |
55 const v8_inspector::StringView& string) { | 68 const v8_inspector::StringView& string) { |
56 v8::internal::Vector<uint16_t> buffer = | 69 v8::internal::Vector<uint16_t> buffer = |
57 v8::internal::Vector<uint16_t>::New(static_cast<int>(string.length())); | 70 v8::internal::Vector<uint16_t>::New(static_cast<int>(string.length())); |
58 for (size_t i = 0; i < string.length(); i++) { | 71 for (size_t i = 0; i < string.length(); i++) { |
59 if (string.is8Bit()) | 72 if (string.is8Bit()) |
60 buffer[i] = string.characters8()[i]; | 73 buffer[i] = string.characters8()[i]; |
61 else | 74 else |
62 buffer[i] = string.characters16()[i]; | 75 buffer[i] = string.characters16()[i]; |
63 } | 76 } |
64 return buffer; | 77 return buffer; |
65 } | 78 } |
66 | 79 |
67 class CreateContextGroupTask : public TaskRunner::Task { | 80 class FrontendChannelImpl : public v8_inspector::V8Inspector::Channel { |
68 public: | 81 public: |
69 CreateContextGroupTask(v8::base::Semaphore* ready_semaphore, | 82 FrontendChannelImpl(TaskRunner* task_runner, int context_group_id, |
70 int* context_group_id) | 83 v8::Isolate* isolate, v8::Local<v8::Function> function) |
71 : ready_semaphore_(ready_semaphore), | 84 : task_runner_(task_runner), |
72 context_group_id_(context_group_id) {} | 85 context_group_id_(context_group_id), |
73 virtual ~CreateContextGroupTask() = default; | 86 function_(isolate, function) {} |
74 bool is_inspector_task() final { return true; } | 87 virtual ~FrontendChannelImpl() = default; |
| 88 |
| 89 void set_session_id(int session_id) { session_id_ = session_id; } |
75 | 90 |
76 private: | 91 private: |
77 void Run() override { | 92 void sendResponse( |
78 *context_group_id_ = data()->CreateContextGroup(); | 93 int callId, |
79 if (ready_semaphore_) ready_semaphore_->Signal(); | 94 std::unique_ptr<v8_inspector::StringBuffer> message) override { |
| 95 task_runner_->Append( |
| 96 new SendMessageTask(this, ToVector(message->string()))); |
80 } | 97 } |
| 98 void sendNotification( |
| 99 std::unique_ptr<v8_inspector::StringBuffer> message) override { |
| 100 task_runner_->Append( |
| 101 new SendMessageTask(this, ToVector(message->string()))); |
| 102 } |
| 103 void flushProtocolNotifications() override {} |
81 | 104 |
82 v8::base::Semaphore* ready_semaphore_; | 105 class SendMessageTask : public TaskRunner::Task { |
83 int* context_group_id_; | 106 public: |
| 107 SendMessageTask(FrontendChannelImpl* channel, |
| 108 const v8::internal::Vector<uint16_t>& message) |
| 109 : channel_(channel), message_(message) {} |
| 110 virtual ~SendMessageTask() {} |
| 111 bool is_priority_task() final { return false; } |
| 112 |
| 113 private: |
| 114 void Run(IsolateData* data) override { |
| 115 v8::MicrotasksScope microtasks_scope(data->isolate(), |
| 116 v8::MicrotasksScope::kRunMicrotasks); |
| 117 v8::HandleScope handle_scope(data->isolate()); |
| 118 v8::Local<v8::Context> context = |
| 119 data->GetContext(channel_->context_group_id_); |
| 120 v8::Context::Scope context_scope(context); |
| 121 v8::Local<v8::Value> message = ToV8String(data->isolate(), message_); |
| 122 v8::MaybeLocal<v8::Value> result; |
| 123 result = channel_->function_.Get(data->isolate()) |
| 124 ->Call(context, context->Global(), 1, &message); |
| 125 } |
| 126 FrontendChannelImpl* channel_; |
| 127 v8::internal::Vector<uint16_t> message_; |
| 128 }; |
| 129 |
| 130 TaskRunner* task_runner_; |
| 131 int context_group_id_; |
| 132 v8::Global<v8::Function> function_; |
| 133 int session_id_; |
| 134 DISALLOW_COPY_AND_ASSIGN(FrontendChannelImpl); |
84 }; | 135 }; |
85 | 136 |
86 class ConnectSessionTask : public TaskRunner::Task { | 137 template <typename T> |
87 public: | 138 void RunSyncTask(TaskRunner* task_runner, T callback) { |
88 ConnectSessionTask(v8::base::Semaphore* ready_semaphore, int context_group_id, | 139 class SyncTask : public TaskRunner::Task { |
89 const v8::internal::Vector<uint16_t>& state, | 140 public: |
90 int* session_id) | 141 SyncTask(v8::base::Semaphore* ready_semaphore, T callback) |
91 : ready_semaphore_(ready_semaphore), | 142 : ready_semaphore_(ready_semaphore), callback_(callback) {} |
92 context_group_id_(context_group_id), | 143 virtual ~SyncTask() = default; |
93 state_(state), | 144 bool is_priority_task() final { return true; } |
94 session_id_(session_id) {} | |
95 virtual ~ConnectSessionTask() = default; | |
96 bool is_inspector_task() final { return true; } | |
97 | 145 |
98 private: | 146 private: |
99 void Run() override { | 147 void Run(IsolateData* data) override { |
100 v8_inspector::StringView state(state_.start(), state_.length()); | 148 callback_(data); |
101 *session_id_ = data()->ConnectSession(context_group_id_, state); | 149 if (ready_semaphore_) ready_semaphore_->Signal(); |
102 if (ready_semaphore_) ready_semaphore_->Signal(); | 150 } |
103 } | |
104 | 151 |
105 v8::base::Semaphore* ready_semaphore_; | 152 v8::base::Semaphore* ready_semaphore_; |
106 int context_group_id_; | 153 T callback_; |
107 const v8::internal::Vector<uint16_t>& state_; | 154 }; |
108 int* session_id_; | |
109 }; | |
110 | 155 |
111 class DisconnectSessionTask : public TaskRunner::Task { | 156 v8::base::Semaphore ready_semaphore(0); |
112 public: | 157 task_runner->Append(new SyncTask(&ready_semaphore, callback)); |
113 DisconnectSessionTask(v8::base::Semaphore* ready_semaphore, int session_id, | 158 ready_semaphore.Wait(); |
114 v8::internal::Vector<uint16_t>* state) | 159 } |
115 : ready_semaphore_(ready_semaphore), | |
116 session_id_(session_id), | |
117 state_(state) {} | |
118 virtual ~DisconnectSessionTask() = default; | |
119 bool is_inspector_task() final { return true; } | |
120 | |
121 private: | |
122 void Run() override { | |
123 std::unique_ptr<v8_inspector::StringBuffer> state = | |
124 data()->DisconnectSession(session_id_); | |
125 *state_ = ToVector(state->string()); | |
126 if (ready_semaphore_) ready_semaphore_->Signal(); | |
127 } | |
128 | |
129 v8::base::Semaphore* ready_semaphore_; | |
130 int session_id_; | |
131 v8::internal::Vector<uint16_t>* state_; | |
132 }; | |
133 | 160 |
134 class SendMessageToBackendTask : public TaskRunner::Task { | 161 class SendMessageToBackendTask : public TaskRunner::Task { |
135 public: | 162 public: |
136 explicit SendMessageToBackendTask( | 163 SendMessageToBackendTask(int session_id, |
137 int session_id, const v8::internal::Vector<uint16_t>& message) | 164 const v8::internal::Vector<uint16_t>& message) |
138 : session_id_(session_id), message_(message) {} | 165 : session_id_(session_id), message_(message) {} |
139 bool is_inspector_task() final { return true; } | 166 bool is_priority_task() final { return true; } |
140 | 167 |
141 private: | 168 private: |
142 void Run() override { | 169 void Run(IsolateData* data) override { |
143 v8_inspector::StringView message_view(message_.start(), message_.length()); | 170 v8_inspector::StringView message_view(message_.start(), message_.length()); |
144 data()->SendMessage(session_id_, message_view); | 171 data->SendMessage(session_id_, message_view); |
145 } | 172 } |
146 | 173 |
147 int session_id_; | 174 int session_id_; |
148 v8::internal::Vector<uint16_t> message_; | 175 v8::internal::Vector<uint16_t> message_; |
149 }; | 176 }; |
150 | 177 |
151 class SchedulePauseOnNextStatementTask : public TaskRunner::Task { | 178 void RunAsyncTask(TaskRunner* task_runner, const char* task_name, |
| 179 TaskRunner::Task* task) { |
| 180 class AsyncTask : public TaskRunner::Task { |
| 181 public: |
| 182 explicit AsyncTask(TaskRunner::Task* inner) : inner_(inner) {} |
| 183 virtual ~AsyncTask() = default; |
| 184 bool is_priority_task() override { return inner_->is_priority_task(); } |
| 185 void Run(IsolateData* data) override { |
| 186 data->AsyncTaskStarted(inner_.get()); |
| 187 inner_->Run(data); |
| 188 data->AsyncTaskFinished(inner_.get()); |
| 189 } |
| 190 |
| 191 private: |
| 192 std::unique_ptr<TaskRunner::Task> inner_; |
| 193 DISALLOW_COPY_AND_ASSIGN(AsyncTask); |
| 194 }; |
| 195 |
| 196 task_runner->data()->AsyncTaskScheduled( |
| 197 v8_inspector::StringView(reinterpret_cast<const uint8_t*>(task_name), |
| 198 strlen(task_name)), |
| 199 task, false); |
| 200 task_runner->Append(new AsyncTask(task)); |
| 201 } |
| 202 |
| 203 class ExecuteStringTask : public TaskRunner::Task { |
152 public: | 204 public: |
153 SchedulePauseOnNextStatementTask( | 205 ExecuteStringTask(int context_group_id, |
154 v8::base::Semaphore* ready_semaphore, int context_group_id, | 206 const v8::internal::Vector<uint16_t>& expression, |
155 const v8::internal::Vector<uint16_t>& reason, | 207 v8::Local<v8::String> name, |
156 const v8::internal::Vector<uint16_t>& details) | 208 v8::Local<v8::Integer> line_offset, |
157 : ready_semaphore_(ready_semaphore), | 209 v8::Local<v8::Integer> column_offset, |
158 context_group_id_(context_group_id), | 210 v8::Local<v8::Boolean> is_module) |
159 reason_(reason), | 211 : expression_(expression), |
160 details_(details) {} | 212 name_(ToVector(name)), |
161 virtual ~SchedulePauseOnNextStatementTask() = default; | 213 line_offset_(line_offset.As<v8::Int32>()->Value()), |
162 bool is_inspector_task() final { return true; } | 214 column_offset_(column_offset.As<v8::Int32>()->Value()), |
| 215 is_module_(is_module->Value()), |
| 216 context_group_id_(context_group_id) {} |
| 217 ExecuteStringTask(const v8::internal::Vector<const char>& expression, |
| 218 int context_group_id) |
| 219 : expression_utf8_(expression), context_group_id_(context_group_id) {} |
| 220 bool is_priority_task() override { return false; } |
| 221 void Run(IsolateData* data) override { |
| 222 v8::MicrotasksScope microtasks_scope(data->isolate(), |
| 223 v8::MicrotasksScope::kRunMicrotasks); |
| 224 v8::HandleScope handle_scope(data->isolate()); |
| 225 v8::Local<v8::Context> context = data->GetContext(context_group_id_); |
| 226 v8::Context::Scope context_scope(context); |
| 227 v8::ScriptOrigin origin( |
| 228 ToV8String(data->isolate(), name_), |
| 229 v8::Integer::New(data->isolate(), line_offset_), |
| 230 v8::Integer::New(data->isolate(), column_offset_), |
| 231 /* resource_is_shared_cross_origin */ v8::Local<v8::Boolean>(), |
| 232 /* script_id */ v8::Local<v8::Integer>(), |
| 233 /* source_map_url */ v8::Local<v8::Value>(), |
| 234 /* resource_is_opaque */ v8::Local<v8::Boolean>(), |
| 235 /* is_wasm */ v8::Local<v8::Boolean>(), |
| 236 v8::Boolean::New(data->isolate(), is_module_)); |
| 237 v8::Local<v8::String> source; |
| 238 if (expression_.length()) |
| 239 source = ToV8String(data->isolate(), expression_); |
| 240 else |
| 241 source = ToV8String(data->isolate(), expression_utf8_.start(), |
| 242 expression_utf8_.length()); |
| 243 |
| 244 v8::ScriptCompiler::Source scriptSource(source, origin); |
| 245 if (!is_module_) { |
| 246 v8::Local<v8::Script> script; |
| 247 if (!v8::ScriptCompiler::Compile(context, &scriptSource).ToLocal(&script)) |
| 248 return; |
| 249 v8::MaybeLocal<v8::Value> result; |
| 250 result = script->Run(context); |
| 251 } else { |
| 252 data->RegisterModule(context, name_, &scriptSource); |
| 253 } |
| 254 } |
163 | 255 |
164 private: | 256 private: |
165 void Run() override { | 257 v8::internal::Vector<uint16_t> expression_; |
166 v8_inspector::StringView reason(reason_.start(), reason_.length()); | 258 v8::internal::Vector<const char> expression_utf8_; |
167 v8_inspector::StringView details(details_.start(), details_.length()); | 259 v8::internal::Vector<uint16_t> name_; |
168 data()->SchedulePauseOnNextStatement(context_group_id_, reason, details); | 260 int32_t line_offset_ = 0; |
169 if (ready_semaphore_) ready_semaphore_->Signal(); | 261 int32_t column_offset_ = 0; |
170 } | 262 bool is_module_ = false; |
| 263 int context_group_id_; |
171 | 264 |
172 v8::base::Semaphore* ready_semaphore_; | 265 DISALLOW_COPY_AND_ASSIGN(ExecuteStringTask); |
173 int context_group_id_; | |
174 const v8::internal::Vector<uint16_t>& reason_; | |
175 const v8::internal::Vector<uint16_t>& details_; | |
176 }; | 266 }; |
177 | 267 |
178 class CancelPauseOnNextStatementTask : public TaskRunner::Task { | |
179 public: | |
180 CancelPauseOnNextStatementTask(v8::base::Semaphore* ready_semaphore, | |
181 int context_group_id) | |
182 : ready_semaphore_(ready_semaphore), | |
183 context_group_id_(context_group_id) {} | |
184 virtual ~CancelPauseOnNextStatementTask() = default; | |
185 bool is_inspector_task() final { return true; } | |
186 | |
187 private: | |
188 void Run() override { | |
189 data()->CancelPauseOnNextStatement(context_group_id_); | |
190 if (ready_semaphore_) ready_semaphore_->Signal(); | |
191 } | |
192 | |
193 v8::base::Semaphore* ready_semaphore_; | |
194 int context_group_id_; | |
195 }; | |
196 | |
197 class SendMessageToFrontendTask : public TaskRunner::Task { | |
198 public: | |
199 SendMessageToFrontendTask(int context_group_id, int session_id, | |
200 const v8::internal::Vector<uint16_t>& message) | |
201 : context_group_id_(context_group_id), | |
202 session_id_(session_id), | |
203 message_(message) {} | |
204 virtual ~SendMessageToFrontendTask() {} | |
205 | |
206 bool is_inspector_task() final { return false; } | |
207 | |
208 static void Register(int session_id, v8::Isolate* isolate, | |
209 v8::Local<v8::Function> dispatcher) { | |
210 dispatchers_[session_id].Reset(isolate, dispatcher); | |
211 } | |
212 | |
213 static void Unregister(int session_id) { dispatchers_.erase(session_id); } | |
214 | |
215 private: | |
216 void Run() override { | |
217 v8::MicrotasksScope microtasks_scope(isolate(), | |
218 v8::MicrotasksScope::kRunMicrotasks); | |
219 v8::HandleScope handle_scope(isolate()); | |
220 v8::Local<v8::Context> context = data()->GetContext(context_group_id_); | |
221 v8::Context::Scope context_scope(context); | |
222 | |
223 if (dispatchers_.find(session_id_) == dispatchers_.end()) return; | |
224 v8::Local<v8::Function> function = dispatchers_[session_id_].Get(isolate()); | |
225 v8::Local<v8::Value> message = | |
226 v8::String::NewFromTwoByte(isolate(), message_.start(), | |
227 v8::NewStringType::kNormal, | |
228 static_cast<int>(message_.size())) | |
229 .ToLocalChecked(); | |
230 v8::MaybeLocal<v8::Value> result; | |
231 result = function->Call(context, context->Global(), 1, &message); | |
232 } | |
233 | |
234 static std::map<int, v8::Global<v8::Function>> dispatchers_; | |
235 int context_group_id_; | |
236 int session_id_; | |
237 v8::internal::Vector<uint16_t> message_; | |
238 }; | |
239 | |
240 std::map<int, v8::Global<v8::Function>> SendMessageToFrontendTask::dispatchers_; | |
241 | |
242 class UtilsExtension : public IsolateData::SetupGlobalTask { | 268 class UtilsExtension : public IsolateData::SetupGlobalTask { |
243 public: | 269 public: |
244 ~UtilsExtension() override = default; | 270 ~UtilsExtension() override = default; |
245 void Run(v8::Isolate* isolate, | 271 void Run(v8::Isolate* isolate, |
246 v8::Local<v8::ObjectTemplate> global) override { | 272 v8::Local<v8::ObjectTemplate> global) override { |
247 v8::Local<v8::ObjectTemplate> utils = v8::ObjectTemplate::New(isolate); | 273 v8::Local<v8::ObjectTemplate> utils = v8::ObjectTemplate::New(isolate); |
248 utils->Set(ToV8String(isolate, "print"), | 274 utils->Set(ToV8String(isolate, "print"), |
249 v8::FunctionTemplate::New(isolate, &UtilsExtension::Print)); | 275 v8::FunctionTemplate::New(isolate, &UtilsExtension::Print)); |
250 utils->Set(ToV8String(isolate, "quit"), | 276 utils->Set(ToV8String(isolate, "quit"), |
251 v8::FunctionTemplate::New(isolate, &UtilsExtension::Quit)); | 277 v8::FunctionTemplate::New(isolate, &UtilsExtension::Quit)); |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
339 setlocale(LC_NUMERIC, *str); | 365 setlocale(LC_NUMERIC, *str); |
340 } | 366 } |
341 | 367 |
342 static bool ReadFile(v8::Isolate* isolate, v8::Local<v8::Value> name, | 368 static bool ReadFile(v8::Isolate* isolate, v8::Local<v8::Value> name, |
343 v8::internal::Vector<const char>* chars) { | 369 v8::internal::Vector<const char>* chars) { |
344 v8::String::Utf8Value str(name); | 370 v8::String::Utf8Value str(name); |
345 bool exists = false; | 371 bool exists = false; |
346 std::string filename(*str, str.length()); | 372 std::string filename(*str, str.length()); |
347 *chars = v8::internal::ReadFile(filename.c_str(), &exists); | 373 *chars = v8::internal::ReadFile(filename.c_str(), &exists); |
348 if (!exists) { | 374 if (!exists) { |
349 isolate->ThrowException( | 375 isolate->ThrowException(ToV8String(isolate, "Error reading file")); |
350 v8::String::NewFromUtf8(isolate, "Error reading file", | |
351 v8::NewStringType::kNormal) | |
352 .ToLocalChecked()); | |
353 return false; | 376 return false; |
354 } | 377 } |
355 return true; | 378 return true; |
356 } | 379 } |
357 | 380 |
358 static void Read(const v8::FunctionCallbackInfo<v8::Value>& args) { | 381 static void Read(const v8::FunctionCallbackInfo<v8::Value>& args) { |
359 if (args.Length() != 1 || !args[0]->IsString()) { | 382 if (args.Length() != 1 || !args[0]->IsString()) { |
360 fprintf(stderr, "Internal error: read gets one string argument."); | 383 fprintf(stderr, "Internal error: read gets one string argument."); |
361 Exit(); | 384 Exit(); |
362 } | 385 } |
363 v8::internal::Vector<const char> chars; | 386 v8::internal::Vector<const char> chars; |
364 v8::Isolate* isolate = args.GetIsolate(); | 387 v8::Isolate* isolate = args.GetIsolate(); |
365 if (ReadFile(isolate, args[0], &chars)) { | 388 if (ReadFile(isolate, args[0], &chars)) |
366 args.GetReturnValue().Set( | 389 args.GetReturnValue().Set(ToV8String(isolate, chars.start())); |
367 v8::String::NewFromUtf8(isolate, chars.start(), | |
368 v8::NewStringType::kNormal, chars.length()) | |
369 .ToLocalChecked()); | |
370 } | |
371 } | 390 } |
372 | 391 |
373 static void Load(const v8::FunctionCallbackInfo<v8::Value>& args) { | 392 static void Load(const v8::FunctionCallbackInfo<v8::Value>& args) { |
374 if (args.Length() != 1 || !args[0]->IsString()) { | 393 if (args.Length() != 1 || !args[0]->IsString()) { |
375 fprintf(stderr, "Internal error: load gets one string argument."); | 394 fprintf(stderr, "Internal error: load gets one string argument."); |
376 Exit(); | 395 Exit(); |
377 } | 396 } |
378 v8::internal::Vector<const char> chars; | 397 v8::internal::Vector<const char> chars; |
379 v8::Isolate* isolate = args.GetIsolate(); | 398 v8::Isolate* isolate = args.GetIsolate(); |
380 v8::Local<v8::Context> context = isolate->GetCurrentContext(); | 399 v8::Local<v8::Context> context = isolate->GetCurrentContext(); |
381 IsolateData* data = IsolateData::FromContext(context); | 400 IsolateData* data = IsolateData::FromContext(context); |
382 int context_group_id = data->GetContextGroupId(context); | 401 int context_group_id = data->GetContextGroupId(context); |
383 if (ReadFile(isolate, args[0], &chars)) { | 402 if (ReadFile(isolate, args[0], &chars)) { |
384 ExecuteStringTask(chars, context_group_id).RunOnIsolate(data); | 403 ExecuteStringTask(chars, context_group_id).Run(data); |
385 } | 404 } |
386 } | 405 } |
387 | 406 |
388 static void CompileAndRunWithOrigin( | 407 static void CompileAndRunWithOrigin( |
389 const v8::FunctionCallbackInfo<v8::Value>& args) { | 408 const v8::FunctionCallbackInfo<v8::Value>& args) { |
390 if (args.Length() != 6 || !args[0]->IsInt32() || !args[1]->IsString() || | 409 if (args.Length() != 6 || !args[0]->IsInt32() || !args[1]->IsString() || |
391 !args[2]->IsString() || !args[3]->IsInt32() || !args[4]->IsInt32() || | 410 !args[2]->IsString() || !args[3]->IsInt32() || !args[4]->IsInt32() || |
392 !args[5]->IsBoolean()) { | 411 !args[5]->IsBoolean()) { |
393 fprintf(stderr, | 412 fprintf(stderr, |
394 "Internal error: compileAndRunWithOrigin(context_group_id, " | 413 "Internal error: compileAndRunWithOrigin(context_group_id, " |
395 "source, name, line, " | 414 "source, name, line, " |
396 "column, is_module)."); | 415 "column, is_module)."); |
397 Exit(); | 416 Exit(); |
398 } | 417 } |
399 | 418 |
400 backend_runner_->Append(new ExecuteStringTask( | 419 backend_runner_->Append(new ExecuteStringTask( |
401 nullptr, args[0].As<v8::Int32>()->Value(), nullptr, | 420 args[0].As<v8::Int32>()->Value(), ToVector(args[1].As<v8::String>()), |
402 ToVector(args[1].As<v8::String>()), args[2].As<v8::String>(), | 421 args[2].As<v8::String>(), args[3].As<v8::Int32>(), |
403 args[3].As<v8::Int32>(), args[4].As<v8::Int32>(), | 422 args[4].As<v8::Int32>(), args[5].As<v8::Boolean>())); |
404 args[5].As<v8::Boolean>())); | |
405 } | 423 } |
406 | 424 |
407 static void SetCurrentTimeMSForTest( | 425 static void SetCurrentTimeMSForTest( |
408 const v8::FunctionCallbackInfo<v8::Value>& args) { | 426 const v8::FunctionCallbackInfo<v8::Value>& args) { |
409 if (args.Length() != 1 || !args[0]->IsNumber()) { | 427 if (args.Length() != 1 || !args[0]->IsNumber()) { |
410 fprintf(stderr, "Internal error: setCurrentTimeMSForTest(time)."); | 428 fprintf(stderr, "Internal error: setCurrentTimeMSForTest(time)."); |
411 Exit(); | 429 Exit(); |
412 } | 430 } |
413 backend_runner_->data()->SetCurrentTimeMS( | 431 backend_runner_->data()->SetCurrentTimeMS( |
414 args[0].As<v8::Number>()->Value()); | 432 args[0].As<v8::Number>()->Value()); |
(...skipping 12 matching lines...) Expand all Loading... |
427 const v8::FunctionCallbackInfo<v8::Value>& args) { | 445 const v8::FunctionCallbackInfo<v8::Value>& args) { |
428 if (args.Length() != 3 || !args[0]->IsInt32() || !args[1]->IsString() || | 446 if (args.Length() != 3 || !args[0]->IsInt32() || !args[1]->IsString() || |
429 !args[2]->IsString()) { | 447 !args[2]->IsString()) { |
430 fprintf(stderr, | 448 fprintf(stderr, |
431 "Internal error: schedulePauseOnNextStatement(context_group_id, " | 449 "Internal error: schedulePauseOnNextStatement(context_group_id, " |
432 "'reason', 'details')."); | 450 "'reason', 'details')."); |
433 Exit(); | 451 Exit(); |
434 } | 452 } |
435 v8::internal::Vector<uint16_t> reason = ToVector(args[1].As<v8::String>()); | 453 v8::internal::Vector<uint16_t> reason = ToVector(args[1].As<v8::String>()); |
436 v8::internal::Vector<uint16_t> details = ToVector(args[2].As<v8::String>()); | 454 v8::internal::Vector<uint16_t> details = ToVector(args[2].As<v8::String>()); |
437 v8::base::Semaphore ready_semaphore(0); | 455 int context_group_id = args[0].As<v8::Int32>()->Value(); |
438 backend_runner_->Append(new SchedulePauseOnNextStatementTask( | 456 RunSyncTask(backend_runner_, [&context_group_id, &reason, |
439 &ready_semaphore, args[0].As<v8::Int32>()->Value(), reason, details)); | 457 &details](IsolateData* data) { |
440 ready_semaphore.Wait(); | 458 data->SchedulePauseOnNextStatement( |
| 459 context_group_id, |
| 460 v8_inspector::StringView(reason.start(), reason.length()), |
| 461 v8_inspector::StringView(details.start(), details.length())); |
| 462 }); |
441 } | 463 } |
442 | 464 |
443 static void CancelPauseOnNextStatement( | 465 static void CancelPauseOnNextStatement( |
444 const v8::FunctionCallbackInfo<v8::Value>& args) { | 466 const v8::FunctionCallbackInfo<v8::Value>& args) { |
445 if (args.Length() != 1 || !args[0]->IsInt32()) { | 467 if (args.Length() != 1 || !args[0]->IsInt32()) { |
446 fprintf(stderr, | 468 fprintf(stderr, |
447 "Internal error: cancelPauseOnNextStatement(context_group_id)."); | 469 "Internal error: cancelPauseOnNextStatement(context_group_id)."); |
448 Exit(); | 470 Exit(); |
449 } | 471 } |
450 v8::base::Semaphore ready_semaphore(0); | 472 int context_group_id = args[0].As<v8::Int32>()->Value(); |
451 backend_runner_->Append(new CancelPauseOnNextStatementTask( | 473 RunSyncTask(backend_runner_, [&context_group_id](IsolateData* data) { |
452 &ready_semaphore, args[0].As<v8::Int32>()->Value())); | 474 data->CancelPauseOnNextStatement(context_group_id); |
453 ready_semaphore.Wait(); | 475 }); |
454 } | 476 } |
455 | 477 |
456 static void SetLogConsoleApiMessageCalls( | 478 static void SetLogConsoleApiMessageCalls( |
457 const v8::FunctionCallbackInfo<v8::Value>& args) { | 479 const v8::FunctionCallbackInfo<v8::Value>& args) { |
458 if (args.Length() != 1 || !args[0]->IsBoolean()) { | 480 if (args.Length() != 1 || !args[0]->IsBoolean()) { |
459 fprintf(stderr, "Internal error: setLogConsoleApiMessageCalls(bool)."); | 481 fprintf(stderr, "Internal error: setLogConsoleApiMessageCalls(bool)."); |
460 Exit(); | 482 Exit(); |
461 } | 483 } |
462 backend_runner_->data()->SetLogConsoleApiMessageCalls( | 484 backend_runner_->data()->SetLogConsoleApiMessageCalls( |
463 args[0].As<v8::Boolean>()->Value()); | 485 args[0].As<v8::Boolean>()->Value()); |
464 } | 486 } |
465 | 487 |
466 static void CreateContextGroup( | 488 static void CreateContextGroup( |
467 const v8::FunctionCallbackInfo<v8::Value>& args) { | 489 const v8::FunctionCallbackInfo<v8::Value>& args) { |
468 if (args.Length() != 0) { | 490 if (args.Length() != 0) { |
469 fprintf(stderr, "Internal error: createContextGroup()."); | 491 fprintf(stderr, "Internal error: createContextGroup()."); |
470 Exit(); | 492 Exit(); |
471 } | 493 } |
472 v8::base::Semaphore ready_semaphore(0); | |
473 int context_group_id = 0; | 494 int context_group_id = 0; |
474 backend_runner_->Append( | 495 RunSyncTask(backend_runner_, [&context_group_id](IsolateData* data) { |
475 new CreateContextGroupTask(&ready_semaphore, &context_group_id)); | 496 context_group_id = data->CreateContextGroup(); |
476 ready_semaphore.Wait(); | 497 }); |
477 args.GetReturnValue().Set( | 498 args.GetReturnValue().Set( |
478 v8::Int32::New(args.GetIsolate(), context_group_id)); | 499 v8::Int32::New(args.GetIsolate(), context_group_id)); |
479 } | 500 } |
480 | 501 |
481 static void ConnectSession(const v8::FunctionCallbackInfo<v8::Value>& args) { | 502 static void ConnectSession(const v8::FunctionCallbackInfo<v8::Value>& args) { |
482 if (args.Length() != 3 || !args[0]->IsInt32() || !args[1]->IsString() || | 503 if (args.Length() != 3 || !args[0]->IsInt32() || !args[1]->IsString() || |
483 !args[2]->IsFunction()) { | 504 !args[2]->IsFunction()) { |
484 fprintf(stderr, | 505 fprintf(stderr, |
485 "Internal error: connectionSession(context_group_id, state, " | 506 "Internal error: connectionSession(context_group_id, state, " |
486 "dispatch)."); | 507 "dispatch)."); |
487 Exit(); | 508 Exit(); |
488 } | 509 } |
| 510 v8::Local<v8::Context> context = args.GetIsolate()->GetCurrentContext(); |
| 511 FrontendChannelImpl* channel = new FrontendChannelImpl( |
| 512 IsolateData::FromContext(context)->task_runner(), |
| 513 IsolateData::FromContext(context)->GetContextGroupId(context), |
| 514 args.GetIsolate(), args[2].As<v8::Function>()); |
| 515 |
489 v8::internal::Vector<uint16_t> state = ToVector(args[1].As<v8::String>()); | 516 v8::internal::Vector<uint16_t> state = ToVector(args[1].As<v8::String>()); |
490 v8::base::Semaphore ready_semaphore(0); | 517 int context_group_id = args[0].As<v8::Int32>()->Value(); |
491 int session_id = 0; | 518 int session_id = 0; |
492 backend_runner_->Append(new ConnectSessionTask( | 519 RunSyncTask(backend_runner_, [&context_group_id, &session_id, &channel, |
493 &ready_semaphore, args[0].As<v8::Int32>()->Value(), state, | 520 &state](IsolateData* data) { |
494 &session_id)); | 521 session_id = data->ConnectSession( |
495 ready_semaphore.Wait(); | 522 context_group_id, |
496 SendMessageToFrontendTask::Register(session_id, args.GetIsolate(), | 523 v8_inspector::StringView(state.start(), state.length()), channel); |
497 args[2].As<v8::Function>()); | 524 channel->set_session_id(session_id); |
| 525 }); |
| 526 |
| 527 channels_[session_id].reset(channel); |
498 args.GetReturnValue().Set(v8::Int32::New(args.GetIsolate(), session_id)); | 528 args.GetReturnValue().Set(v8::Int32::New(args.GetIsolate(), session_id)); |
499 } | 529 } |
500 | 530 |
501 static void DisconnectSession( | 531 static void DisconnectSession( |
502 const v8::FunctionCallbackInfo<v8::Value>& args) { | 532 const v8::FunctionCallbackInfo<v8::Value>& args) { |
503 if (args.Length() != 1 || !args[0]->IsInt32()) { | 533 if (args.Length() != 1 || !args[0]->IsInt32()) { |
504 fprintf(stderr, "Internal error: disconnectionSession(session_id)."); | 534 fprintf(stderr, "Internal error: disconnectionSession(session_id)."); |
505 Exit(); | 535 Exit(); |
506 } | 536 } |
507 int session_id = args[0].As<v8::Int32>()->Value(); | 537 int session_id = args[0].As<v8::Int32>()->Value(); |
508 SendMessageToFrontendTask::Unregister(session_id); | |
509 v8::base::Semaphore ready_semaphore(0); | |
510 v8::internal::Vector<uint16_t> state; | 538 v8::internal::Vector<uint16_t> state; |
511 backend_runner_->Append( | 539 RunSyncTask(backend_runner_, [&session_id, &state](IsolateData* data) { |
512 new DisconnectSessionTask(&ready_semaphore, session_id, &state)); | 540 state = ToVector(data->DisconnectSession(session_id)->string()); |
513 ready_semaphore.Wait(); | 541 }); |
514 args.GetReturnValue().Set( | 542 channels_.erase(session_id); |
515 v8::String::NewFromTwoByte(args.GetIsolate(), state.start(), | 543 args.GetReturnValue().Set(ToV8String(args.GetIsolate(), state)); |
516 v8::NewStringType::kNormal, | |
517 static_cast<int>(state.size())) | |
518 .ToLocalChecked()); | |
519 } | 544 } |
520 | 545 |
521 static void SendMessageToBackend( | 546 static void SendMessageToBackend( |
522 const v8::FunctionCallbackInfo<v8::Value>& args) { | 547 const v8::FunctionCallbackInfo<v8::Value>& args) { |
523 if (args.Length() != 2 || !args[0]->IsInt32() || !args[1]->IsString()) { | 548 if (args.Length() != 2 || !args[0]->IsInt32() || !args[1]->IsString()) { |
524 fprintf(stderr, | 549 fprintf(stderr, |
525 "Internal error: sendMessageToBackend(session_id, message)."); | 550 "Internal error: sendMessageToBackend(session_id, message)."); |
526 Exit(); | 551 Exit(); |
527 } | 552 } |
528 backend_runner_->Append(new SendMessageToBackendTask( | 553 backend_runner_->Append(new SendMessageToBackendTask( |
529 args[0].As<v8::Int32>()->Value(), ToVector(args[1].As<v8::String>()))); | 554 args[0].As<v8::Int32>()->Value(), ToVector(args[1].As<v8::String>()))); |
530 } | 555 } |
| 556 |
| 557 static std::map<int, std::unique_ptr<FrontendChannelImpl>> channels_; |
531 }; | 558 }; |
532 | 559 |
533 TaskRunner* UtilsExtension::backend_runner_ = nullptr; | 560 TaskRunner* UtilsExtension::backend_runner_ = nullptr; |
| 561 std::map<int, std::unique_ptr<FrontendChannelImpl>> UtilsExtension::channels_; |
534 | 562 |
535 class SetTimeoutTask : public AsyncTask { | 563 class SetTimeoutTask : public TaskRunner::Task { |
536 public: | 564 public: |
537 SetTimeoutTask(IsolateData* data, int context_group_id, const char* task_name, | 565 SetTimeoutTask(int context_group_id, v8::Isolate* isolate, |
538 v8::Local<v8::Function> function) | 566 v8::Local<v8::Function> function) |
539 : AsyncTask(data, task_name), | 567 : function_(isolate, function), context_group_id_(context_group_id) {} |
540 function_(data->isolate(), function), | |
541 context_group_id_(context_group_id) {} | |
542 virtual ~SetTimeoutTask() {} | 568 virtual ~SetTimeoutTask() {} |
543 | 569 bool is_priority_task() final { return false; } |
544 bool is_inspector_task() final { return false; } | |
545 | 570 |
546 private: | 571 private: |
547 void AsyncRun() override { | 572 void Run(IsolateData* data) override { |
548 v8::MicrotasksScope microtasks_scope(isolate(), | 573 v8::MicrotasksScope microtasks_scope(data->isolate(), |
549 v8::MicrotasksScope::kRunMicrotasks); | 574 v8::MicrotasksScope::kRunMicrotasks); |
550 v8::HandleScope handle_scope(isolate()); | 575 v8::HandleScope handle_scope(data->isolate()); |
551 v8::Local<v8::Context> context = data()->GetContext(context_group_id_); | 576 v8::Local<v8::Context> context = data->GetContext(context_group_id_); |
552 v8::Context::Scope context_scope(context); | 577 v8::Context::Scope context_scope(context); |
553 | 578 |
554 v8::Local<v8::Function> function = function_.Get(isolate()); | 579 v8::Local<v8::Function> function = function_.Get(data->isolate()); |
555 v8::MaybeLocal<v8::Value> result; | 580 v8::MaybeLocal<v8::Value> result; |
556 result = function->Call(context, context->Global(), 0, nullptr); | 581 result = function->Call(context, context->Global(), 0, nullptr); |
557 } | 582 } |
558 | 583 |
559 v8::Global<v8::Function> function_; | 584 v8::Global<v8::Function> function_; |
560 int context_group_id_; | 585 int context_group_id_; |
561 }; | 586 }; |
562 | 587 |
563 class SetTimeoutExtension : public IsolateData::SetupGlobalTask { | 588 class SetTimeoutExtension : public IsolateData::SetupGlobalTask { |
564 public: | 589 public: |
(...skipping 11 matching lines...) Expand all Loading... |
576 args[1].As<v8::Number>()->Value() != 0.0) { | 601 args[1].As<v8::Number>()->Value() != 0.0) { |
577 fprintf( | 602 fprintf( |
578 stderr, | 603 stderr, |
579 "Internal error: only setTimeout(function|code, 0) is supported."); | 604 "Internal error: only setTimeout(function|code, 0) is supported."); |
580 Exit(); | 605 Exit(); |
581 } | 606 } |
582 v8::Isolate* isolate = args.GetIsolate(); | 607 v8::Isolate* isolate = args.GetIsolate(); |
583 v8::Local<v8::Context> context = isolate->GetCurrentContext(); | 608 v8::Local<v8::Context> context = isolate->GetCurrentContext(); |
584 IsolateData* data = IsolateData::FromContext(context); | 609 IsolateData* data = IsolateData::FromContext(context); |
585 int context_group_id = data->GetContextGroupId(context); | 610 int context_group_id = data->GetContextGroupId(context); |
586 std::unique_ptr<TaskRunner::Task> task; | |
587 if (args[0]->IsFunction()) { | 611 if (args[0]->IsFunction()) { |
588 task.reset(new SetTimeoutTask(data, context_group_id, "setTimeout", | 612 RunAsyncTask(data->task_runner(), "setTimeout", |
589 v8::Local<v8::Function>::Cast(args[0]))); | 613 new SetTimeoutTask(context_group_id, isolate, |
| 614 v8::Local<v8::Function>::Cast(args[0]))); |
590 } else { | 615 } else { |
591 task.reset(new ExecuteStringTask( | 616 RunAsyncTask( |
592 data, context_group_id, "setTimeout", | 617 data->task_runner(), "setTimeout", |
593 ToVector(args[0].As<v8::String>()), v8::String::Empty(isolate), | 618 new ExecuteStringTask( |
594 v8::Integer::New(isolate, 0), v8::Integer::New(isolate, 0), | 619 context_group_id, ToVector(args[0].As<v8::String>()), |
595 v8::Boolean::New(isolate, false))); | 620 v8::String::Empty(isolate), v8::Integer::New(isolate, 0), |
| 621 v8::Integer::New(isolate, 0), v8::Boolean::New(isolate, false))); |
596 } | 622 } |
597 data->task_runner()->Append(task.release()); | |
598 } | 623 } |
599 }; | 624 }; |
600 | 625 |
601 bool StrictAccessCheck(v8::Local<v8::Context> accessing_context, | 626 bool StrictAccessCheck(v8::Local<v8::Context> accessing_context, |
602 v8::Local<v8::Object> accessed_object, | 627 v8::Local<v8::Object> accessed_object, |
603 v8::Local<v8::Value> data) { | 628 v8::Local<v8::Value> data) { |
604 CHECK(accessing_context.IsEmpty()); | 629 CHECK(accessing_context.IsEmpty()); |
605 return accessing_context.IsEmpty(); | 630 return accessing_context.IsEmpty(); |
606 } | 631 } |
607 | 632 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
654 IsolateData* data = IsolateData::FromContext(context); | 679 IsolateData* data = IsolateData::FromContext(context); |
655 data->FireContextDestroyed(context); | 680 data->FireContextDestroyed(context); |
656 } | 681 } |
657 | 682 |
658 static void SetMaxAsyncTaskStacks( | 683 static void SetMaxAsyncTaskStacks( |
659 const v8::FunctionCallbackInfo<v8::Value>& args) { | 684 const v8::FunctionCallbackInfo<v8::Value>& args) { |
660 if (args.Length() != 1 || !args[0]->IsInt32()) { | 685 if (args.Length() != 1 || !args[0]->IsInt32()) { |
661 fprintf(stderr, "Internal error: setMaxAsyncTaskStacks(max)."); | 686 fprintf(stderr, "Internal error: setMaxAsyncTaskStacks(max)."); |
662 Exit(); | 687 Exit(); |
663 } | 688 } |
664 v8_inspector::SetMaxAsyncTaskStacksForTest( | 689 IsolateData::FromContext(args.GetIsolate()->GetCurrentContext()) |
665 IsolateData::FromContext(args.GetIsolate()->GetCurrentContext()) | 690 ->SetMaxAsyncTaskStacksForTest(args[0].As<v8::Int32>()->Value()); |
666 ->inspector(), | |
667 args[0].As<v8::Int32>()->Value()); | |
668 } | 691 } |
669 | 692 |
670 static void DumpAsyncTaskStacksStateForTest( | 693 static void DumpAsyncTaskStacksStateForTest( |
671 const v8::FunctionCallbackInfo<v8::Value>& args) { | 694 const v8::FunctionCallbackInfo<v8::Value>& args) { |
672 if (args.Length() != 0) { | 695 if (args.Length() != 0) { |
673 fprintf(stderr, "Internal error: dumpAsyncTaskStacksStateForTest()."); | 696 fprintf(stderr, "Internal error: dumpAsyncTaskStacksStateForTest()."); |
674 Exit(); | 697 Exit(); |
675 } | 698 } |
676 v8_inspector::DumpAsyncTaskStacksStateForTest( | 699 IsolateData::FromContext(args.GetIsolate()->GetCurrentContext()) |
677 IsolateData::FromContext(args.GetIsolate()->GetCurrentContext()) | 700 ->DumpAsyncTaskStacksStateForTest(); |
678 ->inspector()); | |
679 } | 701 } |
680 | 702 |
681 static void BreakProgram(const v8::FunctionCallbackInfo<v8::Value>& args) { | 703 static void BreakProgram(const v8::FunctionCallbackInfo<v8::Value>& args) { |
682 if (args.Length() != 2 || !args[0]->IsString() || !args[1]->IsString()) { | 704 if (args.Length() != 2 || !args[0]->IsString() || !args[1]->IsString()) { |
683 fprintf(stderr, "Internal error: breakProgram('reason', 'details')."); | 705 fprintf(stderr, "Internal error: breakProgram('reason', 'details')."); |
684 Exit(); | 706 Exit(); |
685 } | 707 } |
686 v8::Local<v8::Context> context = args.GetIsolate()->GetCurrentContext(); | 708 v8::Local<v8::Context> context = args.GetIsolate()->GetCurrentContext(); |
687 IsolateData* data = IsolateData::FromContext(context); | 709 IsolateData* data = IsolateData::FromContext(context); |
688 v8::internal::Vector<uint16_t> reason = ToVector(args[0].As<v8::String>()); | 710 v8::internal::Vector<uint16_t> reason = ToVector(args[0].As<v8::String>()); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
732 | 754 |
733 static void AllowAccessorFormatting( | 755 static void AllowAccessorFormatting( |
734 const v8::FunctionCallbackInfo<v8::Value>& args) { | 756 const v8::FunctionCallbackInfo<v8::Value>& args) { |
735 if (args.Length() != 1 || !args[0]->IsObject()) { | 757 if (args.Length() != 1 || !args[0]->IsObject()) { |
736 fprintf(stderr, "Internal error: allowAccessorFormatting('object')."); | 758 fprintf(stderr, "Internal error: allowAccessorFormatting('object')."); |
737 Exit(); | 759 Exit(); |
738 } | 760 } |
739 v8::Local<v8::Object> object = args[0].As<v8::Object>(); | 761 v8::Local<v8::Object> object = args[0].As<v8::Object>(); |
740 v8::Isolate* isolate = args.GetIsolate(); | 762 v8::Isolate* isolate = args.GetIsolate(); |
741 v8::Local<v8::Private> shouldFormatAccessorsPrivate = v8::Private::ForApi( | 763 v8::Local<v8::Private> shouldFormatAccessorsPrivate = v8::Private::ForApi( |
742 isolate, v8::String::NewFromUtf8(isolate, "allowAccessorFormatting", | 764 isolate, ToV8String(isolate, "allowAccessorFormatting")); |
743 v8::NewStringType::kNormal) | |
744 .ToLocalChecked()); | |
745 object | 765 object |
746 ->SetPrivate(isolate->GetCurrentContext(), shouldFormatAccessorsPrivate, | 766 ->SetPrivate(isolate->GetCurrentContext(), shouldFormatAccessorsPrivate, |
747 v8::Null(isolate)) | 767 v8::Null(isolate)) |
748 .ToChecked(); | 768 .ToChecked(); |
749 } | 769 } |
750 }; | 770 }; |
751 | 771 |
752 class FrontendChannelImpl : public IsolateData::FrontendChannel { | |
753 public: | |
754 FrontendChannelImpl(TaskRunner* frontend_task_runner, int context_group_id) | |
755 : frontend_task_runner_(frontend_task_runner), | |
756 context_group_id_(context_group_id) {} | |
757 virtual ~FrontendChannelImpl() {} | |
758 | |
759 void SendMessageToFrontend(int session_id, | |
760 const v8_inspector::StringView& message) final { | |
761 frontend_task_runner_->Append(new SendMessageToFrontendTask( | |
762 context_group_id_, session_id, ToVector(message))); | |
763 } | |
764 | |
765 private: | |
766 TaskRunner* frontend_task_runner_; | |
767 int context_group_id_; | |
768 }; | |
769 | |
770 } // namespace | 772 } // namespace |
771 | 773 |
772 int main(int argc, char* argv[]) { | 774 int main(int argc, char* argv[]) { |
773 v8::V8::InitializeICUDefaultLocation(argv[0]); | 775 v8::V8::InitializeICUDefaultLocation(argv[0]); |
774 v8::Platform* platform = v8::platform::CreateDefaultPlatform(); | 776 v8::Platform* platform = v8::platform::CreateDefaultPlatform(); |
775 v8::V8::InitializePlatform(platform); | 777 v8::V8::InitializePlatform(platform); |
776 v8::V8::SetFlagsFromCommandLine(&argc, argv, true); | 778 v8::V8::SetFlagsFromCommandLine(&argc, argv, true); |
777 v8::V8::InitializeExternalStartupData(argv[0]); | 779 v8::V8::InitializeExternalStartupData(argv[0]); |
778 v8::V8::Initialize(); | 780 v8::V8::Initialize(); |
779 | 781 |
780 v8::base::Semaphore ready_semaphore(0); | 782 v8::base::Semaphore ready_semaphore(0); |
781 | 783 |
782 v8::StartupData startup_data = {nullptr, 0}; | 784 v8::StartupData startup_data = {nullptr, 0}; |
783 for (int i = 1; i < argc; ++i) { | 785 for (int i = 1; i < argc; ++i) { |
784 if (strcmp(argv[i], "--embed") == 0) { | 786 if (strcmp(argv[i], "--embed") == 0) { |
785 argv[i++] = nullptr; | 787 argv[i++] = nullptr; |
786 printf("Embedding script '%s'\n", argv[i]); | 788 printf("Embedding script '%s'\n", argv[i]); |
787 startup_data = v8::V8::CreateSnapshotDataBlob(argv[i]); | 789 startup_data = v8::V8::CreateSnapshotDataBlob(argv[i]); |
788 argv[i] = nullptr; | 790 argv[i] = nullptr; |
789 } | 791 } |
790 } | 792 } |
791 | 793 |
792 IsolateData::SetupGlobalTasks frontend_extensions; | 794 IsolateData::SetupGlobalTasks frontend_extensions; |
793 frontend_extensions.emplace_back(new UtilsExtension()); | 795 frontend_extensions.emplace_back(new UtilsExtension()); |
794 TaskRunner frontend_runner(std::move(frontend_extensions), true, | 796 TaskRunner frontend_runner(std::move(frontend_extensions), true, |
795 &ready_semaphore, nullptr, nullptr); | 797 &ready_semaphore, nullptr, false); |
796 ready_semaphore.Wait(); | 798 ready_semaphore.Wait(); |
797 | 799 |
798 int frontend_context_group_id = 0; | 800 int frontend_context_group_id = 0; |
799 frontend_runner.Append( | 801 RunSyncTask(&frontend_runner, |
800 new CreateContextGroupTask(&ready_semaphore, &frontend_context_group_id)); | 802 [&frontend_context_group_id](IsolateData* data) { |
801 ready_semaphore.Wait(); | 803 frontend_context_group_id = data->CreateContextGroup(); |
| 804 }); |
802 | 805 |
803 IsolateData::SetupGlobalTasks backend_extensions; | 806 IsolateData::SetupGlobalTasks backend_extensions; |
804 backend_extensions.emplace_back(new SetTimeoutExtension()); | 807 backend_extensions.emplace_back(new SetTimeoutExtension()); |
805 backend_extensions.emplace_back(new InspectorExtension()); | 808 backend_extensions.emplace_back(new InspectorExtension()); |
806 FrontendChannelImpl frontend_channel(&frontend_runner, | 809 TaskRunner backend_runner(std::move(backend_extensions), false, |
807 frontend_context_group_id); | 810 &ready_semaphore, |
808 TaskRunner backend_runner( | 811 startup_data.data ? &startup_data : nullptr, true); |
809 std::move(backend_extensions), false, &ready_semaphore, | |
810 startup_data.data ? &startup_data : nullptr, &frontend_channel); | |
811 ready_semaphore.Wait(); | 812 ready_semaphore.Wait(); |
812 UtilsExtension::set_backend_task_runner(&backend_runner); | 813 UtilsExtension::set_backend_task_runner(&backend_runner); |
813 | 814 |
814 task_runners.push_back(&frontend_runner); | 815 task_runners.push_back(&frontend_runner); |
815 task_runners.push_back(&backend_runner); | 816 task_runners.push_back(&backend_runner); |
816 | 817 |
817 for (int i = 1; i < argc; ++i) { | 818 for (int i = 1; i < argc; ++i) { |
818 // Ignore unknown flags. | 819 // Ignore unknown flags. |
819 if (argv[i] == nullptr || argv[i][0] == '-') continue; | 820 if (argv[i] == nullptr || argv[i][0] == '-') continue; |
820 | 821 |
821 bool exists = false; | 822 bool exists = false; |
822 v8::internal::Vector<const char> chars = | 823 v8::internal::Vector<const char> chars = |
823 v8::internal::ReadFile(argv[i], &exists, true); | 824 v8::internal::ReadFile(argv[i], &exists, true); |
824 if (!exists) { | 825 if (!exists) { |
825 fprintf(stderr, "Internal error: script file doesn't exists: %s\n", | 826 fprintf(stderr, "Internal error: script file doesn't exists: %s\n", |
826 argv[i]); | 827 argv[i]); |
827 Exit(); | 828 Exit(); |
828 } | 829 } |
829 frontend_runner.Append( | 830 frontend_runner.Append( |
830 new ExecuteStringTask(chars, frontend_context_group_id)); | 831 new ExecuteStringTask(chars, frontend_context_group_id)); |
831 } | 832 } |
832 | 833 |
833 frontend_runner.Join(); | 834 frontend_runner.Join(); |
834 backend_runner.Join(); | 835 backend_runner.Join(); |
835 | 836 |
836 delete startup_data.data; | 837 delete startup_data.data; |
837 return 0; | 838 return 0; |
838 } | 839 } |
OLD | NEW |