Skip to content

Commit

Permalink
src: create worker per isolate properties
Browse files Browse the repository at this point in the history
PR-URL: #48655
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
  • Loading branch information
legendecas authored and targos committed Nov 23, 2023
1 parent 4a1ce45 commit 5c58341
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 33 deletions.
5 changes: 3 additions & 2 deletions src/node_binding.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,11 @@ static_assert(static_cast<int>(NM_F_LINKED) ==
V(contextify) \
V(encoding_binding) \
V(fs) \
V(messaging) \
V(mksnapshot) \
V(timers) \
V(process_methods) \
V(performance) \
V(process_methods) \
V(timers) \
V(url) \
V(worker) \
NODE_BUILTIN_ICU_BINDINGS(V)
Expand Down
70 changes: 40 additions & 30 deletions src/node_messaging.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ using v8::Maybe;
using v8::MaybeLocal;
using v8::Nothing;
using v8::Object;
using v8::ObjectTemplate;
using v8::SharedArrayBuffer;
using v8::SharedValueConveyor;
using v8::String;
Expand Down Expand Up @@ -717,7 +718,8 @@ MessagePort* MessagePort::New(
std::unique_ptr<MessagePortData> data,
std::shared_ptr<SiblingGroup> sibling_group) {
Context::Scope context_scope(context);
Local<FunctionTemplate> ctor_templ = GetMessagePortConstructorTemplate(env);
Local<FunctionTemplate> ctor_templ =
GetMessagePortConstructorTemplate(env->isolate_data());

// Construct a new instance, then assign the listener instance and possibly
// the MessagePortData to it.
Expand Down Expand Up @@ -1116,7 +1118,8 @@ void MessagePort::Stop(const FunctionCallbackInfo<Value>& args) {
void MessagePort::CheckType(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
args.GetReturnValue().Set(
GetMessagePortConstructorTemplate(env)->HasInstance(args[0]));
GetMessagePortConstructorTemplate(env->isolate_data())
->HasInstance(args[0]));
}

void MessagePort::Drain(const FunctionCallbackInfo<Value>& args) {
Expand Down Expand Up @@ -1193,28 +1196,30 @@ void MessagePort::MemoryInfo(MemoryTracker* tracker) const {
tracker->TrackField("emit_message_fn", emit_message_fn_);
}

Local<FunctionTemplate> GetMessagePortConstructorTemplate(Environment* env) {
Local<FunctionTemplate> GetMessagePortConstructorTemplate(
IsolateData* isolate_data) {
// Factor generating the MessagePort JS constructor into its own piece
// of code, because it is needed early on in the child environment setup.
Local<FunctionTemplate> templ = env->message_port_constructor_template();
Local<FunctionTemplate> templ =
isolate_data->message_port_constructor_template();
if (!templ.IsEmpty())
return templ;

{
Isolate* isolate = env->isolate();
Isolate* isolate = isolate_data->isolate();
Local<FunctionTemplate> m = NewFunctionTemplate(isolate, MessagePort::New);
m->SetClassName(env->message_port_constructor_string());
m->SetClassName(isolate_data->message_port_constructor_string());
m->InstanceTemplate()->SetInternalFieldCount(
MessagePort::kInternalFieldCount);
m->Inherit(HandleWrap::GetConstructorTemplate(env));
m->Inherit(HandleWrap::GetConstructorTemplate(isolate_data));

SetProtoMethod(isolate, m, "postMessage", MessagePort::PostMessage);
SetProtoMethod(isolate, m, "start", MessagePort::Start);

env->set_message_port_constructor_template(m);
isolate_data->set_message_port_constructor_template(m);
}

return GetMessagePortConstructorTemplate(env);
return GetMessagePortConstructorTemplate(isolate_data);
}

// static
Expand Down Expand Up @@ -1636,15 +1641,12 @@ static void BroadcastChannel(const FunctionCallbackInfo<Value>& args) {
}
}

static void InitMessaging(Local<Object> target,
Local<Value> unused,
Local<Context> context,
void* priv) {
Environment* env = Environment::GetCurrent(context);
Isolate* isolate = env->isolate();
static void CreatePerIsolateProperties(IsolateData* isolate_data,
Local<ObjectTemplate> target) {
Isolate* isolate = isolate_data->isolate();

{
SetConstructorFunction(context,
SetConstructorFunction(isolate,
target,
"MessageChannel",
NewFunctionTemplate(isolate, MessageChannel));
Expand All @@ -1655,31 +1657,36 @@ static void InitMessaging(Local<Object> target,
t->InstanceTemplate()->SetInternalFieldCount(
JSTransferable::kInternalFieldCount);
t->SetClassName(OneByteString(isolate, "JSTransferable"));
env->isolate_data()->set_js_transferable_constructor_template(t);
isolate_data->set_js_transferable_constructor_template(t);
}

SetConstructorFunction(context,
SetConstructorFunction(isolate,
target,
env->message_port_constructor_string(),
GetMessagePortConstructorTemplate(env),
SetConstructorFunctionFlag::NONE);
isolate_data->message_port_constructor_string(),
GetMessagePortConstructorTemplate(isolate_data));

// These are not methods on the MessagePort prototype, because
// the browser equivalents do not provide them.
SetMethod(context, target, "stopMessagePort", MessagePort::Stop);
SetMethod(context, target, "checkMessagePort", MessagePort::CheckType);
SetMethod(context, target, "drainMessagePort", MessagePort::Drain);
SetMethod(isolate, target, "stopMessagePort", MessagePort::Stop);
SetMethod(isolate, target, "checkMessagePort", MessagePort::CheckType);
SetMethod(isolate, target, "drainMessagePort", MessagePort::Drain);
SetMethod(
context, target, "receiveMessageOnPort", MessagePort::ReceiveMessage);
isolate, target, "receiveMessageOnPort", MessagePort::ReceiveMessage);
SetMethod(
context, target, "moveMessagePortToContext", MessagePort::MoveToContext);
SetMethod(context,
isolate, target, "moveMessagePortToContext", MessagePort::MoveToContext);
SetMethod(isolate,
target,
"setDeserializerCreateObjectFunction",
SetDeserializerCreateObjectFunction);
SetMethod(context, target, "broadcastChannel", BroadcastChannel);
SetMethod(context, target, "structuredClone", StructuredClone);
SetMethod(isolate, target, "broadcastChannel", BroadcastChannel);
SetMethod(isolate, target, "structuredClone", StructuredClone);
}

static void CreatePerContextProperties(Local<Object> target,
Local<Value> unused,
Local<Context> context,
void* priv) {
Environment* env = Environment::GetCurrent(context);
{
Local<Function> domexception = GetDOMException(context).ToLocalChecked();
target
Expand Down Expand Up @@ -1710,6 +1717,9 @@ static void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
} // namespace worker
} // namespace node

NODE_BINDING_CONTEXT_AWARE_INTERNAL(messaging, node::worker::InitMessaging)
NODE_BINDING_CONTEXT_AWARE_INTERNAL(messaging,
node::worker::CreatePerContextProperties)
NODE_BINDING_PER_ISOLATE_INIT(messaging,
node::worker::CreatePerIsolateProperties)
NODE_BINDING_EXTERNAL_REFERENCE(messaging,
node::worker::RegisterExternalReferences)
2 changes: 1 addition & 1 deletion src/node_messaging.h
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ class JSTransferable : public BaseObject {
};

v8::Local<v8::FunctionTemplate> GetMessagePortConstructorTemplate(
Environment* env);
IsolateData* isolate_data);

} // namespace worker
} // namespace node
Expand Down

0 comments on commit 5c58341

Please sign in to comment.