aboutsummaryrefslogtreecommitdiff
path: root/deps/v8/test/inspector/isolate-data.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/test/inspector/isolate-data.cc')
-rw-r--r--deps/v8/test/inspector/isolate-data.cc298
1 files changed, 286 insertions, 12 deletions
diff --git a/deps/v8/test/inspector/isolate-data.cc b/deps/v8/test/inspector/isolate-data.cc
index b1e85ede80..74c367a5e9 100644
--- a/deps/v8/test/inspector/isolate-data.cc
+++ b/deps/v8/test/inspector/isolate-data.cc
@@ -4,7 +4,7 @@
#include "test/inspector/isolate-data.h"
-#include "test/inspector/inspector-impl.h"
+#include "src/inspector/test-interface.h"
#include "test/inspector/task-runner.h"
namespace {
@@ -19,12 +19,44 @@ 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 Inspectable : public v8_inspector::V8InspectorSession::Inspectable {
+ public:
+ Inspectable(v8::Isolate* isolate, v8::Local<v8::Value> object)
+ : object_(isolate, object) {}
+ ~Inspectable() override {}
+ v8::Local<v8::Value> get(v8::Local<v8::Context> context) override {
+ return object_.Get(context->GetIsolate());
+ }
+
+ private:
+ v8::Global<v8::Value> object_;
+};
+
} // namespace
IsolateData::IsolateData(TaskRunner* task_runner,
IsolateData::SetupGlobalTasks setup_global_tasks,
- v8::StartupData* startup_data,
- InspectorClientImpl::FrontendChannel* channel)
+ v8::StartupData* startup_data, bool with_inspector)
: task_runner_(task_runner),
setup_global_tasks_(std::move(setup_global_tasks)) {
v8::Isolate::CreateParams params;
@@ -33,8 +65,11 @@ IsolateData::IsolateData(TaskRunner* task_runner,
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 (with_inspector) {
+ isolate_->AddMessageListener(&IsolateData::MessageHandler);
+ isolate_->SetPromiseRejectCallback(&IsolateData::PromiseRejectHandler);
+ inspector_ = v8_inspector::V8Inspector::create(isolate_, this);
+ }
}
IsolateData* IsolateData::FromContext(v8::Local<v8::Context> context) {
@@ -58,7 +93,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;
}
@@ -79,13 +114,16 @@ void IsolateData::RegisterModule(v8::Local<v8::Context> context,
v8::Local<v8::Module> module;
if (!v8::ScriptCompiler::CompileModule(isolate(), source).ToLocal(&module))
return;
- if (!module->Instantiate(context, &IsolateData::ModuleResolveCallback))
+ if (!module->InstantiateModule(context, &IsolateData::ModuleResolveCallback)
+ .FromMaybe(false)) {
return;
+ }
v8::Local<v8::Value> result;
if (!module->Evaluate(context).ToLocal(&result)) return;
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) {
@@ -94,9 +132,245 @@ v8::MaybeLocal<v8::Module> IsolateData::ModuleResolveCallback(
return data->modules_[ToVector(specifier)].Get(data->isolate_);
}
-void IsolateData::FreeContext(v8::Local<v8::Context> context) {
- int context_group_id = GetContextGroupId(context);
- auto it = contexts_.find(context_group_id);
- if (it == contexts_.end()) return;
- contexts_.erase(it);
+int IsolateData::ConnectSession(int context_group_id,
+ const v8_inspector::StringView& state,
+ v8_inspector::V8Inspector::Channel* channel) {
+ int session_id = ++last_session_id_;
+ sessions_[session_id] = inspector_->connect(context_group_id, channel, 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);
+ 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();
+ }
+}
+
+void IsolateData::AsyncTaskScheduled(const v8_inspector::StringView& name,
+ void* task, bool recurring) {
+ inspector_->asyncTaskScheduled(name, task, recurring);
+}
+
+void IsolateData::AsyncTaskStarted(void* task) {
+ inspector_->asyncTaskStarted(task);
+}
+
+void IsolateData::AsyncTaskFinished(void* task) {
+ inspector_->asyncTaskFinished(task);
+}
+
+void IsolateData::AddInspectedObject(int session_id,
+ v8::Local<v8::Value> object) {
+ auto it = sessions_.find(session_id);
+ if (it == sessions_.end()) return;
+ std::unique_ptr<Inspectable> inspectable(new Inspectable(isolate_, object));
+ it->second->addInspectedObject(std::move(inspectable));
+}
+
+void IsolateData::SetMaxAsyncTaskStacksForTest(int limit) {
+ v8_inspector::SetMaxAsyncTaskStacksForTest(inspector_.get(), limit);
+}
+
+void IsolateData::DumpAsyncTaskStacksStateForTest() {
+ v8_inspector::DumpAsyncTaskStacksStateForTest(inspector_.get());
+}
+
+// static
+int IsolateData::HandleMessage(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 0;
+ 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());
+
+ return inspector->exceptionThrown(
+ context, message_text, exception, detailed_message, url, line_number,
+ column_number, inspector->createStackTrace(stack), script_id);
+}
+
+// static
+void IsolateData::MessageHandler(v8::Local<v8::Message> message,
+ v8::Local<v8::Value> exception) {
+ HandleMessage(message, exception);
+}
+
+// static
+void IsolateData::PromiseRejectHandler(v8::PromiseRejectMessage data) {
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+ v8::Local<v8::Context> context = isolate->GetEnteredContext();
+ if (context.IsEmpty()) return;
+ v8::Local<v8::Promise> promise = data.GetPromise();
+ v8::Local<v8::Private> id_private = v8::Private::ForApi(
+ isolate,
+ v8::String::NewFromUtf8(isolate, "id", v8::NewStringType::kNormal)
+ .ToLocalChecked());
+
+ if (data.GetEvent() == v8::kPromiseHandlerAddedAfterReject) {
+ v8::Local<v8::Value> id;
+ if (!promise->GetPrivate(context, id_private).ToLocal(&id)) return;
+ if (!id->IsInt32()) return;
+ v8_inspector::V8Inspector* inspector =
+ IsolateData::FromContext(context)->inspector_.get();
+ const char* reason_str = "Handler added to rejected promise";
+ inspector->exceptionRevoked(
+ context, id.As<v8::Int32>()->Value(),
+ v8_inspector::StringView(reinterpret_cast<const uint8_t*>(reason_str),
+ strlen(reason_str)));
+ return;
+ }
+
+ v8::Local<v8::Value> exception = data.GetValue();
+ int exception_id = HandleMessage(
+ v8::Exception::CreateMessage(isolate, exception), exception);
+ if (exception_id) {
+ promise
+ ->SetPrivate(isolate->GetCurrentContext(), id_private,
+ v8::Int32::New(isolate, exception_id))
+ .ToChecked();
+ }
+}
+
+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");
}