| Index: test/inspector/isolate-data.cc
|
| diff --git a/test/inspector/isolate-data.cc b/test/inspector/isolate-data.cc
|
| index 927bd31ef43e326c594d02488d97833baac3edf4..cdc8cf0e1947283f478b7b57d142100bba9961ef 100644
|
| --- a/test/inspector/isolate-data.cc
|
| +++ b/test/inspector/isolate-data.cc
|
| @@ -4,7 +4,6 @@
|
|
|
| #include "test/inspector/isolate-data.h"
|
|
|
| -#include "test/inspector/inspector-impl.h"
|
| #include "test/inspector/task-runner.h"
|
|
|
| namespace {
|
| @@ -19,22 +18,68 @@ v8::internal::Vector<uint16_t> ToVector(v8::Local<v8::String> str) {
|
| return buffer;
|
| }
|
|
|
| +v8::Local<v8::String> ToString(v8::Isolate* isolate,
|
| + const v8_inspector::StringView& string) {
|
| + if (string.is8Bit())
|
| + return v8::String::NewFromOneByte(isolate, string.characters8(),
|
| + v8::NewStringType::kNormal,
|
| + static_cast<int>(string.length()))
|
| + .ToLocalChecked();
|
| + else
|
| + return v8::String::NewFromTwoByte(isolate, string.characters16(),
|
| + v8::NewStringType::kNormal,
|
| + static_cast<int>(string.length()))
|
| + .ToLocalChecked();
|
| +}
|
| +
|
| +void Print(v8::Isolate* isolate, const v8_inspector::StringView& string) {
|
| + v8::Local<v8::String> v8_string = ToString(isolate, string);
|
| + v8::String::Utf8Value utf8_string(v8_string);
|
| + fwrite(*utf8_string, sizeof(**utf8_string), utf8_string.length(), stdout);
|
| +}
|
| +
|
| +class ChannelImpl final : public v8_inspector::V8Inspector::Channel {
|
| + public:
|
| + ChannelImpl(IsolateData::FrontendChannel* frontend_channel, int session_id)
|
| + : frontend_channel_(frontend_channel), session_id_(session_id) {}
|
| + virtual ~ChannelImpl() = default;
|
| +
|
| + private:
|
| + void sendResponse(
|
| + int callId,
|
| + std::unique_ptr<v8_inspector::StringBuffer> message) override {
|
| + frontend_channel_->SendMessageToFrontend(session_id_, message->string());
|
| + }
|
| + void sendNotification(
|
| + std::unique_ptr<v8_inspector::StringBuffer> message) override {
|
| + frontend_channel_->SendMessageToFrontend(session_id_, message->string());
|
| + }
|
| + void flushProtocolNotifications() override {}
|
| +
|
| + IsolateData::FrontendChannel* frontend_channel_;
|
| + int session_id_;
|
| + DISALLOW_COPY_AND_ASSIGN(ChannelImpl);
|
| +};
|
| +
|
| } // namespace
|
|
|
| IsolateData::IsolateData(TaskRunner* task_runner,
|
| IsolateData::SetupGlobalTasks setup_global_tasks,
|
| v8::StartupData* startup_data,
|
| - InspectorClientImpl::FrontendChannel* channel)
|
| + FrontendChannel* channel)
|
| : task_runner_(task_runner),
|
| - setup_global_tasks_(std::move(setup_global_tasks)) {
|
| + setup_global_tasks_(std::move(setup_global_tasks)),
|
| + frontend_channel_(channel) {
|
| v8::Isolate::CreateParams params;
|
| params.array_buffer_allocator =
|
| v8::ArrayBuffer::Allocator::NewDefaultAllocator();
|
| params.snapshot_blob = startup_data;
|
| isolate_ = v8::Isolate::New(params);
|
| isolate_->SetMicrotasksPolicy(v8::MicrotasksPolicy::kScoped);
|
| - if (channel)
|
| - inspector_.reset(new InspectorClientImpl(isolate_, task_runner, channel));
|
| + if (frontend_channel_) {
|
| + isolate_->AddMessageListener(&IsolateData::MessageHandler);
|
| + inspector_ = v8_inspector::V8Inspector::create(isolate_, this);
|
| + }
|
| }
|
|
|
| IsolateData* IsolateData::FromContext(v8::Local<v8::Context> context) {
|
| @@ -58,7 +103,7 @@ int IsolateData::CreateContextGroup() {
|
| context->SetAlignedPointerInEmbedderData(
|
| kContextGroupIdIndex, reinterpret_cast<void*>(context_group_id * 2));
|
| contexts_[context_group_id].Reset(isolate_, context);
|
| - if (inspector_) inspector_->ContextCreated(context, context_group_id);
|
| + if (inspector_) FireContextCreated(context, context_group_id);
|
| return context_group_id;
|
| }
|
|
|
| @@ -86,6 +131,7 @@ void IsolateData::RegisterModule(v8::Local<v8::Context> context,
|
| modules_[name] = v8::Global<v8::Module>(isolate_, module);
|
| }
|
|
|
| +// static
|
| v8::MaybeLocal<v8::Module> IsolateData::ModuleResolveCallback(
|
| v8::Local<v8::Context> context, v8::Local<v8::String> specifier,
|
| v8::Local<v8::Module> referrer) {
|
| @@ -93,3 +139,177 @@ v8::MaybeLocal<v8::Module> IsolateData::ModuleResolveCallback(
|
| IsolateData* data = IsolateData::FromContext(context);
|
| return data->modules_[ToVector(specifier)].Get(data->isolate_);
|
| }
|
| +
|
| +int IsolateData::ConnectSession(int context_group_id,
|
| + const v8_inspector::StringView& state) {
|
| + int session_id = ++last_session_id_;
|
| + channels_[session_id].reset(new ChannelImpl(frontend_channel_, session_id));
|
| + sessions_[session_id] =
|
| + inspector_->connect(context_group_id, channels_[session_id].get(), state);
|
| + context_group_by_session_[sessions_[session_id].get()] = context_group_id;
|
| + return session_id;
|
| +}
|
| +
|
| +std::unique_ptr<v8_inspector::StringBuffer> IsolateData::DisconnectSession(
|
| + int session_id) {
|
| + auto it = sessions_.find(session_id);
|
| + CHECK(it != sessions_.end());
|
| + context_group_by_session_.erase(it->second.get());
|
| + std::unique_ptr<v8_inspector::StringBuffer> result = it->second->stateJSON();
|
| + sessions_.erase(it);
|
| + channels_.erase(session_id);
|
| + return result;
|
| +}
|
| +
|
| +void IsolateData::SendMessage(int session_id,
|
| + const v8_inspector::StringView& message) {
|
| + auto it = sessions_.find(session_id);
|
| + if (it != sessions_.end()) it->second->dispatchProtocolMessage(message);
|
| +}
|
| +
|
| +void IsolateData::BreakProgram(int context_group_id,
|
| + const v8_inspector::StringView& reason,
|
| + const v8_inspector::StringView& details) {
|
| + for (int session_id : GetSessionIds(context_group_id)) {
|
| + auto it = sessions_.find(session_id);
|
| + if (it != sessions_.end()) it->second->breakProgram(reason, details);
|
| + }
|
| +}
|
| +
|
| +void IsolateData::SchedulePauseOnNextStatement(
|
| + int context_group_id, const v8_inspector::StringView& reason,
|
| + const v8_inspector::StringView& details) {
|
| + for (int session_id : GetSessionIds(context_group_id)) {
|
| + auto it = sessions_.find(session_id);
|
| + if (it != sessions_.end())
|
| + it->second->schedulePauseOnNextStatement(reason, details);
|
| + }
|
| +}
|
| +
|
| +void IsolateData::CancelPauseOnNextStatement(int context_group_id) {
|
| + for (int session_id : GetSessionIds(context_group_id)) {
|
| + auto it = sessions_.find(session_id);
|
| + if (it != sessions_.end()) it->second->cancelPauseOnNextStatement();
|
| + }
|
| +}
|
| +
|
| +// static
|
| +void IsolateData::MessageHandler(v8::Local<v8::Message> message,
|
| + v8::Local<v8::Value> exception) {
|
| + v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
| + v8::Local<v8::Context> context = isolate->GetEnteredContext();
|
| + if (context.IsEmpty()) return;
|
| + v8_inspector::V8Inspector* inspector =
|
| + IsolateData::FromContext(context)->inspector_.get();
|
| +
|
| + v8::Local<v8::StackTrace> stack = message->GetStackTrace();
|
| + int script_id =
|
| + static_cast<int>(message->GetScriptOrigin().ScriptID()->Value());
|
| + if (!stack.IsEmpty() && stack->GetFrameCount() > 0) {
|
| + int top_script_id = stack->GetFrame(0)->GetScriptId();
|
| + if (top_script_id == script_id) script_id = 0;
|
| + }
|
| + int line_number = message->GetLineNumber(context).FromMaybe(0);
|
| + int column_number = 0;
|
| + if (message->GetStartColumn(context).IsJust())
|
| + column_number = message->GetStartColumn(context).FromJust() + 1;
|
| +
|
| + v8_inspector::StringView detailed_message;
|
| + v8::internal::Vector<uint16_t> message_text_string = ToVector(message->Get());
|
| + v8_inspector::StringView message_text(message_text_string.start(),
|
| + message_text_string.length());
|
| + v8::internal::Vector<uint16_t> url_string;
|
| + if (message->GetScriptOrigin().ResourceName()->IsString()) {
|
| + url_string =
|
| + ToVector(message->GetScriptOrigin().ResourceName().As<v8::String>());
|
| + }
|
| + v8_inspector::StringView url(url_string.start(), url_string.length());
|
| +
|
| + inspector->exceptionThrown(context, message_text, exception, detailed_message,
|
| + url, line_number, column_number,
|
| + inspector->createStackTrace(stack), script_id);
|
| +}
|
| +
|
| +void IsolateData::FireContextCreated(v8::Local<v8::Context> context,
|
| + int context_group_id) {
|
| + v8_inspector::V8ContextInfo info(context, context_group_id,
|
| + v8_inspector::StringView());
|
| + info.hasMemoryOnConsole = true;
|
| + inspector_->contextCreated(info);
|
| +}
|
| +
|
| +void IsolateData::FireContextDestroyed(v8::Local<v8::Context> context) {
|
| + inspector_->contextDestroyed(context);
|
| +}
|
| +
|
| +std::vector<int> IsolateData::GetSessionIds(int context_group_id) {
|
| + std::vector<int> result;
|
| + for (auto& it : sessions_) {
|
| + if (context_group_by_session_[it.second.get()] == context_group_id)
|
| + result.push_back(it.first);
|
| + }
|
| + return result;
|
| +}
|
| +
|
| +bool IsolateData::formatAccessorsAsProperties(v8::Local<v8::Value> object) {
|
| + v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
| + v8::Local<v8::Context> context = isolate->GetCurrentContext();
|
| + v8::Local<v8::Private> shouldFormatAccessorsPrivate = v8::Private::ForApi(
|
| + isolate, v8::String::NewFromUtf8(isolate, "allowAccessorFormatting",
|
| + v8::NewStringType::kNormal)
|
| + .ToLocalChecked());
|
| + CHECK(object->IsObject());
|
| + return object.As<v8::Object>()
|
| + ->HasPrivate(context, shouldFormatAccessorsPrivate)
|
| + .FromMaybe(false);
|
| +}
|
| +
|
| +v8::Local<v8::Context> IsolateData::ensureDefaultContextInGroup(
|
| + int context_group_id) {
|
| + return GetContext(context_group_id);
|
| +}
|
| +
|
| +void IsolateData::SetCurrentTimeMS(double time) {
|
| + current_time_ = time;
|
| + current_time_set_ = true;
|
| +}
|
| +
|
| +double IsolateData::currentTimeMS() {
|
| + if (current_time_set_) return current_time_;
|
| + return v8::base::OS::TimeCurrentMillis();
|
| +}
|
| +
|
| +void IsolateData::SetMemoryInfo(v8::Local<v8::Value> memory_info) {
|
| + memory_info_.Reset(isolate_, memory_info);
|
| +}
|
| +
|
| +void IsolateData::SetLogConsoleApiMessageCalls(bool log) {
|
| + log_console_api_message_calls_ = log;
|
| +}
|
| +
|
| +v8::MaybeLocal<v8::Value> IsolateData::memoryInfo(v8::Isolate* isolate,
|
| + v8::Local<v8::Context>) {
|
| + if (memory_info_.IsEmpty()) return v8::MaybeLocal<v8::Value>();
|
| + return memory_info_.Get(isolate);
|
| +}
|
| +
|
| +void IsolateData::runMessageLoopOnPause(int) {
|
| + task_runner_->RunMessageLoop(true);
|
| +}
|
| +
|
| +void IsolateData::quitMessageLoopOnPause() { task_runner_->QuitMessageLoop(); }
|
| +
|
| +void IsolateData::consoleAPIMessage(int contextGroupId,
|
| + v8::Isolate::MessageErrorLevel level,
|
| + const v8_inspector::StringView& message,
|
| + const v8_inspector::StringView& url,
|
| + unsigned lineNumber, unsigned columnNumber,
|
| + v8_inspector::V8StackTrace* stack) {
|
| + if (!log_console_api_message_calls_) return;
|
| + Print(isolate_, message);
|
| + fprintf(stdout, " (");
|
| + Print(isolate_, url);
|
| + fprintf(stdout, ":%d:%d)", lineNumber, columnNumber);
|
| + Print(isolate_, stack->toString()->string());
|
| + fprintf(stdout, "\n");
|
| +}
|
|
|