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 <[email protected]> Reviewed-By: Daniel Bevenius <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent 11c6745 commit 5a83967

32 files changed

+141
-204
lines changed

lib/internal/worker.js

+2-1
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

-1
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

+16-9
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

+2-8
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

+4-4
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

+4-1
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

+1-1
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

+13-7
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

+2-2
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

+1-1
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

src/js_stream.cc

+1-2
Original file line numberDiff line numberDiff line change
@@ -202,8 +202,7 @@ void JSStream::Initialize(Local<Object> target,
202202
FIXED_ONE_BYTE_STRING(env->isolate(), "JSStream");
203203
t->SetClassName(jsStreamString);
204204
t->InstanceTemplate()->SetInternalFieldCount(1);
205-
206-
AsyncWrap::AddWrapMethods(env, t);
205+
t->Inherit(AsyncWrap::GetConstructorTemplate(env));
207206

208207
env->SetProtoMethod(t, "finishWrite", Finish<WriteWrap>);
209208
env->SetProtoMethod(t, "finishShutdown", Finish<ShutdownWrap>);

src/node_file.cc

+5-5
Original file line numberDiff line numberDiff line change
@@ -2250,7 +2250,7 @@ void Initialize(Local<Object> target,
22502250
// Create FunctionTemplate for FSReqCallback
22512251
Local<FunctionTemplate> fst = env->NewFunctionTemplate(NewFSReqWrap);
22522252
fst->InstanceTemplate()->SetInternalFieldCount(1);
2253-
AsyncWrap::AddWrapMethods(env, fst);
2253+
fst->Inherit(AsyncWrap::GetConstructorTemplate(env));
22542254
Local<String> wrapString = FIXED_ONE_BYTE_STRING(isolate, "FSReqWrap");
22552255
fst->SetClassName(wrapString);
22562256
target
@@ -2262,7 +2262,7 @@ void Initialize(Local<Object> target,
22622262
// to do anything in the constructor, so we only store the instance template.
22632263
Local<FunctionTemplate> fh_rw = FunctionTemplate::New(isolate);
22642264
fh_rw->InstanceTemplate()->SetInternalFieldCount(1);
2265-
AsyncWrap::AddWrapMethods(env, fh_rw);
2265+
fh_rw->Inherit(AsyncWrap::GetConstructorTemplate(env));
22662266
Local<String> fhWrapString =
22672267
FIXED_ONE_BYTE_STRING(isolate, "FileHandleReqWrap");
22682268
fh_rw->SetClassName(fhWrapString);
@@ -2271,7 +2271,7 @@ void Initialize(Local<Object> target,
22712271

22722272
// Create Function Template for FSReqPromise
22732273
Local<FunctionTemplate> fpt = FunctionTemplate::New(isolate);
2274-
AsyncWrap::AddWrapMethods(env, fpt);
2274+
fpt->Inherit(AsyncWrap::GetConstructorTemplate(env));
22752275
Local<String> promiseString =
22762276
FIXED_ONE_BYTE_STRING(isolate, "FSReqPromise");
22772277
fpt->SetClassName(promiseString);
@@ -2281,7 +2281,7 @@ void Initialize(Local<Object> target,
22812281

22822282
// Create FunctionTemplate for FileHandle
22832283
Local<FunctionTemplate> fd = env->NewFunctionTemplate(FileHandle::New);
2284-
AsyncWrap::AddWrapMethods(env, fd);
2284+
fd->Inherit(AsyncWrap::GetConstructorTemplate(env));
22852285
env->SetProtoMethod(fd, "close", FileHandle::Close);
22862286
env->SetProtoMethod(fd, "releaseFD", FileHandle::ReleaseFD);
22872287
Local<ObjectTemplate> fdt = fd->InstanceTemplate();
@@ -2300,7 +2300,7 @@ void Initialize(Local<Object> target,
23002300
Local<FunctionTemplate> fdclose = FunctionTemplate::New(isolate);
23012301
fdclose->SetClassName(FIXED_ONE_BYTE_STRING(isolate,
23022302
"FileHandleCloseReq"));
2303-
AsyncWrap::AddWrapMethods(env, fdclose);
2303+
fdclose->Inherit(AsyncWrap::GetConstructorTemplate(env));
23042304
Local<ObjectTemplate> fdcloset = fdclose->InstanceTemplate();
23052305
fdcloset->SetInternalFieldCount(1);
23062306
env->set_fdclose_constructor_template(fdcloset);

src/node_http2.cc

+4-4
Original file line numberDiff line numberDiff line change
@@ -2960,14 +2960,14 @@ void Initialize(Local<Object> target,
29602960

29612961
Local<FunctionTemplate> ping = FunctionTemplate::New(env->isolate());
29622962
ping->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "Http2Ping"));
2963-
AsyncWrap::AddWrapMethods(env, ping);
2963+
ping->Inherit(AsyncWrap::GetConstructorTemplate(env));
29642964
Local<ObjectTemplate> pingt = ping->InstanceTemplate();
29652965
pingt->SetInternalFieldCount(1);
29662966
env->set_http2ping_constructor_template(pingt);
29672967

29682968
Local<FunctionTemplate> setting = FunctionTemplate::New(env->isolate());
29692969
setting->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "Http2Setting"));
2970-
AsyncWrap::AddWrapMethods(env, setting);
2970+
setting->Inherit(AsyncWrap::GetConstructorTemplate(env));
29712971
Local<ObjectTemplate> settingt = setting->InstanceTemplate();
29722972
settingt->SetInternalFieldCount(1);
29732973
env->set_http2settings_constructor_template(settingt);
@@ -2984,7 +2984,7 @@ void Initialize(Local<Object> target,
29842984
env->SetProtoMethod(stream, "respond", Http2Stream::Respond);
29852985
env->SetProtoMethod(stream, "rstStream", Http2Stream::RstStream);
29862986
env->SetProtoMethod(stream, "refreshState", Http2Stream::RefreshState);
2987-
AsyncWrap::AddWrapMethods(env, stream);
2987+
stream->Inherit(AsyncWrap::GetConstructorTemplate(env));
29882988
StreamBase::AddMethods<Http2Stream>(env, stream);
29892989
Local<ObjectTemplate> streamt = stream->InstanceTemplate();
29902990
streamt->SetInternalFieldCount(1);
@@ -2997,7 +2997,7 @@ void Initialize(Local<Object> target,
29972997
env->NewFunctionTemplate(Http2Session::New);
29982998
session->SetClassName(http2SessionClassName);
29992999
session->InstanceTemplate()->SetInternalFieldCount(1);
3000-
AsyncWrap::AddWrapMethods(env, session);
3000+
session->Inherit(AsyncWrap::GetConstructorTemplate(env));
30013001
env->SetProtoMethod(session, "origin", Http2Session::Origin);
30023002
env->SetProtoMethod(session, "altsvc", Http2Session::AltSvc);
30033003
env->SetProtoMethod(session, "ping", Http2Session::Ping);

src/node_http_parser.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -763,7 +763,7 @@ void Initialize(Local<Object> target,
763763
#undef V
764764
target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "methods"), methods);
765765

766-
AsyncWrap::AddWrapMethods(env, t);
766+
t->Inherit(AsyncWrap::GetConstructorTemplate(env));
767767
env->SetProtoMethod(t, "close", Parser::Close);
768768
env->SetProtoMethod(t, "free", Parser::Free);
769769
env->SetProtoMethod(t, "execute", Parser::Execute);

src/node_messaging.cc

+1-3
Original file line numberDiff line numberDiff line change
@@ -722,9 +722,7 @@ MaybeLocal<Function> GetMessagePortConstructor(
722722
Local<FunctionTemplate> m = env->NewFunctionTemplate(MessagePort::New);
723723
m->SetClassName(env->message_port_constructor_string());
724724
m->InstanceTemplate()->SetInternalFieldCount(1);
725-
726-
AsyncWrap::AddWrapMethods(env, m);
727-
HandleWrap::AddWrapMethods(env, m);
725+
m->Inherit(HandleWrap::GetConstructorTemplate(env));
728726

729727
env->SetProtoMethod(m, "postMessage", MessagePort::PostMessage);
730728
env->SetProtoMethod(m, "start", MessagePort::Start);

src/node_stat_watcher.cc

+1-3
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,7 @@ void StatWatcher::Initialize(Environment* env, Local<Object> target) {
5050
Local<String> statWatcherString =
5151
FIXED_ONE_BYTE_STRING(env->isolate(), "StatWatcher");
5252
t->SetClassName(statWatcherString);
53-
54-
AsyncWrap::AddWrapMethods(env, t);
55-
HandleWrap::AddWrapMethods(env, t);
53+
t->Inherit(HandleWrap::GetConstructorTemplate(env));
5654

5755
env->SetProtoMethod(t, "start", StatWatcher::Start);
5856

src/node_worker.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -481,8 +481,8 @@ void InitWorker(Local<Object> target,
481481
Local<FunctionTemplate> w = env->NewFunctionTemplate(Worker::New);
482482

483483
w->InstanceTemplate()->SetInternalFieldCount(1);
484+
w->Inherit(AsyncWrap::GetConstructorTemplate(env));
484485

485-
AsyncWrap::AddWrapMethods(env, w);
486486
env->SetProtoMethod(w, "startThread", Worker::StartThread);
487487
env->SetProtoMethod(w, "stopThread", Worker::StopThread);
488488
env->SetProtoMethod(w, "ref", Worker::Ref);

0 commit comments

Comments
 (0)