| 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 |