Skip to content

Commit d527dde

Browse files
committed
src: use JS inheritance for AsyncWrap
For all classes descending from `AsyncWrap`, use JS inheritance instead of manually adding methods to the individual classes. This allows cleanup of some code around transferring handles over IPC. PR-URL: #23094 Reviewed-By: Joyee Cheung <[email protected]> Reviewed-By: Daniel Bevenius <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent 2ebdba1 commit d527dde

30 files changed

+140
-198
lines changed

lib/internal/worker.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@ Object.setPrototypeOf(MessagePort.prototype, EventEmitter.prototype);
7373
delete MessagePort.prototype.stop;
7474
delete MessagePort.prototype.drain;
7575
delete MessagePort.prototype.hasRef;
76-
delete MessagePort.prototype.getAsyncId;
76+
MessagePort.prototype.ref = MessagePortPrototype.ref;
77+
MessagePort.prototype.unref = MessagePortPrototype.unref;
7778

7879
// A communication channel consisting of a handle (that wraps around an
7980
// uv_async_t) which can receive information from other threads and emits

node.gyp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,6 @@
422422
'src/node_root_certs.h',
423423
'src/node_version.h',
424424
'src/node_watchdog.h',
425-
'src/node_wrap.h',
426425
'src/node_revert.h',
427426
'src/node_i18n.h',
428427
'src/node_worker.h',

src/async_wrap.cc

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ struct AsyncWrapObject : public AsyncWrap {
6464
static inline void New(const FunctionCallbackInfo<Value>& args) {
6565
Environment* env = Environment::GetCurrent(args);
6666
CHECK(args.IsConstructCall());
67-
CHECK(env->async_wrap_constructor_template()->HasInstance(args.This()));
67+
CHECK(env->async_wrap_object_ctor_template()->HasInstance(args.This()));
6868
CHECK(args[0]->IsUint32());
6969
auto type = static_cast<ProviderType>(args[0].As<Uint32>()->Value());
7070
new AsyncWrapObject(env, args.This(), type);
@@ -424,12 +424,16 @@ void AsyncWrap::QueueDestroyAsyncId(const FunctionCallbackInfo<Value>& args) {
424424
args[0].As<Number>()->Value());
425425
}
426426

427-
void AsyncWrap::AddWrapMethods(Environment* env,
428-
Local<FunctionTemplate> constructor,
429-
int flag) {
430-
env->SetProtoMethod(constructor, "getAsyncId", AsyncWrap::GetAsyncId);
431-
if (flag & kFlagHasReset)
432-
env->SetProtoMethod(constructor, "asyncReset", AsyncWrap::AsyncReset);
427+
Local<FunctionTemplate> AsyncWrap::GetConstructorTemplate(Environment* env) {
428+
Local<FunctionTemplate> tmpl = env->async_wrap_ctor_template();
429+
if (tmpl.IsEmpty()) {
430+
tmpl = env->NewFunctionTemplate(nullptr);
431+
tmpl->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "AsyncWrap"));
432+
env->SetProtoMethod(tmpl, "getAsyncId", AsyncWrap::GetAsyncId);
433+
env->SetProtoMethod(tmpl, "asyncReset", AsyncWrap::AsyncReset);
434+
env->set_async_wrap_ctor_template(tmpl);
435+
}
436+
return tmpl;
433437
}
434438

435439
void AsyncWrap::Initialize(Local<Object> target,
@@ -525,17 +529,20 @@ void AsyncWrap::Initialize(Local<Object> target,
525529
env->set_async_hooks_promise_resolve_function(Local<Function>());
526530
env->set_async_hooks_binding(target);
527531

532+
// TODO(addaleax): This block might better work as a
533+
// AsyncWrapObject::Initialize() or AsyncWrapObject::GetConstructorTemplate()
534+
// function.
528535
{
529536
auto class_name = FIXED_ONE_BYTE_STRING(env->isolate(), "AsyncWrap");
530537
auto function_template = env->NewFunctionTemplate(AsyncWrapObject::New);
531538
function_template->SetClassName(class_name);
532-
AsyncWrap::AddWrapMethods(env, function_template);
539+
function_template->Inherit(AsyncWrap::GetConstructorTemplate(env));
533540
auto instance_template = function_template->InstanceTemplate();
534541
instance_template->SetInternalFieldCount(1);
535542
auto function =
536543
function_template->GetFunction(env->context()).ToLocalChecked();
537544
target->Set(env->context(), class_name, function).FromJust();
538-
env->set_async_wrap_constructor_template(function_template);
545+
env->set_async_wrap_object_ctor_template(function_template);
539546
}
540547
}
541548

src/async_wrap.h

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -104,21 +104,15 @@ class AsyncWrap : public BaseObject {
104104
PROVIDERS_LENGTH,
105105
};
106106

107-
enum Flags {
108-
kFlagNone = 0x0,
109-
kFlagHasReset = 0x1
110-
};
111-
112107
AsyncWrap(Environment* env,
113108
v8::Local<v8::Object> object,
114109
ProviderType provider,
115110
double execution_async_id = -1);
116111

117112
virtual ~AsyncWrap();
118113

119-
static void AddWrapMethods(Environment* env,
120-
v8::Local<v8::FunctionTemplate> constructor,
121-
int flags = kFlagNone);
114+
static v8::Local<v8::FunctionTemplate> GetConstructorTemplate(
115+
Environment* env);
122116

123117
static void Initialize(v8::Local<v8::Object> target,
124118
v8::Local<v8::Value> unused,

src/cares_wrap.cc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2220,23 +2220,23 @@ void Initialize(Local<Object> target,
22202220

22212221
Local<FunctionTemplate> aiw =
22222222
BaseObject::MakeLazilyInitializedJSTemplate(env);
2223-
AsyncWrap::AddWrapMethods(env, aiw);
2223+
aiw->Inherit(AsyncWrap::GetConstructorTemplate(env));
22242224
Local<String> addrInfoWrapString =
22252225
FIXED_ONE_BYTE_STRING(env->isolate(), "GetAddrInfoReqWrap");
22262226
aiw->SetClassName(addrInfoWrapString);
22272227
target->Set(addrInfoWrapString, aiw->GetFunction(context).ToLocalChecked());
22282228

22292229
Local<FunctionTemplate> niw =
22302230
BaseObject::MakeLazilyInitializedJSTemplate(env);
2231-
AsyncWrap::AddWrapMethods(env, niw);
2231+
niw->Inherit(AsyncWrap::GetConstructorTemplate(env));
22322232
Local<String> nameInfoWrapString =
22332233
FIXED_ONE_BYTE_STRING(env->isolate(), "GetNameInfoReqWrap");
22342234
niw->SetClassName(nameInfoWrapString);
22352235
target->Set(nameInfoWrapString, niw->GetFunction(context).ToLocalChecked());
22362236

22372237
Local<FunctionTemplate> qrw =
22382238
BaseObject::MakeLazilyInitializedJSTemplate(env);
2239-
AsyncWrap::AddWrapMethods(env, qrw);
2239+
qrw->Inherit(AsyncWrap::GetConstructorTemplate(env));
22402240
Local<String> queryWrapString =
22412241
FIXED_ONE_BYTE_STRING(env->isolate(), "QueryReqWrap");
22422242
qrw->SetClassName(queryWrapString);
@@ -2245,7 +2245,7 @@ void Initialize(Local<Object> target,
22452245
Local<FunctionTemplate> channel_wrap =
22462246
env->NewFunctionTemplate(ChannelWrap::New);
22472247
channel_wrap->InstanceTemplate()->SetInternalFieldCount(1);
2248-
AsyncWrap::AddWrapMethods(env, channel_wrap);
2248+
channel_wrap->Inherit(AsyncWrap::GetConstructorTemplate(env));
22492249

22502250
env->SetProtoMethod(channel_wrap, "queryAny", Query<QueryAnyWrap>);
22512251
env->SetProtoMethod(channel_wrap, "queryA", Query<QueryAWrap>);

src/env.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,8 @@ struct PackageConfig {
319319
V(async_hooks_destroy_function, v8::Function) \
320320
V(async_hooks_init_function, v8::Function) \
321321
V(async_hooks_promise_resolve_function, v8::Function) \
322-
V(async_wrap_constructor_template, v8::FunctionTemplate) \
322+
V(async_wrap_object_ctor_template, v8::FunctionTemplate) \
323+
V(async_wrap_ctor_template, v8::FunctionTemplate) \
323324
V(buffer_prototype_object, v8::Object) \
324325
V(context, v8::Context) \
325326
V(domain_callback, v8::Function) \
@@ -329,13 +330,15 @@ struct PackageConfig {
329330
V(filehandlereadwrap_template, v8::ObjectTemplate) \
330331
V(fsreqpromise_constructor_template, v8::ObjectTemplate) \
331332
V(fs_use_promises_symbol, v8::Symbol) \
333+
V(handle_wrap_ctor_template, v8::FunctionTemplate) \
332334
V(host_import_module_dynamically_callback, v8::Function) \
333335
V(host_initialize_import_meta_object_callback, v8::Function) \
334336
V(http2ping_constructor_template, v8::ObjectTemplate) \
335337
V(http2settings_constructor_template, v8::ObjectTemplate) \
336338
V(http2stream_constructor_template, v8::ObjectTemplate) \
337339
V(immediate_callback_function, v8::Function) \
338340
V(inspector_console_api_object, v8::Object) \
341+
V(libuv_stream_wrap_ctor_template, v8::FunctionTemplate) \
339342
V(message_port, v8::Object) \
340343
V(message_port_constructor_template, v8::FunctionTemplate) \
341344
V(pipe_constructor_template, v8::FunctionTemplate) \

src/fs_event_wrap.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ void FSEventWrap::Initialize(Local<Object> target,
105105
t->InstanceTemplate()->SetInternalFieldCount(1);
106106
t->SetClassName(fsevent_string);
107107

108-
AsyncWrap::AddWrapMethods(env, t);
108+
t->Inherit(AsyncWrap::GetConstructorTemplate(env));
109109
env->SetProtoMethod(t, "start", Start);
110110
env->SetProtoMethod(t, "close", Close);
111111

src/handle_wrap.cc

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -130,13 +130,19 @@ void HandleWrap::OnClose(uv_handle_t* handle) {
130130
}
131131
}
132132

133-
134-
void HandleWrap::AddWrapMethods(Environment* env,
135-
Local<FunctionTemplate> t) {
136-
env->SetProtoMethod(t, "close", HandleWrap::Close);
137-
env->SetProtoMethodNoSideEffect(t, "hasRef", HandleWrap::HasRef);
138-
env->SetProtoMethod(t, "ref", HandleWrap::Ref);
139-
env->SetProtoMethod(t, "unref", HandleWrap::Unref);
133+
Local<FunctionTemplate> HandleWrap::GetConstructorTemplate(Environment* env) {
134+
Local<FunctionTemplate> tmpl = env->handle_wrap_ctor_template();
135+
if (tmpl.IsEmpty()) {
136+
tmpl = env->NewFunctionTemplate(nullptr);
137+
tmpl->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "HandleWrap"));
138+
tmpl->Inherit(AsyncWrap::GetConstructorTemplate(env));
139+
env->SetProtoMethod(tmpl, "close", HandleWrap::Close);
140+
env->SetProtoMethodNoSideEffect(tmpl, "hasRef", HandleWrap::HasRef);
141+
env->SetProtoMethod(tmpl, "ref", HandleWrap::Ref);
142+
env->SetProtoMethod(tmpl, "unref", HandleWrap::Unref);
143+
env->set_handle_wrap_ctor_template(tmpl);
144+
}
145+
return tmpl;
140146
}
141147

142148

src/handle_wrap.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,8 @@ class HandleWrap : public AsyncWrap {
7373
virtual void Close(
7474
v8::Local<v8::Value> close_callback = v8::Local<v8::Value>());
7575

76-
static void AddWrapMethods(Environment* env,
77-
v8::Local<v8::FunctionTemplate> constructor);
76+
static v8::Local<v8::FunctionTemplate> GetConstructorTemplate(
77+
Environment* env);
7878

7979
protected:
8080
HandleWrap(Environment* env,

src/inspector_js_api.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ void Initialize(Local<Object> target, Local<Value> unused,
307307
env->NewFunctionTemplate(JSBindingsConnection::New);
308308
tmpl->InstanceTemplate()->SetInternalFieldCount(1);
309309
tmpl->SetClassName(conn_str);
310-
AsyncWrap::AddWrapMethods(env, tmpl);
310+
tmpl->Inherit(AsyncWrap::GetConstructorTemplate(env));
311311
env->SetProtoMethod(tmpl, "dispatch", JSBindingsConnection::Dispatch);
312312
env->SetProtoMethod(tmpl, "disconnect", JSBindingsConnection::Disconnect);
313313
target

0 commit comments

Comments
 (0)