Skip to content

Commit 5a83967

Browse files
addaleaxtargos
authored andcommitted
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. Backport-PR-URL: #23247 PR-URL: #23094 Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Daniel Bevenius <daniel.bevenius@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent 11c6745 commit 5a83967

32 files changed

+141
-204
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
@@ -426,7 +426,6 @@
426426
'src/node_root_certs.h',
427427
'src/node_version.h',
428428
'src/node_watchdog.h',
429-
'src/node_wrap.h',
430429
'src/node_revert.h',
431430
'src/node_i18n.h',
432431
'src/node_worker.h',

src/async_wrap.cc

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

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

434438
void AsyncWrap::Initialize(Local<Object> target,
@@ -524,17 +528,20 @@ void AsyncWrap::Initialize(Local<Object> target,
524528
env->set_async_hooks_promise_resolve_function(Local<Function>());
525529
env->set_async_hooks_binding(target);
526530

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

src/async_wrap.h

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

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

118113
virtual ~AsyncWrap();
119114

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

124118
static void Initialize(v8::Local<v8::Object> target,
125119
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)