[inspector] Extract IsolateData out of TaskRunner
This brings clear separation to tasks vs isolate management. BUG=none Review-Url: https://codereview.chromium.org/2885253002 Cr-Commit-Position: refs/heads/master@{#45355}
This commit is contained in:
parent
d7e09f8fcc
commit
578150a5f9
@ -117,7 +117,7 @@ class ConnectTask : public TaskRunner::Task {
|
||||
private:
|
||||
void Run() override {
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
client_->connect(default_context());
|
||||
client_->connect();
|
||||
if (ready_semaphore_) ready_semaphore_->Signal();
|
||||
}
|
||||
|
||||
@ -150,7 +150,7 @@ class DisconnectTask : public TaskRunner::Task {
|
||||
class CreateContextGroupTask : public TaskRunner::Task {
|
||||
public:
|
||||
CreateContextGroupTask(InspectorClientImpl* client,
|
||||
TaskRunner::SetupGlobalTasks setup_global_tasks,
|
||||
IsolateData::SetupGlobalTasks setup_global_tasks,
|
||||
v8::base::Semaphore* ready_semaphore,
|
||||
int* context_group_id)
|
||||
: client_(client),
|
||||
@ -168,7 +168,7 @@ class CreateContextGroupTask : public TaskRunner::Task {
|
||||
}
|
||||
|
||||
InspectorClientImpl* client_;
|
||||
TaskRunner::SetupGlobalTasks setup_global_tasks_;
|
||||
IsolateData::SetupGlobalTasks setup_global_tasks_;
|
||||
v8::base::Semaphore* ready_semaphore_;
|
||||
int* context_group_id_;
|
||||
};
|
||||
@ -184,40 +184,35 @@ InspectorClientImpl::InspectorClientImpl(TaskRunner* task_runner,
|
||||
|
||||
InspectorClientImpl::~InspectorClientImpl() {}
|
||||
|
||||
void InspectorClientImpl::connect(v8::Local<v8::Context> context) {
|
||||
isolate_ = context->GetIsolate();
|
||||
void InspectorClientImpl::connect() {
|
||||
isolate_ = task_runner_->data()->isolate();
|
||||
isolate_->AddMessageListener(MessageHandler);
|
||||
channel_.reset(new ChannelImpl(frontend_channel_));
|
||||
inspector_ = v8_inspector::V8Inspector::create(isolate_, this);
|
||||
|
||||
if (states_.empty()) {
|
||||
int context_group_id = TaskRunner::GetContextGroupId(context);
|
||||
v8_inspector::StringView state;
|
||||
sessions_[context_group_id] =
|
||||
inspector_->connect(context_group_id, channel_.get(), state);
|
||||
context->SetAlignedPointerInEmbedderData(kInspectorClientIndex, this);
|
||||
v8_inspector::V8ContextInfo info(context, context_group_id,
|
||||
v8_inspector::StringView());
|
||||
info.hasMemoryOnConsole = true;
|
||||
inspector_->contextCreated(info);
|
||||
ConnectToContextGroup(task_runner_->default_context_group_id(),
|
||||
v8_inspector::StringView());
|
||||
} else {
|
||||
for (const auto& it : states_) {
|
||||
int context_group_id = it.first;
|
||||
v8::Local<v8::Context> context =
|
||||
task_runner_->GetContext(context_group_id);
|
||||
v8_inspector::StringView state = it.second->string();
|
||||
sessions_[context_group_id] =
|
||||
inspector_->connect(context_group_id, channel_.get(), state);
|
||||
context->SetAlignedPointerInEmbedderData(kInspectorClientIndex, this);
|
||||
v8_inspector::V8ContextInfo info(context, context_group_id,
|
||||
v8_inspector::StringView());
|
||||
info.hasMemoryOnConsole = true;
|
||||
inspector_->contextCreated(info);
|
||||
}
|
||||
for (const auto& it : states_)
|
||||
ConnectToContextGroup(it.first, it.second->string());
|
||||
}
|
||||
states_.clear();
|
||||
}
|
||||
|
||||
void InspectorClientImpl::ConnectToContextGroup(
|
||||
int context_group_id, v8_inspector::StringView state) {
|
||||
v8::Local<v8::Context> context =
|
||||
task_runner_->data()->GetContext(context_group_id);
|
||||
sessions_[context_group_id] =
|
||||
inspector_->connect(context_group_id, channel_.get(), state);
|
||||
context->SetAlignedPointerInEmbedderData(kInspectorClientIndex, this);
|
||||
v8_inspector::V8ContextInfo info(context, context_group_id,
|
||||
v8_inspector::StringView());
|
||||
info.hasMemoryOnConsole = true;
|
||||
inspector_->contextCreated(info);
|
||||
}
|
||||
|
||||
void InspectorClientImpl::scheduleReconnect(
|
||||
v8::base::Semaphore* ready_semaphore) {
|
||||
task_runner_->Append(
|
||||
@ -240,19 +235,19 @@ void InspectorClientImpl::disconnect(bool reset_inspector) {
|
||||
}
|
||||
|
||||
void InspectorClientImpl::scheduleCreateContextGroup(
|
||||
TaskRunner::SetupGlobalTasks setup_global_tasks,
|
||||
IsolateData::SetupGlobalTasks setup_global_tasks,
|
||||
v8::base::Semaphore* ready_semaphore, int* context_group_id) {
|
||||
task_runner_->Append(new CreateContextGroupTask(
|
||||
this, std::move(setup_global_tasks), ready_semaphore, context_group_id));
|
||||
}
|
||||
|
||||
int InspectorClientImpl::createContextGroup(
|
||||
const TaskRunner::SetupGlobalTasks& setup_global_tasks) {
|
||||
const IsolateData::SetupGlobalTasks& setup_global_tasks) {
|
||||
v8::HandleScope handle_scope(isolate_);
|
||||
int context_group_id = task_runner_->data()->CreateContextGroup();
|
||||
v8::Local<v8::Context> context =
|
||||
task_runner_->NewContextGroup(setup_global_tasks);
|
||||
task_runner_->data()->GetContext(context_group_id);
|
||||
context->SetAlignedPointerInEmbedderData(kInspectorClientIndex, this);
|
||||
int context_group_id = TaskRunner::GetContextGroupId(context);
|
||||
v8_inspector::StringView state;
|
||||
sessions_[context_group_id] =
|
||||
inspector_->connect(context_group_id, channel_.get(), state);
|
||||
@ -278,7 +273,7 @@ bool InspectorClientImpl::formatAccessorsAsProperties(
|
||||
v8::Local<v8::Context> InspectorClientImpl::ensureDefaultContextInGroup(
|
||||
int context_group_id) {
|
||||
CHECK(isolate_);
|
||||
return task_runner_->GetContext(context_group_id);
|
||||
return task_runner_->data()->GetContext(context_group_id);
|
||||
}
|
||||
|
||||
void InspectorClientImpl::setCurrentTimeMSForTest(double time) {
|
||||
@ -335,8 +330,12 @@ v8_inspector::V8Inspector* InspectorClientImpl::InspectorFromContext(
|
||||
|
||||
v8_inspector::V8InspectorSession* InspectorClientImpl::SessionFromContext(
|
||||
v8::Local<v8::Context> context) {
|
||||
int context_group_id = TaskRunner::GetContextGroupId(context);
|
||||
return InspectorClientFromContext(context)->sessions_[context_group_id].get();
|
||||
InspectorClientImpl* client = InspectorClientFromContext(context);
|
||||
for (auto& it : client->sessions_) {
|
||||
if (client->task_runner_->data()->GetContext(it.first) == context)
|
||||
return it.second.get();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
v8_inspector::V8InspectorSession* InspectorClientImpl::session(
|
||||
|
@ -28,7 +28,7 @@ class InspectorClientImpl : public v8_inspector::V8InspectorClient {
|
||||
void scheduleReconnect(v8::base::Semaphore* ready_semaphore);
|
||||
void scheduleDisconnect(v8::base::Semaphore* ready_semaphore);
|
||||
void scheduleCreateContextGroup(
|
||||
TaskRunner::SetupGlobalTasks setup_global_tasks,
|
||||
IsolateData::SetupGlobalTasks setup_global_tasks,
|
||||
v8::base::Semaphore* ready_semaphore, int* context_group_id);
|
||||
|
||||
static v8_inspector::V8Inspector* InspectorFromContext(
|
||||
@ -62,12 +62,14 @@ class InspectorClientImpl : public v8_inspector::V8InspectorClient {
|
||||
friend class SendMessageToBackendTask;
|
||||
|
||||
friend class ConnectTask;
|
||||
void connect(v8::Local<v8::Context> context);
|
||||
void connect();
|
||||
void ConnectToContextGroup(int context_group_id,
|
||||
v8_inspector::StringView state);
|
||||
friend class DisconnectTask;
|
||||
void disconnect(bool reset_inspector);
|
||||
friend class CreateContextGroupTask;
|
||||
int createContextGroup(
|
||||
const TaskRunner::SetupGlobalTasks& setup_global_tasks);
|
||||
const IsolateData::SetupGlobalTasks& setup_global_tasks);
|
||||
|
||||
std::unique_ptr<v8_inspector::V8Inspector> inspector_;
|
||||
std::unique_ptr<v8_inspector::V8Inspector::Channel> channel_;
|
||||
@ -88,7 +90,7 @@ class InspectorClientImpl : public v8_inspector::V8InspectorClient {
|
||||
DISALLOW_COPY_AND_ASSIGN(InspectorClientImpl);
|
||||
};
|
||||
|
||||
class SendMessageToBackendExtension : public TaskRunner::SetupGlobalTask {
|
||||
class SendMessageToBackendExtension : public IsolateData::SetupGlobalTask {
|
||||
public:
|
||||
void Run(v8::Isolate* isolate, v8::Local<v8::ObjectTemplate> global) override;
|
||||
|
||||
|
@ -51,7 +51,7 @@ v8::Local<v8::String> ToV8String(v8::Isolate* isolate, const char* str) {
|
||||
.ToLocalChecked();
|
||||
}
|
||||
|
||||
class UtilsExtension : public TaskRunner::SetupGlobalTask {
|
||||
class UtilsExtension : public IsolateData::SetupGlobalTask {
|
||||
public:
|
||||
~UtilsExtension() override = default;
|
||||
void Run(v8::Isolate* isolate,
|
||||
@ -191,7 +191,8 @@ class UtilsExtension : public TaskRunner::SetupGlobalTask {
|
||||
v8::Isolate* isolate = args.GetIsolate();
|
||||
if (ReadFile(isolate, args[0], &chars)) {
|
||||
ExecuteStringTask(chars).RunOnTaskRunner(
|
||||
TaskRunner::FromContext(isolate->GetCurrentContext()));
|
||||
IsolateData::FromContext(isolate->GetCurrentContext())
|
||||
->task_runner());
|
||||
}
|
||||
}
|
||||
|
||||
@ -317,7 +318,7 @@ class SetTimeoutTask : public AsyncTask {
|
||||
v8::Global<v8::Function> function_;
|
||||
};
|
||||
|
||||
class SetTimeoutExtension : public TaskRunner::SetupGlobalTask {
|
||||
class SetTimeoutExtension : public IsolateData::SetupGlobalTask {
|
||||
public:
|
||||
void Run(v8::Isolate* isolate,
|
||||
v8::Local<v8::ObjectTemplate> global) override {
|
||||
@ -350,7 +351,7 @@ class SetTimeoutExtension : public TaskRunner::SetupGlobalTask {
|
||||
v8::Integer::New(isolate, 0), v8::Integer::New(isolate, 0),
|
||||
v8::Boolean::New(isolate, false), "setTimeout", inspector));
|
||||
}
|
||||
TaskRunner::FromContext(context)->Append(task.release());
|
||||
IsolateData::FromContext(context)->task_runner()->Append(task.release());
|
||||
}
|
||||
};
|
||||
|
||||
@ -361,7 +362,7 @@ bool StrictAccessCheck(v8::Local<v8::Context> accessing_context,
|
||||
return accessing_context.IsEmpty();
|
||||
}
|
||||
|
||||
class InspectorExtension : public TaskRunner::SetupGlobalTask {
|
||||
class InspectorExtension : public IsolateData::SetupGlobalTask {
|
||||
public:
|
||||
~InspectorExtension() override = default;
|
||||
void Run(v8::Isolate* isolate,
|
||||
@ -531,7 +532,7 @@ void UtilsExtension::CreateContextGroup(
|
||||
}
|
||||
v8::base::Semaphore ready_semaphore(0);
|
||||
int context_group_id = 0;
|
||||
TaskRunner::SetupGlobalTasks setup_global;
|
||||
IsolateData::SetupGlobalTasks setup_global;
|
||||
setup_global.emplace_back(new SetTimeoutExtension());
|
||||
setup_global.emplace_back(new InspectorExtension());
|
||||
inspector_client_->scheduleCreateContextGroup(
|
||||
@ -609,7 +610,7 @@ int main(int argc, char* argv[]) {
|
||||
}
|
||||
}
|
||||
|
||||
TaskRunner::SetupGlobalTasks backend_extensions;
|
||||
IsolateData::SetupGlobalTasks backend_extensions;
|
||||
backend_extensions.emplace_back(new SetTimeoutExtension());
|
||||
backend_extensions.emplace_back(new InspectorExtension());
|
||||
TaskRunner backend_runner(std::move(backend_extensions), false,
|
||||
@ -619,7 +620,7 @@ int main(int argc, char* argv[]) {
|
||||
SendMessageToBackendExtension::set_backend_task_runner(&backend_runner);
|
||||
UtilsExtension::set_backend_task_runner(&backend_runner);
|
||||
|
||||
TaskRunner::SetupGlobalTasks frontend_extensions;
|
||||
IsolateData::SetupGlobalTasks frontend_extensions;
|
||||
frontend_extensions.emplace_back(new UtilsExtension());
|
||||
frontend_extensions.emplace_back(new SendMessageToBackendExtension());
|
||||
TaskRunner frontend_runner(std::move(frontend_extensions), true,
|
||||
|
@ -12,8 +12,7 @@
|
||||
|
||||
namespace {
|
||||
|
||||
const int kTaskRunnerIndex = 2;
|
||||
const int kContextGroupIdIndex = 3;
|
||||
const int kIsolateDataIndex = 2;
|
||||
|
||||
void ReportUncaughtException(v8::Isolate* isolate,
|
||||
const v8::TryCatch& try_catch) {
|
||||
@ -32,7 +31,65 @@ v8::internal::Vector<uint16_t> ToVector(v8::Local<v8::String> str) {
|
||||
|
||||
} // namespace
|
||||
|
||||
TaskRunner::TaskRunner(TaskRunner::SetupGlobalTasks setup_global_tasks,
|
||||
IsolateData::IsolateData(TaskRunner* task_runner,
|
||||
IsolateData::SetupGlobalTasks setup_global_tasks,
|
||||
v8::StartupData* startup_data)
|
||||
: task_runner_(task_runner),
|
||||
setup_global_tasks_(std::move(setup_global_tasks)) {
|
||||
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);
|
||||
}
|
||||
|
||||
IsolateData* IsolateData::FromContext(v8::Local<v8::Context> context) {
|
||||
return static_cast<IsolateData*>(
|
||||
context->GetAlignedPointerFromEmbedderData(kIsolateDataIndex));
|
||||
}
|
||||
|
||||
int IsolateData::CreateContextGroup() {
|
||||
v8::Local<v8::ObjectTemplate> global_template =
|
||||
v8::ObjectTemplate::New(isolate_);
|
||||
for (auto it = setup_global_tasks_.begin(); it != setup_global_tasks_.end();
|
||||
++it) {
|
||||
(*it)->Run(isolate_, global_template);
|
||||
}
|
||||
v8::Local<v8::Context> context =
|
||||
v8::Context::New(isolate_, nullptr, global_template);
|
||||
context->SetAlignedPointerInEmbedderData(kIsolateDataIndex, this);
|
||||
int context_group_id = ++last_context_group_id_;
|
||||
contexts_[context_group_id].Reset(isolate_, context);
|
||||
return context_group_id;
|
||||
}
|
||||
|
||||
v8::Local<v8::Context> IsolateData::GetContext(int context_group_id) {
|
||||
return contexts_[context_group_id].Get(isolate_);
|
||||
}
|
||||
|
||||
void IsolateData::RegisterModule(v8::Local<v8::Context> context,
|
||||
v8::internal::Vector<uint16_t> name,
|
||||
v8::ScriptCompiler::Source* source) {
|
||||
v8::Local<v8::Module> module;
|
||||
if (!v8::ScriptCompiler::CompileModule(isolate(), source).ToLocal(&module))
|
||||
return;
|
||||
if (!module->Instantiate(context, &IsolateData::ModuleResolveCallback))
|
||||
return;
|
||||
v8::Local<v8::Value> result;
|
||||
if (!module->Evaluate(context).ToLocal(&result)) return;
|
||||
modules_[name] = v8::Global<v8::Module>(isolate_, module);
|
||||
}
|
||||
|
||||
v8::MaybeLocal<v8::Module> IsolateData::ModuleResolveCallback(
|
||||
v8::Local<v8::Context> context, v8::Local<v8::String> specifier,
|
||||
v8::Local<v8::Module> referrer) {
|
||||
std::string str = *v8::String::Utf8Value(specifier);
|
||||
IsolateData* data = IsolateData::FromContext(context);
|
||||
return data->modules_[ToVector(specifier)].Get(data->isolate_);
|
||||
}
|
||||
|
||||
TaskRunner::TaskRunner(IsolateData::SetupGlobalTasks setup_global_tasks,
|
||||
bool catch_exceptions,
|
||||
v8::base::Semaphore* ready_semaphore,
|
||||
v8::StartupData* startup_data)
|
||||
@ -41,7 +98,7 @@ TaskRunner::TaskRunner(TaskRunner::SetupGlobalTasks setup_global_tasks,
|
||||
startup_data_(startup_data),
|
||||
catch_exceptions_(catch_exceptions),
|
||||
ready_semaphore_(ready_semaphore),
|
||||
isolate_(nullptr),
|
||||
data_(nullptr),
|
||||
process_queue_semaphore_(0),
|
||||
nested_loop_count_(0) {
|
||||
Start();
|
||||
@ -49,51 +106,15 @@ TaskRunner::TaskRunner(TaskRunner::SetupGlobalTasks setup_global_tasks,
|
||||
|
||||
TaskRunner::~TaskRunner() { Join(); }
|
||||
|
||||
void TaskRunner::InitializeIsolate() {
|
||||
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);
|
||||
v8::Isolate::Scope isolate_scope(isolate_);
|
||||
v8::HandleScope handle_scope(isolate_);
|
||||
NewContextGroup(setup_global_tasks_);
|
||||
if (ready_semaphore_) ready_semaphore_->Signal();
|
||||
}
|
||||
|
||||
v8::Local<v8::Context> TaskRunner::NewContextGroup(
|
||||
const TaskRunner::SetupGlobalTasks& setup_global_tasks) {
|
||||
v8::Local<v8::ObjectTemplate> global_template =
|
||||
v8::ObjectTemplate::New(isolate_);
|
||||
for (auto it = setup_global_tasks.begin(); it != setup_global_tasks.end();
|
||||
++it) {
|
||||
(*it)->Run(isolate_, global_template);
|
||||
}
|
||||
v8::Local<v8::Context> context =
|
||||
v8::Context::New(isolate_, nullptr, global_template);
|
||||
context->SetAlignedPointerInEmbedderData(kTaskRunnerIndex, this);
|
||||
intptr_t context_group_id = ++last_context_group_id_;
|
||||
// Should be 2-byte aligned.
|
||||
context->SetAlignedPointerInEmbedderData(
|
||||
kContextGroupIdIndex, reinterpret_cast<void*>(context_group_id * 2));
|
||||
contexts_[context_group_id].Reset(isolate_, context);
|
||||
return context;
|
||||
}
|
||||
|
||||
v8::Local<v8::Context> TaskRunner::GetContext(int context_group_id) {
|
||||
return contexts_[context_group_id].Get(isolate_);
|
||||
}
|
||||
|
||||
int TaskRunner::GetContextGroupId(v8::Local<v8::Context> context) {
|
||||
return static_cast<int>(
|
||||
reinterpret_cast<intptr_t>(
|
||||
context->GetAlignedPointerFromEmbedderData(kContextGroupIdIndex)) /
|
||||
2);
|
||||
}
|
||||
|
||||
void TaskRunner::Run() {
|
||||
InitializeIsolate();
|
||||
data_.reset(
|
||||
new IsolateData(this, std::move(setup_global_tasks_), startup_data_));
|
||||
|
||||
v8::Isolate::Scope isolate_scope(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
default_context_group_id_ = data_->CreateContextGroup();
|
||||
|
||||
if (ready_semaphore_) ready_semaphore_->Signal();
|
||||
RunMessageLoop(false);
|
||||
}
|
||||
|
||||
@ -102,13 +123,13 @@ void TaskRunner::RunMessageLoop(bool only_protocol) {
|
||||
while (nested_loop_count_ == loop_number && !is_terminated_.Value()) {
|
||||
TaskRunner::Task* task = GetNext(only_protocol);
|
||||
if (!task) return;
|
||||
v8::Isolate::Scope isolate_scope(isolate_);
|
||||
v8::Isolate::Scope isolate_scope(isolate());
|
||||
if (catch_exceptions_) {
|
||||
v8::TryCatch try_catch(isolate_);
|
||||
v8::TryCatch try_catch(isolate());
|
||||
task->RunOnTaskRunner(this);
|
||||
delete task;
|
||||
if (try_catch.HasCaught()) {
|
||||
ReportUncaughtException(isolate_, try_catch);
|
||||
ReportUncaughtException(isolate(), try_catch);
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
_exit(0);
|
||||
@ -135,19 +156,6 @@ void TaskRunner::Terminate() {
|
||||
process_queue_semaphore_.Signal();
|
||||
}
|
||||
|
||||
void TaskRunner::RegisterModule(v8::internal::Vector<uint16_t> name,
|
||||
v8::Local<v8::Module> module) {
|
||||
modules_[name] = v8::Global<v8::Module>(isolate_, module);
|
||||
}
|
||||
|
||||
v8::MaybeLocal<v8::Module> TaskRunner::ModuleResolveCallback(
|
||||
v8::Local<v8::Context> context, v8::Local<v8::String> specifier,
|
||||
v8::Local<v8::Module> referrer) {
|
||||
std::string str = *v8::String::Utf8Value(specifier);
|
||||
TaskRunner* runner = TaskRunner::FromContext(context);
|
||||
return runner->modules_[ToVector(specifier)].Get(runner->isolate_);
|
||||
}
|
||||
|
||||
TaskRunner::Task* TaskRunner::GetNext(bool only_protocol) {
|
||||
for (;;) {
|
||||
if (is_terminated_.Value()) return nullptr;
|
||||
@ -167,11 +175,6 @@ TaskRunner::Task* TaskRunner::GetNext(bool only_protocol) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TaskRunner* TaskRunner::FromContext(v8::Local<v8::Context> context) {
|
||||
return static_cast<TaskRunner*>(
|
||||
context->GetAlignedPointerFromEmbedderData(kTaskRunnerIndex));
|
||||
}
|
||||
|
||||
AsyncTask::AsyncTask(const char* task_name,
|
||||
v8_inspector::V8Inspector* inspector)
|
||||
: inspector_(task_name ? inspector : nullptr) {
|
||||
@ -250,16 +253,7 @@ void ExecuteStringTask::AsyncRun() {
|
||||
v8::MaybeLocal<v8::Value> result;
|
||||
result = script->Run(context);
|
||||
} else {
|
||||
v8::Local<v8::Module> module;
|
||||
if (!v8::ScriptCompiler::CompileModule(isolate(), &scriptSource)
|
||||
.ToLocal(&module)) {
|
||||
return;
|
||||
}
|
||||
if (!module->Instantiate(context, &TaskRunner::ModuleResolveCallback))
|
||||
return;
|
||||
v8::Local<v8::Value> result;
|
||||
if (!module->Evaluate(context).ToLocal(&result)) return;
|
||||
TaskRunner* runner = TaskRunner::FromContext(context);
|
||||
runner->RegisterModule(name_, module);
|
||||
IsolateData::FromContext(context)->RegisterModule(context, name_,
|
||||
&scriptSource);
|
||||
}
|
||||
}
|
||||
|
@ -16,14 +16,52 @@
|
||||
#include "src/locked-queue-inl.h"
|
||||
#include "src/vector.h"
|
||||
|
||||
struct VectorCompare {
|
||||
bool operator()(const v8::internal::Vector<uint16_t>& lhs,
|
||||
const v8::internal::Vector<uint16_t>& rhs) const {
|
||||
for (int i = 0; i < lhs.length() && i < rhs.length(); ++i) {
|
||||
if (lhs[i] != rhs[i]) return lhs[i] < rhs[i];
|
||||
class TaskRunner;
|
||||
|
||||
class IsolateData {
|
||||
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>>;
|
||||
|
||||
IsolateData(TaskRunner* task_runner, SetupGlobalTasks setup_global_tasks,
|
||||
v8::StartupData* startup_data);
|
||||
static IsolateData* FromContext(v8::Local<v8::Context> context);
|
||||
|
||||
v8::Isolate* isolate() const { return isolate_; }
|
||||
TaskRunner* task_runner() const { return task_runner_; }
|
||||
int CreateContextGroup();
|
||||
v8::Local<v8::Context> GetContext(int context_group_id);
|
||||
void RegisterModule(v8::Local<v8::Context> context,
|
||||
v8::internal::Vector<uint16_t> name,
|
||||
v8::ScriptCompiler::Source* source);
|
||||
|
||||
private:
|
||||
struct VectorCompare {
|
||||
bool operator()(const v8::internal::Vector<uint16_t>& lhs,
|
||||
const v8::internal::Vector<uint16_t>& 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;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
static v8::MaybeLocal<v8::Module> ModuleResolveCallback(
|
||||
v8::Local<v8::Context> context, v8::Local<v8::String> specifier,
|
||||
v8::Local<v8::Module> referrer);
|
||||
|
||||
TaskRunner* task_runner_;
|
||||
SetupGlobalTasks setup_global_tasks_;
|
||||
v8::Isolate* isolate_;
|
||||
int last_context_group_id_ = 0;
|
||||
std::map<int, v8::Global<v8::Context>> contexts_;
|
||||
std::map<v8::internal::Vector<uint16_t>, v8::Global<v8::Module>,
|
||||
VectorCompare>
|
||||
modules_;
|
||||
};
|
||||
|
||||
class TaskRunner : public v8::base::Thread {
|
||||
@ -40,27 +78,22 @@ class TaskRunner : public v8::base::Thread {
|
||||
|
||||
protected:
|
||||
virtual void Run() = 0;
|
||||
v8::Isolate* isolate() const { return task_runner_->isolate_; }
|
||||
v8::Isolate* isolate() const { return task_runner_->data_->isolate(); }
|
||||
v8::Local<v8::Context> default_context() const {
|
||||
return task_runner_->contexts_.begin()->second.Get(isolate());
|
||||
return task_runner_->data_->GetContext(
|
||||
task_runner_->default_context_group_id_);
|
||||
}
|
||||
|
||||
private:
|
||||
TaskRunner* task_runner_ = nullptr;
|
||||
};
|
||||
|
||||
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>>;
|
||||
|
||||
TaskRunner(SetupGlobalTasks setup_global_tasks, bool catch_exceptions,
|
||||
v8::base::Semaphore* ready_semaphore,
|
||||
TaskRunner(IsolateData::SetupGlobalTasks setup_global_tasks,
|
||||
bool catch_exceptions, v8::base::Semaphore* ready_semaphore,
|
||||
v8::StartupData* startup_data);
|
||||
virtual ~TaskRunner();
|
||||
IsolateData* data() const { return data_.get(); }
|
||||
int default_context_group_id() const { return default_context_group_id_; }
|
||||
|
||||
// Thread implementation.
|
||||
void Run() override;
|
||||
@ -72,33 +105,18 @@ class TaskRunner : public v8::base::Thread {
|
||||
// TaskRunner takes ownership.
|
||||
void Append(Task* task);
|
||||
|
||||
static TaskRunner* FromContext(v8::Local<v8::Context>);
|
||||
|
||||
v8::Local<v8::Context> NewContextGroup(
|
||||
const SetupGlobalTasks& setup_global_tasks);
|
||||
v8::Local<v8::Context> GetContext(int context_group_id);
|
||||
static int GetContextGroupId(v8::Local<v8::Context> context);
|
||||
|
||||
void Terminate();
|
||||
|
||||
void RegisterModule(v8::internal::Vector<uint16_t> name,
|
||||
v8::Local<v8::Module> module);
|
||||
static v8::MaybeLocal<v8::Module> ModuleResolveCallback(
|
||||
v8::Local<v8::Context> context, v8::Local<v8::String> specifier,
|
||||
v8::Local<v8::Module> referrer);
|
||||
|
||||
private:
|
||||
void InitializeIsolate();
|
||||
Task* GetNext(bool only_protocol);
|
||||
v8::Isolate* isolate() const { return data_->isolate(); }
|
||||
|
||||
SetupGlobalTasks setup_global_tasks_;
|
||||
IsolateData::SetupGlobalTasks setup_global_tasks_;
|
||||
v8::StartupData* startup_data_;
|
||||
bool catch_exceptions_;
|
||||
v8::base::Semaphore* ready_semaphore_;
|
||||
|
||||
v8::Isolate* isolate_;
|
||||
intptr_t last_context_group_id_ = 0;
|
||||
std::map<intptr_t, v8::Global<v8::Context>> contexts_;
|
||||
std::unique_ptr<IsolateData> data_;
|
||||
int default_context_group_id_;
|
||||
|
||||
// deferred_queue_ combined with queue_ (in this order) have all tasks in the
|
||||
// correct order. Sometimes we skip non-protocol tasks by moving them from
|
||||
@ -107,10 +125,6 @@ class TaskRunner : public v8::base::Thread {
|
||||
v8::internal::LockedQueue<Task*> deffered_queue_;
|
||||
v8::base::Semaphore process_queue_semaphore_;
|
||||
|
||||
std::map<v8::internal::Vector<uint16_t>, v8::Global<v8::Module>,
|
||||
VectorCompare>
|
||||
modules_;
|
||||
|
||||
int nested_loop_count_;
|
||||
|
||||
v8::base::AtomicNumber<int> is_terminated_;
|
||||
|
Loading…
Reference in New Issue
Block a user