// Copyright 2017 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef V8_TEST_INSPECTOR_PROTOCOL_ISOLATE_DATA_H_ #define V8_TEST_INSPECTOR_PROTOCOL_ISOLATE_DATA_H_ #include #include "include/v8-inspector.h" #include "include/v8-platform.h" #include "include/v8.h" #include "src/base/macros.h" #include "src/base/platform/platform.h" #include "src/vector.h" class TaskRunner; class IsolateData : public v8_inspector::V8InspectorClient { public: class SetupGlobalTask { public: virtual ~SetupGlobalTask() = default; virtual void Run(v8::Isolate* isolate, v8::Local global) = 0; }; using SetupGlobalTasks = std::vector>; IsolateData(TaskRunner* task_runner, SetupGlobalTasks setup_global_tasks, v8::StartupData* startup_data, bool with_inspector); static IsolateData* FromContext(v8::Local context); v8::Isolate* isolate() const { return isolate_.get(); } TaskRunner* task_runner() const { return task_runner_; } // Setting things up. int CreateContextGroup(); v8::Local GetContext(int context_group_id); int GetContextGroupId(v8::Local context); void RegisterModule(v8::Local context, v8::internal::Vector name, v8::ScriptCompiler::Source* source); // Working with V8Inspector api. int ConnectSession(int context_group_id, const v8_inspector::StringView& state, v8_inspector::V8Inspector::Channel* channel); std::unique_ptr DisconnectSession(int session_id); void SendMessage(int session_id, const v8_inspector::StringView& message); void BreakProgram(int context_group_id, const v8_inspector::StringView& reason, const v8_inspector::StringView& details); void SchedulePauseOnNextStatement(int context_group_id, const v8_inspector::StringView& reason, const v8_inspector::StringView& details); void CancelPauseOnNextStatement(int context_group_id); void AsyncTaskScheduled(const v8_inspector::StringView& name, void* task, bool recurring); void AsyncTaskStarted(void* task); void AsyncTaskFinished(void* task); v8_inspector::V8StackTraceId StoreCurrentStackTrace( const v8_inspector::StringView& description); void ExternalAsyncTaskStarted(const v8_inspector::V8StackTraceId& parent); void ExternalAsyncTaskFinished(const v8_inspector::V8StackTraceId& parent); void AddInspectedObject(int session_id, v8::Local object); // Test utilities. void SetCurrentTimeMS(double time); void SetMemoryInfo(v8::Local memory_info); void SetLogConsoleApiMessageCalls(bool log); void SetLogMaxAsyncCallStackDepthChanged(bool log); void SetMaxAsyncTaskStacksForTest(int limit); void DumpAsyncTaskStacksStateForTest(); void FireContextCreated(v8::Local context, int context_group_id); void FireContextDestroyed(v8::Local context); void FreeContext(v8::Local context); void SetResourceNamePrefix(v8::Local prefix); private: struct VectorCompare { bool operator()(const v8::internal::Vector& lhs, const v8::internal::Vector& rhs) const { for (int i = 0; i < lhs.length() && i < rhs.length(); ++i) { if (lhs[i] != rhs[i]) return lhs[i] < rhs[i]; } return false; } }; static v8::MaybeLocal ModuleResolveCallback( v8::Local context, v8::Local specifier, v8::Local referrer); static void MessageHandler(v8::Local message, v8::Local exception); static void PromiseRejectHandler(v8::PromiseRejectMessage data); static int HandleMessage(v8::Local message, v8::Local exception); std::vector GetSessionIds(int context_group_id); // V8InspectorClient implementation. bool formatAccessorsAsProperties(v8::Local) override; v8::Local ensureDefaultContextInGroup( int context_group_id) override; double currentTimeMS() override; v8::MaybeLocal memoryInfo(v8::Isolate* isolate, v8::Local) override; void runMessageLoopOnPause(int context_group_id) override; void quitMessageLoopOnPause() override; void consoleAPIMessage(int contextGroupId, v8::Isolate::MessageErrorLevel level, const v8_inspector::StringView& message, const v8_inspector::StringView& url, unsigned lineNumber, unsigned columnNumber, v8_inspector::V8StackTrace*) override; bool isInspectableHeapObject(v8::Local) override; void maxAsyncCallStackDepthChanged(int depth) override; std::unique_ptr resourceNameToUrl( const v8_inspector::StringView& resourceName) override; // The isolate gets deleted by its {Dispose} method, not by the default // deleter. Therefore we have to define a custom deleter for the unique_ptr to // call {Dispose}. We have to use the unique_ptr so that the isolate get // disposed in the right order, relative to other member variables. struct IsolateDeleter { void operator()(v8::Isolate* isolate) const { isolate->Dispose(); } }; TaskRunner* task_runner_; SetupGlobalTasks setup_global_tasks_; std::unique_ptr isolate_; std::unique_ptr inspector_; int last_context_group_id_ = 0; std::map> contexts_; std::map, v8::Global, VectorCompare> modules_; int last_session_id_ = 0; std::map> sessions_; std::map context_group_by_session_; v8::Global memory_info_; bool current_time_set_ = false; double current_time_ = 0.0; bool log_console_api_message_calls_ = false; bool log_max_async_call_stack_depth_changed_ = false; v8::Global not_inspectable_private_; v8::Global resource_name_prefix_; DISALLOW_COPY_AND_ASSIGN(IsolateData); }; #endif // V8_TEST_INSPECTOR_PROTOCOL_ISOLATE_DATA_H_