2017-05-17 00:30:52 +00:00
|
|
|
// 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 <map>
|
2019-09-13 16:11:40 +00:00
|
|
|
#include <memory>
|
2017-05-17 00:30:52 +00:00
|
|
|
|
|
|
|
#include "include/v8-inspector.h"
|
|
|
|
#include "include/v8-platform.h"
|
|
|
|
#include "include/v8.h"
|
2017-05-22 00:48:27 +00:00
|
|
|
#include "src/base/macros.h"
|
|
|
|
#include "src/base/platform/platform.h"
|
2019-05-23 13:27:57 +00:00
|
|
|
#include "src/utils/vector.h"
|
2017-05-17 00:30:52 +00:00
|
|
|
|
2020-10-27 13:52:22 +00:00
|
|
|
namespace v8 {
|
|
|
|
namespace internal {
|
|
|
|
|
2017-05-17 00:30:52 +00:00
|
|
|
class TaskRunner;
|
|
|
|
|
2020-11-09 13:52:29 +00:00
|
|
|
enum WithInspector : bool { kWithInspector = true, kNoInspector = false };
|
|
|
|
|
2017-05-22 00:48:27 +00:00
|
|
|
class IsolateData : public v8_inspector::V8InspectorClient {
|
2017-05-17 00:30:52 +00:00
|
|
|
public:
|
|
|
|
class SetupGlobalTask {
|
|
|
|
public:
|
|
|
|
virtual ~SetupGlobalTask() = default;
|
|
|
|
virtual void Run(v8::Isolate* isolate,
|
|
|
|
v8::Local<v8::ObjectTemplate> global) = 0;
|
|
|
|
};
|
|
|
|
using SetupGlobalTasks = std::vector<std::unique_ptr<SetupGlobalTask>>;
|
|
|
|
|
2020-11-06 02:39:19 +00:00
|
|
|
IsolateData(const IsolateData&) = delete;
|
|
|
|
IsolateData& operator=(const IsolateData&) = delete;
|
2017-05-17 00:30:52 +00:00
|
|
|
IsolateData(TaskRunner* task_runner, SetupGlobalTasks setup_global_tasks,
|
2020-11-09 13:52:29 +00:00
|
|
|
v8::StartupData* startup_data, WithInspector with_inspector);
|
2017-05-17 00:30:52 +00:00
|
|
|
static IsolateData* FromContext(v8::Local<v8::Context> context);
|
|
|
|
|
2020-11-16 09:20:55 +00:00
|
|
|
~IsolateData() override {
|
|
|
|
// Enter the isolate before destructing this IsolateData, so that
|
|
|
|
// destructors that run before the Isolate's destructor still see it as
|
|
|
|
// entered.
|
|
|
|
isolate()->Enter();
|
|
|
|
}
|
|
|
|
|
2017-11-16 15:29:57 +00:00
|
|
|
v8::Isolate* isolate() const { return isolate_.get(); }
|
2017-05-17 00:30:52 +00:00
|
|
|
TaskRunner* task_runner() const { return task_runner_; }
|
2017-05-22 00:48:27 +00:00
|
|
|
|
|
|
|
// Setting things up.
|
2017-05-17 00:30:52 +00:00
|
|
|
int CreateContextGroup();
|
2020-09-30 22:20:01 +00:00
|
|
|
void CreateContext(int context_group_id, v8_inspector::StringView name);
|
2018-11-06 21:42:48 +00:00
|
|
|
void ResetContextGroup(int context_group_id);
|
2020-09-30 22:20:01 +00:00
|
|
|
v8::Local<v8::Context> GetDefaultContext(int context_group_id);
|
2017-05-18 23:11:20 +00:00
|
|
|
int GetContextGroupId(v8::Local<v8::Context> context);
|
2017-05-17 00:30:52 +00:00
|
|
|
void RegisterModule(v8::Local<v8::Context> context,
|
2020-11-06 12:19:12 +00:00
|
|
|
std::vector<uint16_t> name,
|
2017-05-17 00:30:52 +00:00
|
|
|
v8::ScriptCompiler::Source* source);
|
|
|
|
|
2017-05-22 00:48:27 +00:00
|
|
|
// Working with V8Inspector api.
|
|
|
|
int ConnectSession(int context_group_id,
|
2017-05-22 20:46:42 +00:00
|
|
|
const v8_inspector::StringView& state,
|
|
|
|
v8_inspector::V8Inspector::Channel* channel);
|
2019-05-14 23:07:29 +00:00
|
|
|
std::vector<uint8_t> DisconnectSession(int session_id);
|
2017-05-22 00:48:27 +00:00
|
|
|
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);
|
2017-05-22 20:46:42 +00:00
|
|
|
void AsyncTaskScheduled(const v8_inspector::StringView& name, void* task,
|
|
|
|
bool recurring);
|
|
|
|
void AsyncTaskStarted(void* task);
|
|
|
|
void AsyncTaskFinished(void* task);
|
2017-11-22 19:46:33 +00:00
|
|
|
|
|
|
|
v8_inspector::V8StackTraceId StoreCurrentStackTrace(
|
|
|
|
const v8_inspector::StringView& description);
|
|
|
|
void ExternalAsyncTaskStarted(const v8_inspector::V8StackTraceId& parent);
|
|
|
|
void ExternalAsyncTaskFinished(const v8_inspector::V8StackTraceId& parent);
|
|
|
|
|
2017-06-05 17:37:25 +00:00
|
|
|
void AddInspectedObject(int session_id, v8::Local<v8::Value> object);
|
2017-05-22 00:48:27 +00:00
|
|
|
|
|
|
|
// Test utilities.
|
|
|
|
void SetCurrentTimeMS(double time);
|
|
|
|
void SetMemoryInfo(v8::Local<v8::Value> memory_info);
|
|
|
|
void SetLogConsoleApiMessageCalls(bool log);
|
2017-10-18 18:47:30 +00:00
|
|
|
void SetLogMaxAsyncCallStackDepthChanged(bool log);
|
2020-09-29 19:24:48 +00:00
|
|
|
void SetAdditionalConsoleApi(v8_inspector::StringView api_script);
|
2017-05-22 20:46:42 +00:00
|
|
|
void SetMaxAsyncTaskStacksForTest(int limit);
|
|
|
|
void DumpAsyncTaskStacksStateForTest();
|
2020-09-30 22:20:01 +00:00
|
|
|
void FireContextCreated(v8::Local<v8::Context> context, int context_group_id,
|
|
|
|
v8_inspector::StringView name);
|
2017-05-22 00:48:27 +00:00
|
|
|
void FireContextDestroyed(v8::Local<v8::Context> context);
|
2017-08-01 21:17:31 +00:00
|
|
|
void FreeContext(v8::Local<v8::Context> context);
|
2018-08-09 17:27:00 +00:00
|
|
|
void SetResourceNamePrefix(v8::Local<v8::String> prefix);
|
2017-05-22 00:48:27 +00:00
|
|
|
|
2017-05-17 00:30:52 +00:00
|
|
|
private:
|
|
|
|
static v8::MaybeLocal<v8::Module> ModuleResolveCallback(
|
|
|
|
v8::Local<v8::Context> context, v8::Local<v8::String> specifier,
|
2020-11-25 19:10:03 +00:00
|
|
|
v8::Local<v8::FixedArray> import_assertions,
|
2017-05-17 00:30:52 +00:00
|
|
|
v8::Local<v8::Module> referrer);
|
2017-05-22 00:48:27 +00:00
|
|
|
static void MessageHandler(v8::Local<v8::Message> message,
|
|
|
|
v8::Local<v8::Value> exception);
|
2017-06-01 21:33:59 +00:00
|
|
|
static void PromiseRejectHandler(v8::PromiseRejectMessage data);
|
|
|
|
static int HandleMessage(v8::Local<v8::Message> message,
|
|
|
|
v8::Local<v8::Value> exception);
|
2017-05-22 00:48:27 +00:00
|
|
|
std::vector<int> GetSessionIds(int context_group_id);
|
|
|
|
|
|
|
|
// V8InspectorClient implementation.
|
|
|
|
bool formatAccessorsAsProperties(v8::Local<v8::Value>) override;
|
|
|
|
v8::Local<v8::Context> ensureDefaultContextInGroup(
|
|
|
|
int context_group_id) override;
|
|
|
|
double currentTimeMS() override;
|
|
|
|
v8::MaybeLocal<v8::Value> memoryInfo(v8::Isolate* isolate,
|
|
|
|
v8::Local<v8::Context>) override;
|
|
|
|
void runMessageLoopOnPause(int context_group_id) override;
|
|
|
|
void quitMessageLoopOnPause() override;
|
2020-09-29 19:24:48 +00:00
|
|
|
void installAdditionalCommandLineAPI(v8::Local<v8::Context>,
|
|
|
|
v8::Local<v8::Object>) override;
|
2017-05-22 00:48:27 +00:00
|
|
|
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;
|
2017-08-23 19:40:46 +00:00
|
|
|
bool isInspectableHeapObject(v8::Local<v8::Object>) override;
|
2017-10-18 18:47:30 +00:00
|
|
|
void maxAsyncCallStackDepthChanged(int depth) override;
|
2018-08-09 17:27:00 +00:00
|
|
|
std::unique_ptr<v8_inspector::StringBuffer> resourceNameToUrl(
|
|
|
|
const v8_inspector::StringView& resourceName) override;
|
2020-12-22 07:13:23 +00:00
|
|
|
int64_t generateUniqueId() override;
|
2017-05-17 00:30:52 +00:00
|
|
|
|
2017-11-16 15:29:57 +00:00
|
|
|
// 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 {
|
2020-11-16 09:20:55 +00:00
|
|
|
void operator()(v8::Isolate* isolate) const {
|
|
|
|
// Exit the isolate after it was entered by ~IsolateData.
|
|
|
|
isolate->Exit();
|
|
|
|
isolate->Dispose();
|
|
|
|
}
|
2017-11-16 15:29:57 +00:00
|
|
|
};
|
|
|
|
|
2017-05-17 00:30:52 +00:00
|
|
|
TaskRunner* task_runner_;
|
|
|
|
SetupGlobalTasks setup_global_tasks_;
|
2019-10-02 13:06:22 +00:00
|
|
|
std::unique_ptr<v8::ArrayBuffer::Allocator> array_buffer_allocator_;
|
2017-11-16 15:29:57 +00:00
|
|
|
std::unique_ptr<v8::Isolate, IsolateDeleter> isolate_;
|
2017-05-22 00:48:27 +00:00
|
|
|
std::unique_ptr<v8_inspector::V8Inspector> inspector_;
|
2017-05-17 00:30:52 +00:00
|
|
|
int last_context_group_id_ = 0;
|
2020-09-30 22:20:01 +00:00
|
|
|
std::map<int, std::vector<v8::Global<v8::Context>>> contexts_;
|
2020-11-06 12:19:12 +00:00
|
|
|
std::map<std::vector<uint16_t>, v8::Global<v8::Module>> modules_;
|
2017-05-22 00:48:27 +00:00
|
|
|
int last_session_id_ = 0;
|
|
|
|
std::map<int, std::unique_ptr<v8_inspector::V8InspectorSession>> sessions_;
|
|
|
|
std::map<v8_inspector::V8InspectorSession*, int> context_group_by_session_;
|
|
|
|
v8::Global<v8::Value> memory_info_;
|
|
|
|
bool current_time_set_ = false;
|
|
|
|
double current_time_ = 0.0;
|
|
|
|
bool log_console_api_message_calls_ = false;
|
2017-10-18 18:47:30 +00:00
|
|
|
bool log_max_async_call_stack_depth_changed_ = false;
|
2017-08-23 19:40:46 +00:00
|
|
|
v8::Global<v8::Private> not_inspectable_private_;
|
2018-08-09 17:27:00 +00:00
|
|
|
v8::Global<v8::String> resource_name_prefix_;
|
2020-09-29 19:24:48 +00:00
|
|
|
v8::Global<v8::String> additional_console_api_;
|
2017-05-17 00:30:52 +00:00
|
|
|
};
|
2017-05-22 00:48:27 +00:00
|
|
|
|
2020-10-27 13:52:22 +00:00
|
|
|
} // namespace internal
|
|
|
|
} // namespace v8
|
|
|
|
|
2017-05-17 00:30:52 +00:00
|
|
|
#endif // V8_TEST_INSPECTOR_PROTOCOL_ISOLATE_DATA_H_
|