Skip to content

Commit

Permalink
src: add worker per-isolate binding initialization
Browse files Browse the repository at this point in the history
Create worker binding templates in the per-isolate initialization.

PR-URL: #45547
Refs: #42528
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
  • Loading branch information
legendecas authored and RafaelGSS committed Jan 5, 2023
1 parent db535b6 commit 6c5b7e6
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 23 deletions.
6 changes: 6 additions & 0 deletions src/async_wrap-inl.h
Expand Up @@ -80,6 +80,12 @@ inline v8::MaybeLocal<v8::Value> AsyncWrap::MakeCallback(
return MakeCallback(cb_v.As<v8::Function>(), argc, argv);
}

// static
inline v8::Local<v8::FunctionTemplate> AsyncWrap::GetConstructorTemplate(
Environment* env) {
return GetConstructorTemplate(env->isolate_data());
}

} // namespace node

#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
Expand Down
14 changes: 8 additions & 6 deletions src/async_wrap.cc
Expand Up @@ -334,18 +334,20 @@ void AsyncWrap::SetCallbackTrampoline(const FunctionCallbackInfo<Value>& args) {
}
}

Local<FunctionTemplate> AsyncWrap::GetConstructorTemplate(Environment* env) {
Local<FunctionTemplate> tmpl = env->async_wrap_ctor_template();
Local<FunctionTemplate> AsyncWrap::GetConstructorTemplate(
IsolateData* isolate_data) {
Local<FunctionTemplate> tmpl = isolate_data->async_wrap_ctor_template();
if (tmpl.IsEmpty()) {
Isolate* isolate = env->isolate();
Isolate* isolate = isolate_data->isolate();
tmpl = NewFunctionTemplate(isolate, nullptr);
tmpl->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "AsyncWrap"));
tmpl->Inherit(BaseObject::GetConstructorTemplate(env));
tmpl->SetClassName(
FIXED_ONE_BYTE_STRING(isolate_data->isolate(), "AsyncWrap"));
tmpl->Inherit(BaseObject::GetConstructorTemplate(isolate_data));
SetProtoMethod(isolate, tmpl, "getAsyncId", AsyncWrap::GetAsyncId);
SetProtoMethod(isolate, tmpl, "asyncReset", AsyncWrap::AsyncReset);
SetProtoMethod(
isolate, tmpl, "getProviderType", AsyncWrap::GetProviderType);
env->set_async_wrap_ctor_template(tmpl);
isolate_data->set_async_wrap_ctor_template(tmpl);
}
return tmpl;
}
Expand Down
2 changes: 2 additions & 0 deletions src/async_wrap.h
Expand Up @@ -138,6 +138,8 @@ class AsyncWrap : public BaseObject {
static constexpr double kInvalidAsyncId = -1;

static v8::Local<v8::FunctionTemplate> GetConstructorTemplate(
IsolateData* isolate_data);
inline static v8::Local<v8::FunctionTemplate> GetConstructorTemplate(
Environment* env);

static void RegisterExternalReferences(ExternalReferenceRegistry* registry);
Expand Down
1 change: 1 addition & 0 deletions src/inspector_js_api.cc
@@ -1,3 +1,4 @@
#include "async_wrap-inl.h"
#include "base_object-inl.h"
#include "inspector_agent.h"
#include "inspector_io.h"
Expand Down
4 changes: 3 additions & 1 deletion src/node_binding.h
Expand Up @@ -24,7 +24,9 @@ static_assert(static_cast<int>(NM_F_LINKED) ==
static_cast<int>(node::ModuleFlags::kLinked),
"NM_F_LINKED != node::ModuleFlags::kLinked");

#define NODE_BINDINGS_WITH_PER_ISOLATE_INIT(V) V(builtins)
#define NODE_BINDINGS_WITH_PER_ISOLATE_INIT(V) \
V(builtins) \
V(worker)

#define NODE_BINDING_CONTEXT_AWARE_CPP(modname, regfunc, priv, flags) \
static node::node_module _module = { \
Expand Down
35 changes: 23 additions & 12 deletions src/node_worker.cc
Expand Up @@ -34,6 +34,7 @@ using v8::MaybeLocal;
using v8::Null;
using v8::Number;
using v8::Object;
using v8::ObjectTemplate;
using v8::ResourceConstraints;
using v8::SealHandleScope;
using v8::String;
Expand Down Expand Up @@ -876,19 +877,17 @@ void GetEnvMessagePort(const FunctionCallbackInfo<Value>& args) {
}
}

void InitWorker(Local<Object> target,
Local<Value> unused,
Local<Context> context,
void* priv) {
Environment* env = Environment::GetCurrent(context);
Isolate* isolate = env->isolate();
void CreateWorkerPerIsolateProperties(IsolateData* isolate_data,
Local<FunctionTemplate> target) {
Isolate* isolate = isolate_data->isolate();
Local<ObjectTemplate> proto = target->PrototypeTemplate();

{
Local<FunctionTemplate> w = NewFunctionTemplate(isolate, Worker::New);

w->InstanceTemplate()->SetInternalFieldCount(
Worker::kInternalFieldCount);
w->Inherit(AsyncWrap::GetConstructorTemplate(env));
w->Inherit(AsyncWrap::GetConstructorTemplate(isolate_data));

SetProtoMethod(isolate, w, "startThread", Worker::StartThread);
SetProtoMethod(isolate, w, "stopThread", Worker::StopThread);
Expand All @@ -900,23 +899,32 @@ void InitWorker(Local<Object> target,
SetProtoMethod(isolate, w, "loopIdleTime", Worker::LoopIdleTime);
SetProtoMethod(isolate, w, "loopStartTime", Worker::LoopStartTime);

SetConstructorFunction(context, target, "Worker", w);
SetConstructorFunction(isolate, proto, "Worker", w);
}

{
Local<FunctionTemplate> wst = NewFunctionTemplate(isolate, nullptr);

wst->InstanceTemplate()->SetInternalFieldCount(
WorkerHeapSnapshotTaker::kInternalFieldCount);
wst->Inherit(AsyncWrap::GetConstructorTemplate(env));
wst->Inherit(AsyncWrap::GetConstructorTemplate(isolate_data));

Local<String> wst_string =
FIXED_ONE_BYTE_STRING(isolate, "WorkerHeapSnapshotTaker");
wst->SetClassName(wst_string);
env->set_worker_heap_snapshot_taker_template(wst->InstanceTemplate());
isolate_data->set_worker_heap_snapshot_taker_template(
wst->InstanceTemplate());
}

SetMethod(context, target, "getEnvMessagePort", GetEnvMessagePort);
SetMethod(isolate, proto, "getEnvMessagePort", GetEnvMessagePort);
}

void CreateWorkerPerContextProperties(Local<Object> target,
Local<Value> unused,
Local<Context> context,
void* priv) {
Environment* env = Environment::GetCurrent(context);
Isolate* isolate = env->isolate();

target
->Set(env->context(),
Expand Down Expand Up @@ -969,6 +977,9 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
} // namespace worker
} // namespace node

NODE_BINDING_CONTEXT_AWARE_INTERNAL(worker, node::worker::InitWorker)
NODE_BINDING_CONTEXT_AWARE_INTERNAL(
worker, node::worker::CreateWorkerPerContextProperties)
NODE_BINDING_PER_ISOLATE_INIT(worker,
node::worker::CreateWorkerPerIsolateProperties)
NODE_BINDING_EXTERNAL_REFERENCE(worker,
node::worker::RegisterExternalReferences)
31 changes: 27 additions & 4 deletions src/util.cc
Expand Up @@ -56,9 +56,13 @@ static std::atomic_int seq = {0}; // Sequence number for diagnostic filenames.
namespace node {

using v8::ArrayBufferView;
using v8::Context;
using v8::FunctionTemplate;
using v8::Isolate;
using v8::Local;
using v8::Object;
using v8::String;
using v8::Template;
using v8::Value;

template <typename T>
Expand Down Expand Up @@ -482,14 +486,33 @@ void SetConstructorFunction(Local<v8::Context> context,
context, that, OneByteString(isolate, name), tmpl, flag);
}

void SetConstructorFunction(Local<v8::Context> context,
Local<v8::Object> that,
Local<v8::String> name,
Local<v8::FunctionTemplate> tmpl,
void SetConstructorFunction(Local<Context> context,
Local<Object> that,
Local<String> name,
Local<FunctionTemplate> tmpl,
SetConstructorFunctionFlag flag) {
if (LIKELY(flag == SetConstructorFunctionFlag::SET_CLASS_NAME))
tmpl->SetClassName(name);
that->Set(context, name, tmpl->GetFunction(context).ToLocalChecked()).Check();
}

void SetConstructorFunction(Isolate* isolate,
Local<Template> that,
const char* name,
Local<FunctionTemplate> tmpl,
SetConstructorFunctionFlag flag) {
SetConstructorFunction(
isolate, that, OneByteString(isolate, name), tmpl, flag);
}

void SetConstructorFunction(Isolate* isolate,
Local<Template> that,
Local<String> name,
Local<FunctionTemplate> tmpl,
SetConstructorFunctionFlag flag) {
if (LIKELY(flag == SetConstructorFunctionFlag::SET_CLASS_NAME))
tmpl->SetClassName(name);
that->Set(name, tmpl);
}

} // namespace node
14 changes: 14 additions & 0 deletions src/util.h
Expand Up @@ -932,6 +932,20 @@ void SetConstructorFunction(v8::Local<v8::Context> context,
SetConstructorFunctionFlag flag =
SetConstructorFunctionFlag::SET_CLASS_NAME);

void SetConstructorFunction(v8::Isolate* isolate,
v8::Local<v8::Template> that,
const char* name,
v8::Local<v8::FunctionTemplate> tmpl,
SetConstructorFunctionFlag flag =
SetConstructorFunctionFlag::SET_CLASS_NAME);

void SetConstructorFunction(v8::Isolate* isolate,
v8::Local<v8::Template> that,
v8::Local<v8::String> name,
v8::Local<v8::FunctionTemplate> tmpl,
SetConstructorFunctionFlag flag =
SetConstructorFunctionFlag::SET_CLASS_NAME);

} // namespace node

#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
Expand Down

0 comments on commit 6c5b7e6

Please sign in to comment.