summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/internal/worker.js3
-rw-r--r--node.gyp1
-rw-r--r--src/async_wrap.cc25
-rw-r--r--src/async_wrap.h10
-rw-r--r--src/cares_wrap.cc8
-rw-r--r--src/env.h5
-rw-r--r--src/fs_event_wrap.cc2
-rw-r--r--src/handle_wrap.cc20
-rw-r--r--src/handle_wrap.h4
-rw-r--r--src/inspector_js_api.cc2
-rw-r--r--src/js_stream.cc3
-rw-r--r--src/node_file.cc10
-rw-r--r--src/node_http2.cc8
-rw-r--r--src/node_http_parser.cc2
-rw-r--r--src/node_messaging.cc4
-rw-r--r--src/node_stat_watcher.cc4
-rw-r--r--src/node_worker.cc2
-rw-r--r--src/node_wrap.h72
-rw-r--r--src/node_zlib.cc2
-rw-r--r--src/pipe_wrap.cc7
-rw-r--r--src/process_wrap.cc33
-rw-r--r--src/signal_wrap.cc4
-rw-r--r--src/stream_pipe.cc2
-rw-r--r--src/stream_wrap.cc70
-rw-r--r--src/stream_wrap.h6
-rw-r--r--src/tcp_wrap.cc6
-rw-r--r--src/tls_wrap.cc2
-rw-r--r--src/tty_wrap.cc6
-rw-r--r--src/udp_wrap.cc5
-rw-r--r--test/parallel/test-accessor-properties.js10
30 files changed, 140 insertions, 198 deletions
diff --git a/lib/internal/worker.js b/lib/internal/worker.js
index ceec8469b1..2cffb77e52 100644
--- a/lib/internal/worker.js
+++ b/lib/internal/worker.js
@@ -73,7 +73,8 @@ Object.setPrototypeOf(MessagePort.prototype, EventEmitter.prototype);
delete MessagePort.prototype.stop;
delete MessagePort.prototype.drain;
delete MessagePort.prototype.hasRef;
-delete MessagePort.prototype.getAsyncId;
+MessagePort.prototype.ref = MessagePortPrototype.ref;
+MessagePort.prototype.unref = MessagePortPrototype.unref;
// A communication channel consisting of a handle (that wraps around an
// uv_async_t) which can receive information from other threads and emits
diff --git a/node.gyp b/node.gyp
index baae954d15..38c0a73c51 100644
--- a/node.gyp
+++ b/node.gyp
@@ -422,7 +422,6 @@
'src/node_root_certs.h',
'src/node_version.h',
'src/node_watchdog.h',
- 'src/node_wrap.h',
'src/node_revert.h',
'src/node_i18n.h',
'src/node_worker.h',
diff --git a/src/async_wrap.cc b/src/async_wrap.cc
index b04ab68087..eb67433c39 100644
--- a/src/async_wrap.cc
+++ b/src/async_wrap.cc
@@ -64,7 +64,7 @@ struct AsyncWrapObject : public AsyncWrap {
static inline void New(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
CHECK(args.IsConstructCall());
- CHECK(env->async_wrap_constructor_template()->HasInstance(args.This()));
+ CHECK(env->async_wrap_object_ctor_template()->HasInstance(args.This()));
CHECK(args[0]->IsUint32());
auto type = static_cast<ProviderType>(args[0].As<Uint32>()->Value());
new AsyncWrapObject(env, args.This(), type);
@@ -424,12 +424,16 @@ void AsyncWrap::QueueDestroyAsyncId(const FunctionCallbackInfo<Value>& args) {
args[0].As<Number>()->Value());
}
-void AsyncWrap::AddWrapMethods(Environment* env,
- Local<FunctionTemplate> constructor,
- int flag) {
- env->SetProtoMethod(constructor, "getAsyncId", AsyncWrap::GetAsyncId);
- if (flag & kFlagHasReset)
- env->SetProtoMethod(constructor, "asyncReset", AsyncWrap::AsyncReset);
+Local<FunctionTemplate> AsyncWrap::GetConstructorTemplate(Environment* env) {
+ Local<FunctionTemplate> tmpl = env->async_wrap_ctor_template();
+ if (tmpl.IsEmpty()) {
+ tmpl = env->NewFunctionTemplate(nullptr);
+ tmpl->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "AsyncWrap"));
+ env->SetProtoMethod(tmpl, "getAsyncId", AsyncWrap::GetAsyncId);
+ env->SetProtoMethod(tmpl, "asyncReset", AsyncWrap::AsyncReset);
+ env->set_async_wrap_ctor_template(tmpl);
+ }
+ return tmpl;
}
void AsyncWrap::Initialize(Local<Object> target,
@@ -525,17 +529,20 @@ void AsyncWrap::Initialize(Local<Object> target,
env->set_async_hooks_promise_resolve_function(Local<Function>());
env->set_async_hooks_binding(target);
+ // TODO(addaleax): This block might better work as a
+ // AsyncWrapObject::Initialize() or AsyncWrapObject::GetConstructorTemplate()
+ // function.
{
auto class_name = FIXED_ONE_BYTE_STRING(env->isolate(), "AsyncWrap");
auto function_template = env->NewFunctionTemplate(AsyncWrapObject::New);
function_template->SetClassName(class_name);
- AsyncWrap::AddWrapMethods(env, function_template);
+ function_template->Inherit(AsyncWrap::GetConstructorTemplate(env));
auto instance_template = function_template->InstanceTemplate();
instance_template->SetInternalFieldCount(1);
auto function =
function_template->GetFunction(env->context()).ToLocalChecked();
target->Set(env->context(), class_name, function).FromJust();
- env->set_async_wrap_constructor_template(function_template);
+ env->set_async_wrap_object_ctor_template(function_template);
}
}
diff --git a/src/async_wrap.h b/src/async_wrap.h
index 50864837d6..360380afc3 100644
--- a/src/async_wrap.h
+++ b/src/async_wrap.h
@@ -104,11 +104,6 @@ class AsyncWrap : public BaseObject {
PROVIDERS_LENGTH,
};
- enum Flags {
- kFlagNone = 0x0,
- kFlagHasReset = 0x1
- };
-
AsyncWrap(Environment* env,
v8::Local<v8::Object> object,
ProviderType provider,
@@ -116,9 +111,8 @@ class AsyncWrap : public BaseObject {
virtual ~AsyncWrap();
- static void AddWrapMethods(Environment* env,
- v8::Local<v8::FunctionTemplate> constructor,
- int flags = kFlagNone);
+ static v8::Local<v8::FunctionTemplate> GetConstructorTemplate(
+ Environment* env);
static void Initialize(v8::Local<v8::Object> target,
v8::Local<v8::Value> unused,
diff --git a/src/cares_wrap.cc b/src/cares_wrap.cc
index a967414aec..3187b7d476 100644
--- a/src/cares_wrap.cc
+++ b/src/cares_wrap.cc
@@ -2220,7 +2220,7 @@ void Initialize(Local<Object> target,
Local<FunctionTemplate> aiw =
BaseObject::MakeLazilyInitializedJSTemplate(env);
- AsyncWrap::AddWrapMethods(env, aiw);
+ aiw->Inherit(AsyncWrap::GetConstructorTemplate(env));
Local<String> addrInfoWrapString =
FIXED_ONE_BYTE_STRING(env->isolate(), "GetAddrInfoReqWrap");
aiw->SetClassName(addrInfoWrapString);
@@ -2228,7 +2228,7 @@ void Initialize(Local<Object> target,
Local<FunctionTemplate> niw =
BaseObject::MakeLazilyInitializedJSTemplate(env);
- AsyncWrap::AddWrapMethods(env, niw);
+ niw->Inherit(AsyncWrap::GetConstructorTemplate(env));
Local<String> nameInfoWrapString =
FIXED_ONE_BYTE_STRING(env->isolate(), "GetNameInfoReqWrap");
niw->SetClassName(nameInfoWrapString);
@@ -2236,7 +2236,7 @@ void Initialize(Local<Object> target,
Local<FunctionTemplate> qrw =
BaseObject::MakeLazilyInitializedJSTemplate(env);
- AsyncWrap::AddWrapMethods(env, qrw);
+ qrw->Inherit(AsyncWrap::GetConstructorTemplate(env));
Local<String> queryWrapString =
FIXED_ONE_BYTE_STRING(env->isolate(), "QueryReqWrap");
qrw->SetClassName(queryWrapString);
@@ -2245,7 +2245,7 @@ void Initialize(Local<Object> target,
Local<FunctionTemplate> channel_wrap =
env->NewFunctionTemplate(ChannelWrap::New);
channel_wrap->InstanceTemplate()->SetInternalFieldCount(1);
- AsyncWrap::AddWrapMethods(env, channel_wrap);
+ channel_wrap->Inherit(AsyncWrap::GetConstructorTemplate(env));
env->SetProtoMethod(channel_wrap, "queryAny", Query<QueryAnyWrap>);
env->SetProtoMethod(channel_wrap, "queryA", Query<QueryAWrap>);
diff --git a/src/env.h b/src/env.h
index feeeda661c..a210252643 100644
--- a/src/env.h
+++ b/src/env.h
@@ -319,7 +319,8 @@ struct PackageConfig {
V(async_hooks_destroy_function, v8::Function) \
V(async_hooks_init_function, v8::Function) \
V(async_hooks_promise_resolve_function, v8::Function) \
- V(async_wrap_constructor_template, v8::FunctionTemplate) \
+ V(async_wrap_object_ctor_template, v8::FunctionTemplate) \
+ V(async_wrap_ctor_template, v8::FunctionTemplate) \
V(buffer_prototype_object, v8::Object) \
V(context, v8::Context) \
V(domain_callback, v8::Function) \
@@ -329,6 +330,7 @@ struct PackageConfig {
V(filehandlereadwrap_template, v8::ObjectTemplate) \
V(fsreqpromise_constructor_template, v8::ObjectTemplate) \
V(fs_use_promises_symbol, v8::Symbol) \
+ V(handle_wrap_ctor_template, v8::FunctionTemplate) \
V(host_import_module_dynamically_callback, v8::Function) \
V(host_initialize_import_meta_object_callback, v8::Function) \
V(http2ping_constructor_template, v8::ObjectTemplate) \
@@ -336,6 +338,7 @@ struct PackageConfig {
V(http2stream_constructor_template, v8::ObjectTemplate) \
V(immediate_callback_function, v8::Function) \
V(inspector_console_api_object, v8::Object) \
+ V(libuv_stream_wrap_ctor_template, v8::FunctionTemplate) \
V(message_port, v8::Object) \
V(message_port_constructor_template, v8::FunctionTemplate) \
V(pipe_constructor_template, v8::FunctionTemplate) \
diff --git a/src/fs_event_wrap.cc b/src/fs_event_wrap.cc
index c51054819f..aaf03dcb2b 100644
--- a/src/fs_event_wrap.cc
+++ b/src/fs_event_wrap.cc
@@ -105,7 +105,7 @@ void FSEventWrap::Initialize(Local<Object> target,
t->InstanceTemplate()->SetInternalFieldCount(1);
t->SetClassName(fsevent_string);
- AsyncWrap::AddWrapMethods(env, t);
+ t->Inherit(AsyncWrap::GetConstructorTemplate(env));
env->SetProtoMethod(t, "start", Start);
env->SetProtoMethod(t, "close", Close);
diff --git a/src/handle_wrap.cc b/src/handle_wrap.cc
index 9281300146..d4c5962c35 100644
--- a/src/handle_wrap.cc
+++ b/src/handle_wrap.cc
@@ -130,13 +130,19 @@ void HandleWrap::OnClose(uv_handle_t* handle) {
}
}
-
-void HandleWrap::AddWrapMethods(Environment* env,
- Local<FunctionTemplate> t) {
- env->SetProtoMethod(t, "close", HandleWrap::Close);
- env->SetProtoMethodNoSideEffect(t, "hasRef", HandleWrap::HasRef);
- env->SetProtoMethod(t, "ref", HandleWrap::Ref);
- env->SetProtoMethod(t, "unref", HandleWrap::Unref);
+Local<FunctionTemplate> HandleWrap::GetConstructorTemplate(Environment* env) {
+ Local<FunctionTemplate> tmpl = env->handle_wrap_ctor_template();
+ if (tmpl.IsEmpty()) {
+ tmpl = env->NewFunctionTemplate(nullptr);
+ tmpl->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "HandleWrap"));
+ tmpl->Inherit(AsyncWrap::GetConstructorTemplate(env));
+ env->SetProtoMethod(tmpl, "close", HandleWrap::Close);
+ env->SetProtoMethodNoSideEffect(tmpl, "hasRef", HandleWrap::HasRef);
+ env->SetProtoMethod(tmpl, "ref", HandleWrap::Ref);
+ env->SetProtoMethod(tmpl, "unref", HandleWrap::Unref);
+ env->set_handle_wrap_ctor_template(tmpl);
+ }
+ return tmpl;
}
diff --git a/src/handle_wrap.h b/src/handle_wrap.h
index 443d28bf52..b2722511c3 100644
--- a/src/handle_wrap.h
+++ b/src/handle_wrap.h
@@ -73,8 +73,8 @@ class HandleWrap : public AsyncWrap {
virtual void Close(
v8::Local<v8::Value> close_callback = v8::Local<v8::Value>());
- static void AddWrapMethods(Environment* env,
- v8::Local<v8::FunctionTemplate> constructor);
+ static v8::Local<v8::FunctionTemplate> GetConstructorTemplate(
+ Environment* env);
protected:
HandleWrap(Environment* env,
diff --git a/src/inspector_js_api.cc b/src/inspector_js_api.cc
index 52184111f5..49e1dcc6e8 100644
--- a/src/inspector_js_api.cc
+++ b/src/inspector_js_api.cc
@@ -307,7 +307,7 @@ void Initialize(Local<Object> target, Local<Value> unused,
env->NewFunctionTemplate(JSBindingsConnection::New);
tmpl->InstanceTemplate()->SetInternalFieldCount(1);
tmpl->SetClassName(conn_str);
- AsyncWrap::AddWrapMethods(env, tmpl);
+ tmpl->Inherit(AsyncWrap::GetConstructorTemplate(env));
env->SetProtoMethod(tmpl, "dispatch", JSBindingsConnection::Dispatch);
env->SetProtoMethod(tmpl, "disconnect", JSBindingsConnection::Disconnect);
target
diff --git a/src/js_stream.cc b/src/js_stream.cc
index 9aca2f1d4b..99ea7d870b 100644
--- a/src/js_stream.cc
+++ b/src/js_stream.cc
@@ -202,8 +202,7 @@ void JSStream::Initialize(Local<Object> target,
FIXED_ONE_BYTE_STRING(env->isolate(), "JSStream");
t->SetClassName(jsStreamString);
t->InstanceTemplate()->SetInternalFieldCount(1);
-
- AsyncWrap::AddWrapMethods(env, t);
+ t->Inherit(AsyncWrap::GetConstructorTemplate(env));
env->SetProtoMethod(t, "finishWrite", Finish<WriteWrap>);
env->SetProtoMethod(t, "finishShutdown", Finish<ShutdownWrap>);
diff --git a/src/node_file.cc b/src/node_file.cc
index 6a71ef1124..f4f5b263a6 100644
--- a/src/node_file.cc
+++ b/src/node_file.cc
@@ -2250,7 +2250,7 @@ void Initialize(Local<Object> target,
// Create FunctionTemplate for FSReqCallback
Local<FunctionTemplate> fst = env->NewFunctionTemplate(NewFSReqCallback);
fst->InstanceTemplate()->SetInternalFieldCount(1);
- AsyncWrap::AddWrapMethods(env, fst);
+ fst->Inherit(AsyncWrap::GetConstructorTemplate(env));
Local<String> wrapString =
FIXED_ONE_BYTE_STRING(isolate, "FSReqCallback");
fst->SetClassName(wrapString);
@@ -2263,7 +2263,7 @@ void Initialize(Local<Object> target,
// to do anything in the constructor, so we only store the instance template.
Local<FunctionTemplate> fh_rw = FunctionTemplate::New(isolate);
fh_rw->InstanceTemplate()->SetInternalFieldCount(1);
- AsyncWrap::AddWrapMethods(env, fh_rw);
+ fh_rw->Inherit(AsyncWrap::GetConstructorTemplate(env));
Local<String> fhWrapString =
FIXED_ONE_BYTE_STRING(isolate, "FileHandleReqWrap");
fh_rw->SetClassName(fhWrapString);
@@ -2272,7 +2272,7 @@ void Initialize(Local<Object> target,
// Create Function Template for FSReqPromise
Local<FunctionTemplate> fpt = FunctionTemplate::New(isolate);
- AsyncWrap::AddWrapMethods(env, fpt);
+ fpt->Inherit(AsyncWrap::GetConstructorTemplate(env));
Local<String> promiseString =
FIXED_ONE_BYTE_STRING(isolate, "FSReqPromise");
fpt->SetClassName(promiseString);
@@ -2282,7 +2282,7 @@ void Initialize(Local<Object> target,
// Create FunctionTemplate for FileHandle
Local<FunctionTemplate> fd = env->NewFunctionTemplate(FileHandle::New);
- AsyncWrap::AddWrapMethods(env, fd);
+ fd->Inherit(AsyncWrap::GetConstructorTemplate(env));
env->SetProtoMethod(fd, "close", FileHandle::Close);
env->SetProtoMethod(fd, "releaseFD", FileHandle::ReleaseFD);
Local<ObjectTemplate> fdt = fd->InstanceTemplate();
@@ -2301,7 +2301,7 @@ void Initialize(Local<Object> target,
Local<FunctionTemplate> fdclose = FunctionTemplate::New(isolate);
fdclose->SetClassName(FIXED_ONE_BYTE_STRING(isolate,
"FileHandleCloseReq"));
- AsyncWrap::AddWrapMethods(env, fdclose);
+ fdclose->Inherit(AsyncWrap::GetConstructorTemplate(env));
Local<ObjectTemplate> fdcloset = fdclose->InstanceTemplate();
fdcloset->SetInternalFieldCount(1);
env->set_fdclose_constructor_template(fdcloset);
diff --git a/src/node_http2.cc b/src/node_http2.cc
index 09662b08a4..b95a81e385 100644
--- a/src/node_http2.cc
+++ b/src/node_http2.cc
@@ -2960,14 +2960,14 @@ void Initialize(Local<Object> target,
Local<FunctionTemplate> ping = FunctionTemplate::New(env->isolate());
ping->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "Http2Ping"));
- AsyncWrap::AddWrapMethods(env, ping);
+ ping->Inherit(AsyncWrap::GetConstructorTemplate(env));
Local<ObjectTemplate> pingt = ping->InstanceTemplate();
pingt->SetInternalFieldCount(1);
env->set_http2ping_constructor_template(pingt);
Local<FunctionTemplate> setting = FunctionTemplate::New(env->isolate());
setting->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "Http2Setting"));
- AsyncWrap::AddWrapMethods(env, setting);
+ setting->Inherit(AsyncWrap::GetConstructorTemplate(env));
Local<ObjectTemplate> settingt = setting->InstanceTemplate();
settingt->SetInternalFieldCount(1);
env->set_http2settings_constructor_template(settingt);
@@ -2984,7 +2984,7 @@ void Initialize(Local<Object> target,
env->SetProtoMethod(stream, "respond", Http2Stream::Respond);
env->SetProtoMethod(stream, "rstStream", Http2Stream::RstStream);
env->SetProtoMethod(stream, "refreshState", Http2Stream::RefreshState);
- AsyncWrap::AddWrapMethods(env, stream);
+ stream->Inherit(AsyncWrap::GetConstructorTemplate(env));
StreamBase::AddMethods<Http2Stream>(env, stream);
Local<ObjectTemplate> streamt = stream->InstanceTemplate();
streamt->SetInternalFieldCount(1);
@@ -2997,7 +2997,7 @@ void Initialize(Local<Object> target,
env->NewFunctionTemplate(Http2Session::New);
session->SetClassName(http2SessionClassName);
session->InstanceTemplate()->SetInternalFieldCount(1);
- AsyncWrap::AddWrapMethods(env, session);
+ session->Inherit(AsyncWrap::GetConstructorTemplate(env));
env->SetProtoMethod(session, "origin", Http2Session::Origin);
env->SetProtoMethod(session, "altsvc", Http2Session::AltSvc);
env->SetProtoMethod(session, "ping", Http2Session::Ping);
diff --git a/src/node_http_parser.cc b/src/node_http_parser.cc
index 3236dd4f9f..dcaf3d211a 100644
--- a/src/node_http_parser.cc
+++ b/src/node_http_parser.cc
@@ -763,7 +763,7 @@ void Initialize(Local<Object> target,
#undef V
target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "methods"), methods);
- AsyncWrap::AddWrapMethods(env, t);
+ t->Inherit(AsyncWrap::GetConstructorTemplate(env));
env->SetProtoMethod(t, "close", Parser::Close);
env->SetProtoMethod(t, "free", Parser::Free);
env->SetProtoMethod(t, "execute", Parser::Execute);
diff --git a/src/node_messaging.cc b/src/node_messaging.cc
index 6dd66f243e..0a79d6f9d3 100644
--- a/src/node_messaging.cc
+++ b/src/node_messaging.cc
@@ -722,9 +722,7 @@ MaybeLocal<Function> GetMessagePortConstructor(
Local<FunctionTemplate> m = env->NewFunctionTemplate(MessagePort::New);
m->SetClassName(env->message_port_constructor_string());
m->InstanceTemplate()->SetInternalFieldCount(1);
-
- AsyncWrap::AddWrapMethods(env, m);
- HandleWrap::AddWrapMethods(env, m);
+ m->Inherit(HandleWrap::GetConstructorTemplate(env));
env->SetProtoMethod(m, "postMessage", MessagePort::PostMessage);
env->SetProtoMethod(m, "start", MessagePort::Start);
diff --git a/src/node_stat_watcher.cc b/src/node_stat_watcher.cc
index 91333714b2..ca0927af66 100644
--- a/src/node_stat_watcher.cc
+++ b/src/node_stat_watcher.cc
@@ -50,9 +50,7 @@ void StatWatcher::Initialize(Environment* env, Local<Object> target) {
Local<String> statWatcherString =
FIXED_ONE_BYTE_STRING(env->isolate(), "StatWatcher");
t->SetClassName(statWatcherString);
-
- AsyncWrap::AddWrapMethods(env, t);
- HandleWrap::AddWrapMethods(env, t);
+ t->Inherit(HandleWrap::GetConstructorTemplate(env));
env->SetProtoMethod(t, "start", StatWatcher::Start);
diff --git a/src/node_worker.cc b/src/node_worker.cc
index aee97095a4..63d89a966d 100644
--- a/src/node_worker.cc
+++ b/src/node_worker.cc
@@ -482,8 +482,8 @@ void InitWorker(Local<Object> target,
Local<FunctionTemplate> w = env->NewFunctionTemplate(Worker::New);
w->InstanceTemplate()->SetInternalFieldCount(1);
+ w->Inherit(AsyncWrap::GetConstructorTemplate(env));
- AsyncWrap::AddWrapMethods(env, w);
env->SetProtoMethod(w, "startThread", Worker::StartThread);
env->SetProtoMethod(w, "stopThread", Worker::StopThread);
env->SetProtoMethod(w, "ref", Worker::Ref);
diff --git a/src/node_wrap.h b/src/node_wrap.h
deleted file mode 100644
index 42caca2dc6..0000000000
--- a/src/node_wrap.h
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright Joyent, Inc. and other Node contributors.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to permit
-// persons to whom the Software is furnished to do so, subject to the
-// following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
-// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-#ifndef SRC_NODE_WRAP_H_
-#define SRC_NODE_WRAP_H_
-
-#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
-
-#include "env.h"
-#include "pipe_wrap.h"
-#include "tcp_wrap.h"
-#include "tty_wrap.h"
-#include "uv.h"
-#include "v8.h"
-
-namespace node {
-
-// TODO(addaleax): Use real inheritance for the JS object templates to avoid
-// this unnecessary case switching.
-#define WITH_GENERIC_UV_STREAM(env, obj, BODY) \
- do { \
- if (env->tcp_constructor_template().IsEmpty() == false && \
- env->tcp_constructor_template()->HasInstance(obj)) { \
- TCPWrap* const wrap = Unwrap<TCPWrap>(obj); \
- BODY \
- } else if (env->tty_constructor_template().IsEmpty() == false && \
- env->tty_constructor_template()->HasInstance(obj)) { \
- TTYWrap* const wrap = Unwrap<TTYWrap>(obj); \
- BODY \
- } else if (env->pipe_constructor_template().IsEmpty() == false && \
- env->pipe_constructor_template()->HasInstance(obj)) { \
- PipeWrap* const wrap = Unwrap<PipeWrap>(obj); \
- BODY \
- } \
- } while (0)
-
-inline uv_stream_t* HandleToStream(Environment* env,
- v8::Local<v8::Object> obj) {
- v8::HandleScope scope(env->isolate());
-
- WITH_GENERIC_UV_STREAM(env, obj, {
- if (wrap == nullptr)
- return nullptr;
- return reinterpret_cast<uv_stream_t*>(wrap->UVHandle());
- });
-
- return nullptr;
-}
-
-} // namespace node
-
-#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
-
-#endif // SRC_NODE_WRAP_H_
diff --git a/src/node_zlib.cc b/src/node_zlib.cc
index d0cc54c943..93dcf0122d 100644
--- a/src/node_zlib.cc
+++ b/src/node_zlib.cc
@@ -755,8 +755,8 @@ void Initialize(Local<Object> target,
Local<FunctionTemplate> z = env->NewFunctionTemplate(ZCtx::New);
z->InstanceTemplate()->SetInternalFieldCount(1);
+ z->Inherit(AsyncWrap::GetConstructorTemplate(env));
- AsyncWrap::AddWrapMethods(env, z);
env->SetProtoMethod(z, "write", ZCtx::Write<true>);
env->SetProtoMethod(z, "writeSync", ZCtx::Write<false>);
env->SetProtoMethod(z, "init", ZCtx::Init);
diff --git a/src/pipe_wrap.cc b/src/pipe_wrap.cc
index f3317ecc8c..eb1e06876c 100644
--- a/src/pipe_wrap.cc
+++ b/src/pipe_wrap.cc
@@ -28,7 +28,6 @@
#include "node.h"
#include "node_buffer.h"
#include "node_internals.h"
-#include "node_wrap.h"
#include "connect_wrap.h"
#include "stream_base-inl.h"
#include "stream_wrap.h"
@@ -78,9 +77,7 @@ void PipeWrap::Initialize(Local<Object> target,
t->SetClassName(pipeString);
t->InstanceTemplate()->SetInternalFieldCount(1);
- AsyncWrap::AddWrapMethods(env, t);
- HandleWrap::AddWrapMethods(env, t);
- LibuvStreamWrap::AddMethods(env, t);
+ t->Inherit(LibuvStreamWrap::GetConstructorTemplate(env));
env->SetProtoMethod(t, "bind", Bind);
env->SetProtoMethod(t, "listen", Listen);
@@ -98,7 +95,7 @@ void PipeWrap::Initialize(Local<Object> target,
// Create FunctionTemplate for PipeConnectWrap.
auto cwt = BaseObject::MakeLazilyInitializedJSTemplate(env);
- AsyncWrap::AddWrapMethods(env, cwt);
+ cwt->Inherit(AsyncWrap::GetConstructorTemplate(env));
Local<String> wrapString =
FIXED_ONE_BYTE_STRING(env->isolate(), "PipeConnectWrap");
cwt->SetClassName(wrapString);
diff --git a/src/process_wrap.cc b/src/process_wrap.cc
index 1daa437b29..af6cbfb4e5 100644
--- a/src/process_wrap.cc
+++ b/src/process_wrap.cc
@@ -20,10 +20,9 @@
// USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "env-inl.h"
-#include "handle_wrap.h"
#include "node_internals.h"
-#include "node_wrap.h"
#include "stream_base-inl.h"
+#include "stream_wrap.h"
#include "util-inl.h"
#include <string.h>
@@ -58,8 +57,7 @@ class ProcessWrap : public HandleWrap {
FIXED_ONE_BYTE_STRING(env->isolate(), "Process");
constructor->SetClassName(processString);
- AsyncWrap::AddWrapMethods(env, constructor);
- HandleWrap::AddWrapMethods(env, constructor);
+ constructor->Inherit(HandleWrap::GetConstructorTemplate(env));
env->SetProtoMethod(constructor, "spawn", Spawn);
env->SetProtoMethod(constructor, "kill", Kill);
@@ -92,6 +90,17 @@ class ProcessWrap : public HandleWrap {
MarkAsUninitialized();
}
+ static uv_stream_t* StreamForWrap(Environment* env, Local<Object> stdio) {
+ Local<String> handle_key = env->handle_string();
+ // This property has always been set by JS land if we are in this code path.
+ Local<Object> handle =
+ stdio->Get(env->context(), handle_key).ToLocalChecked().As<Object>();
+
+ uv_stream_t* stream = LibuvStreamWrap::From(env, handle)->stream();
+ CHECK_NOT_NULL(stream);
+ return stream;
+ }
+
static void ParseStdioOptions(Environment* env,
Local<Object> js_options,
uv_process_options_t* options) {
@@ -115,22 +124,10 @@ class ProcessWrap : public HandleWrap {
} else if (type->StrictEquals(env->pipe_string())) {
options->stdio[i].flags = static_cast<uv_stdio_flags>(
UV_CREATE_PIPE | UV_READABLE_PIPE | UV_WRITABLE_PIPE);
- Local<String> handle_key = env->handle_string();
- Local<Object> handle =
- stdio->Get(context, handle_key).ToLocalChecked().As<Object>();
- CHECK(!handle.IsEmpty());
- options->stdio[i].data.stream =
- reinterpret_cast<uv_stream_t*>(
- Unwrap<PipeWrap>(handle)->UVHandle());
+ options->stdio[i].data.stream = StreamForWrap(env, stdio);
} else if (type->StrictEquals(env->wrap_string())) {
- Local<String> handle_key = env->handle_string();
- Local<Object> handle =
- stdio->Get(context, handle_key).ToLocalChecked().As<Object>();
- uv_stream_t* stream = HandleToStream(env, handle);
- CHECK_NOT_NULL(stream);
-
options->stdio[i].flags = UV_INHERIT_STREAM;
- options->stdio[i].data.stream = stream;
+ options->stdio[i].data.stream = StreamForWrap(env, stdio);
} else {
Local<String> fd_key = env->fd_string();
Local<Value> fd_value = stdio->Get(context, fd_key).ToLocalChecked();
diff --git a/src/signal_wrap.cc b/src/signal_wrap.cc
index b9ec037b45..e1792a0267 100644
--- a/src/signal_wrap.cc
+++ b/src/signal_wrap.cc
@@ -50,9 +50,7 @@ class SignalWrap : public HandleWrap {
Local<String> signalString =
FIXED_ONE_BYTE_STRING(env->isolate(), "Signal");
constructor->SetClassName(signalString);
-
- AsyncWrap::AddWrapMethods(env, constructor);
- HandleWrap::AddWrapMethods(env, constructor);
+ constructor->Inherit(HandleWrap::GetConstructorTemplate(env));
env->SetProtoMethod(constructor, "start", Start);
env->SetProtoMethod(constructor, "stop", Stop);
diff --git a/src/stream_pipe.cc b/src/stream_pipe.cc
index 90da2043af..0b00f225d8 100644
--- a/src/stream_pipe.cc
+++ b/src/stream_pipe.cc
@@ -257,7 +257,7 @@ void InitializeStreamPipe(Local<Object> target,
FIXED_ONE_BYTE_STRING(env->isolate(), "StreamPipe");
env->SetProtoMethod(pipe, "unpipe", StreamPipe::Unpipe);
env->SetProtoMethod(pipe, "start", StreamPipe::Start);
- AsyncWrap::AddWrapMethods(env, pipe);
+ pipe->Inherit(AsyncWrap::GetConstructorTemplate(env));
pipe->SetClassName(stream_pipe_string);
pipe->InstanceTemplate()->SetInternalFieldCount(1);
target
diff --git a/src/stream_wrap.cc b/src/stream_wrap.cc
index 9738d2a53b..9ccace435c 100644
--- a/src/stream_wrap.cc
+++ b/src/stream_wrap.cc
@@ -66,7 +66,7 @@ void LibuvStreamWrap::Initialize(Local<Object> target,
Local<String> wrapString =
FIXED_ONE_BYTE_STRING(env->isolate(), "ShutdownWrap");
sw->SetClassName(wrapString);
- AsyncWrap::AddWrapMethods(env, sw);
+ sw->Inherit(AsyncWrap::GetConstructorTemplate(env));
target->Set(wrapString, sw->GetFunction(env->context()).ToLocalChecked());
env->set_shutdown_wrap_template(sw->InstanceTemplate());
@@ -76,7 +76,7 @@ void LibuvStreamWrap::Initialize(Local<Object> target,
Local<String> writeWrapString =
FIXED_ONE_BYTE_STRING(env->isolate(), "WriteWrap");
ww->SetClassName(writeWrapString);
- AsyncWrap::AddWrapMethods(env, ww);
+ ww->Inherit(AsyncWrap::GetConstructorTemplate(env));
target->Set(writeWrapString,
ww->GetFunction(env->context()).ToLocalChecked());
env->set_write_wrap_template(ww->InstanceTemplate());
@@ -96,20 +96,36 @@ LibuvStreamWrap::LibuvStreamWrap(Environment* env,
}
-void LibuvStreamWrap::AddMethods(Environment* env,
- v8::Local<v8::FunctionTemplate> target) {
- Local<FunctionTemplate> get_write_queue_size =
- FunctionTemplate::New(env->isolate(),
- GetWriteQueueSize,
- env->as_external(),
- Signature::New(env->isolate(), target));
- target->PrototypeTemplate()->SetAccessorProperty(
- env->write_queue_size_string(),
- get_write_queue_size,
- Local<FunctionTemplate>(),
- static_cast<PropertyAttribute>(ReadOnly | DontDelete));
- env->SetProtoMethod(target, "setBlocking", SetBlocking);
- StreamBase::AddMethods<LibuvStreamWrap>(env, target);
+Local<FunctionTemplate> LibuvStreamWrap::GetConstructorTemplate(
+ Environment* env) {
+ Local<FunctionTemplate> tmpl = env->libuv_stream_wrap_ctor_template();
+ if (tmpl.IsEmpty()) {
+ tmpl = env->NewFunctionTemplate(nullptr);
+ tmpl->SetClassName(
+ FIXED_ONE_BYTE_STRING(env->isolate(), "LibuvStreamWrap"));
+ tmpl->Inherit(HandleWrap::GetConstructorTemplate(env));
+ Local<FunctionTemplate> get_write_queue_size =
+ FunctionTemplate::New(env->isolate(),
+ GetWriteQueueSize,
+ env->as_external(),
+ Signature::New(env->isolate(), tmpl));
+ tmpl->PrototypeTemplate()->SetAccessorProperty(
+ env->write_queue_size_string(),
+ get_write_queue_size,
+ Local<FunctionTemplate>(),
+ static_cast<PropertyAttribute>(ReadOnly | DontDelete));
+ env->SetProtoMethod(tmpl, "setBlocking", SetBlocking);
+ StreamBase::AddMethods<LibuvStreamWrap>(env, tmpl);
+ env->set_libuv_stream_wrap_ctor_template(tmpl);
+ }
+ return tmpl;
+}
+
+
+LibuvStreamWrap* LibuvStreamWrap::From(Environment* env, Local<Object> object) {
+ Local<FunctionTemplate> sw = env->libuv_stream_wrap_ctor_template();
+ CHECK(!sw.IsEmpty() && sw->HasInstance(object));
+ return Unwrap<LibuvStreamWrap>(object);
}
@@ -170,21 +186,25 @@ void LibuvStreamWrap::OnUvAlloc(size_t suggested_size, uv_buf_t* buf) {
-template <class WrapType, class UVType>
+template <class WrapType>
static Local<Object> AcceptHandle(Environment* env, LibuvStreamWrap* parent) {
+ static_assert(std::is_base_of<LibuvStreamWrap, WrapType>::value ||
+ std::is_base_of<UDPWrap, WrapType>::value,
+ "Can only accept stream handles");
+
EscapableHandleScope scope(env->isolate());
Local<Object> wrap_obj;
- UVType* handle;
wrap_obj = WrapType::Instantiate(env, parent, WrapType::SOCKET);
if (wrap_obj.IsEmpty())
return Local<Object>();
- WrapType* wrap;
- ASSIGN_OR_RETURN_UNWRAP(&wrap, wrap_obj, Local<Object>());
- handle = wrap->UVHandle();
+ HandleWrap* wrap = Unwrap<HandleWrap>(wrap_obj);
+ CHECK_NOT_NULL(wrap);
+ uv_stream_t* stream = reinterpret_cast<uv_stream_t*>(wrap->GetHandle());
+ CHECK_NOT_NULL(stream);
- if (uv_accept(parent->stream(), reinterpret_cast<uv_stream_t*>(handle)))
+ if (uv_accept(parent->stream(), stream))
ABORT();
return scope.Escape(wrap_obj);
@@ -209,11 +229,11 @@ void LibuvStreamWrap::OnUvRead(ssize_t nread, const uv_buf_t* buf) {
Local<Object> pending_obj;
if (type == UV_TCP) {
- pending_obj = AcceptHandle<TCPWrap, uv_tcp_t>(env(), this);
+ pending_obj = AcceptHandle<TCPWrap>(env(), this);
} else if (type == UV_NAMED_PIPE) {
- pending_obj = AcceptHandle<PipeWrap, uv_pipe_t>(env(), this);
+ pending_obj = AcceptHandle<PipeWrap>(env(), this);
} else if (type == UV_UDP) {
- pending_obj = AcceptHandle<UDPWrap, uv_udp_t>(env(), this);
+ pending_obj = AcceptHandle<UDPWrap>(env(), this);
} else {
CHECK_EQ(type, UV_UNKNOWN_HANDLE);
}
diff --git a/src/stream_wrap.h b/src/stream_wrap.h
index 487a40b7ff..98f0ca4ac4 100644
--- a/src/stream_wrap.h
+++ b/src/stream_wrap.h
@@ -76,6 +76,8 @@ class LibuvStreamWrap : public HandleWrap, public StreamBase {
ShutdownWrap* CreateShutdownWrap(v8::Local<v8::Object> object) override;
WriteWrap* CreateWriteWrap(v8::Local<v8::Object> object) override;
+ static LibuvStreamWrap* From(Environment* env, v8::Local<v8::Object> object);
+
protected:
LibuvStreamWrap(Environment* env,
v8::Local<v8::Object> object,
@@ -84,8 +86,8 @@ class LibuvStreamWrap : public HandleWrap, public StreamBase {
AsyncWrap* GetAsyncWrap() override;
- static void AddMethods(Environment* env,
- v8::Local<v8::FunctionTemplate> target);
+ static v8::Local<v8::FunctionTemplate> GetConstructorTemplate(
+ Environment* env);
protected:
inline void set_fd(int fd) {
diff --git a/src/tcp_wrap.cc b/src/tcp_wrap.cc
index 554b0216fa..ff30be3363 100644
--- a/src/tcp_wrap.cc
+++ b/src/tcp_wrap.cc
@@ -88,9 +88,7 @@ void TCPWrap::Initialize(Local<Object> target,
t->InstanceTemplate()->Set(env->onread_string(), Null(env->isolate()));
t->InstanceTemplate()->Set(env->onconnection_string(), Null(env->isolate()));
- AsyncWrap::AddWrapMethods(env, t, AsyncWrap::kFlagHasReset);
- HandleWrap::AddWrapMethods(env, t);
- LibuvStreamWrap::AddMethods(env, t);
+ t->Inherit(LibuvStreamWrap::GetConstructorTemplate(env));
env->SetProtoMethod(t, "open", Open);
env->SetProtoMethod(t, "bind", Bind);
@@ -115,7 +113,7 @@ void TCPWrap::Initialize(Local<Object> target,
// Create FunctionTemplate for TCPConnectWrap.
Local<FunctionTemplate> cwt =
BaseObject::MakeLazilyInitializedJSTemplate(env);
- AsyncWrap::AddWrapMethods(env, cwt);
+ cwt->Inherit(AsyncWrap::GetConstructorTemplate(env));
Local<String> wrapString =
FIXED_ONE_BYTE_STRING(env->isolate(), "TCPConnectWrap");
cwt->SetClassName(wrapString);
diff --git a/src/tls_wrap.cc b/src/tls_wrap.cc
index 27bedd08ce..3462dac8ae 100644
--- a/src/tls_wrap.cc
+++ b/src/tls_wrap.cc
@@ -891,7 +891,7 @@ void TLSWrap::Initialize(Local<Object> target,
Local<FunctionTemplate>(),
static_cast<PropertyAttribute>(ReadOnly | DontDelete));
- AsyncWrap::AddWrapMethods(env, t, AsyncWrap::kFlagHasReset);
+ t->Inherit(AsyncWrap::GetConstructorTemplate(env));
env->SetProtoMethod(t, "receive", Receive);
env->SetProtoMethod(t, "start", Start);
env->SetProtoMethod(t, "setVerifyMode", SetVerifyMode);
diff --git a/src/tty_wrap.cc b/src/tty_wrap.cc
index e7b684a7ee..1d0ea90f36 100644
--- a/src/tty_wrap.cc
+++ b/src/tty_wrap.cc
@@ -24,7 +24,6 @@
#include "env-inl.h"
#include "handle_wrap.h"
#include "node_buffer.h"
-#include "node_wrap.h"
#include "stream_base-inl.h"
#include "stream_wrap.h"
#include "util-inl.h"
@@ -52,10 +51,7 @@ void TTYWrap::Initialize(Local<Object> target,
Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
t->SetClassName(ttyString);
t->InstanceTemplate()->SetInternalFieldCount(1);
-
- AsyncWrap::AddWrapMethods(env, t);
- HandleWrap::AddWrapMethods(env, t);
- LibuvStreamWrap::AddMethods(env, t);
+ t->Inherit(LibuvStreamWrap::GetConstructorTemplate(env));
env->SetProtoMethodNoSideEffect(t, "getWindowSize", TTYWrap::GetWindowSize);
env->SetProtoMethod(t, "setRawMode", SetRawMode);
diff --git a/src/udp_wrap.cc b/src/udp_wrap.cc
index 510926abde..77139c2f93 100644
--- a/src/udp_wrap.cc
+++ b/src/udp_wrap.cc
@@ -135,8 +135,7 @@ void UDPWrap::Initialize(Local<Object> target,
env->SetProtoMethod(t, "setTTL", SetTTL);
env->SetProtoMethod(t, "bufferSize", BufferSize);
- AsyncWrap::AddWrapMethods(env, t);
- HandleWrap::AddWrapMethods(env, t);
+ t->Inherit(HandleWrap::GetConstructorTemplate(env));
target->Set(udpString, t->GetFunction(env->context()).ToLocalChecked());
env->set_udp_constructor_function(
@@ -145,7 +144,7 @@ void UDPWrap::Initialize(Local<Object> target,
// Create FunctionTemplate for SendWrap
Local<FunctionTemplate> swt =
BaseObject::MakeLazilyInitializedJSTemplate(env);
- AsyncWrap::AddWrapMethods(env, swt);
+ swt->Inherit(AsyncWrap::GetConstructorTemplate(env));
Local<String> sendWrapString =
FIXED_ONE_BYTE_STRING(env->isolate(), "SendWrap");
swt->SetClassName(sendWrapString);
diff --git a/test/parallel/test-accessor-properties.js b/test/parallel/test-accessor-properties.js
index ce026313d0..453100d108 100644
--- a/test/parallel/test-accessor-properties.js
+++ b/test/parallel/test-accessor-properties.js
@@ -32,24 +32,26 @@ const UDP = internalBinding('udp_wrap').UDP;
UDP.prototype.fd;
}, TypeError);
+ const StreamWrapProto = Object.getPrototypeOf(TTY.prototype);
+
// Should not throw for Object.getOwnPropertyDescriptor
assert.strictEqual(
- typeof Object.getOwnPropertyDescriptor(TTY.prototype, 'bytesRead'),
+ typeof Object.getOwnPropertyDescriptor(StreamWrapProto, 'bytesRead'),
'object'
);
assert.strictEqual(
- typeof Object.getOwnPropertyDescriptor(TTY.prototype, 'fd'),
+ typeof Object.getOwnPropertyDescriptor(StreamWrapProto, 'fd'),
'object'
);
assert.strictEqual(
- typeof Object.getOwnPropertyDescriptor(TTY.prototype, '_externalStream'),
+ typeof Object.getOwnPropertyDescriptor(StreamWrapProto, '_externalStream'),
'object'
);
assert.strictEqual(
- typeof Object.getOwnPropertyDescriptor(UDP.prototype, 'fd'),
+ typeof Object.getOwnPropertyDescriptor(StreamWrapProto, 'fd'),
'object'
);
}