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: https://github.com/nodejs/node/pull/23094
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Daniel Bevenius <daniel.bevenius@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
Anna Henningsen 2018-09-23 19:24:33 +02:00
parent 2ebdba1229
commit d527dde360
No known key found for this signature in database
GPG Key ID: 9C63F3A6CD2AD8F9
30 changed files with 140 additions and 198 deletions

View File

@ -73,7 +73,8 @@ Object.setPrototypeOf(MessagePort.prototype, EventEmitter.prototype);
delete MessagePort.prototype.stop; delete MessagePort.prototype.stop;
delete MessagePort.prototype.drain; delete MessagePort.prototype.drain;
delete MessagePort.prototype.hasRef; 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 // A communication channel consisting of a handle (that wraps around an
// uv_async_t) which can receive information from other threads and emits // uv_async_t) which can receive information from other threads and emits

View File

@ -422,7 +422,6 @@
'src/node_root_certs.h', 'src/node_root_certs.h',
'src/node_version.h', 'src/node_version.h',
'src/node_watchdog.h', 'src/node_watchdog.h',
'src/node_wrap.h',
'src/node_revert.h', 'src/node_revert.h',
'src/node_i18n.h', 'src/node_i18n.h',
'src/node_worker.h', 'src/node_worker.h',

View File

@ -64,7 +64,7 @@ struct AsyncWrapObject : public AsyncWrap {
static inline void New(const FunctionCallbackInfo<Value>& args) { static inline void New(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args); Environment* env = Environment::GetCurrent(args);
CHECK(args.IsConstructCall()); 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()); CHECK(args[0]->IsUint32());
auto type = static_cast<ProviderType>(args[0].As<Uint32>()->Value()); auto type = static_cast<ProviderType>(args[0].As<Uint32>()->Value());
new AsyncWrapObject(env, args.This(), type); new AsyncWrapObject(env, args.This(), type);
@ -424,12 +424,16 @@ void AsyncWrap::QueueDestroyAsyncId(const FunctionCallbackInfo<Value>& args) {
args[0].As<Number>()->Value()); args[0].As<Number>()->Value());
} }
void AsyncWrap::AddWrapMethods(Environment* env, Local<FunctionTemplate> AsyncWrap::GetConstructorTemplate(Environment* env) {
Local<FunctionTemplate> constructor, Local<FunctionTemplate> tmpl = env->async_wrap_ctor_template();
int flag) { if (tmpl.IsEmpty()) {
env->SetProtoMethod(constructor, "getAsyncId", AsyncWrap::GetAsyncId); tmpl = env->NewFunctionTemplate(nullptr);
if (flag & kFlagHasReset) tmpl->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "AsyncWrap"));
env->SetProtoMethod(constructor, "asyncReset", AsyncWrap::AsyncReset); 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, 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_promise_resolve_function(Local<Function>());
env->set_async_hooks_binding(target); 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 class_name = FIXED_ONE_BYTE_STRING(env->isolate(), "AsyncWrap");
auto function_template = env->NewFunctionTemplate(AsyncWrapObject::New); auto function_template = env->NewFunctionTemplate(AsyncWrapObject::New);
function_template->SetClassName(class_name); function_template->SetClassName(class_name);
AsyncWrap::AddWrapMethods(env, function_template); function_template->Inherit(AsyncWrap::GetConstructorTemplate(env));
auto instance_template = function_template->InstanceTemplate(); auto instance_template = function_template->InstanceTemplate();
instance_template->SetInternalFieldCount(1); instance_template->SetInternalFieldCount(1);
auto function = auto function =
function_template->GetFunction(env->context()).ToLocalChecked(); function_template->GetFunction(env->context()).ToLocalChecked();
target->Set(env->context(), class_name, function).FromJust(); 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);
} }
} }

View File

@ -104,11 +104,6 @@ class AsyncWrap : public BaseObject {
PROVIDERS_LENGTH, PROVIDERS_LENGTH,
}; };
enum Flags {
kFlagNone = 0x0,
kFlagHasReset = 0x1
};
AsyncWrap(Environment* env, AsyncWrap(Environment* env,
v8::Local<v8::Object> object, v8::Local<v8::Object> object,
ProviderType provider, ProviderType provider,
@ -116,9 +111,8 @@ class AsyncWrap : public BaseObject {
virtual ~AsyncWrap(); virtual ~AsyncWrap();
static void AddWrapMethods(Environment* env, static v8::Local<v8::FunctionTemplate> GetConstructorTemplate(
v8::Local<v8::FunctionTemplate> constructor, Environment* env);
int flags = kFlagNone);
static void Initialize(v8::Local<v8::Object> target, static void Initialize(v8::Local<v8::Object> target,
v8::Local<v8::Value> unused, v8::Local<v8::Value> unused,

View File

@ -2220,7 +2220,7 @@ void Initialize(Local<Object> target,
Local<FunctionTemplate> aiw = Local<FunctionTemplate> aiw =
BaseObject::MakeLazilyInitializedJSTemplate(env); BaseObject::MakeLazilyInitializedJSTemplate(env);
AsyncWrap::AddWrapMethods(env, aiw); aiw->Inherit(AsyncWrap::GetConstructorTemplate(env));
Local<String> addrInfoWrapString = Local<String> addrInfoWrapString =
FIXED_ONE_BYTE_STRING(env->isolate(), "GetAddrInfoReqWrap"); FIXED_ONE_BYTE_STRING(env->isolate(), "GetAddrInfoReqWrap");
aiw->SetClassName(addrInfoWrapString); aiw->SetClassName(addrInfoWrapString);
@ -2228,7 +2228,7 @@ void Initialize(Local<Object> target,
Local<FunctionTemplate> niw = Local<FunctionTemplate> niw =
BaseObject::MakeLazilyInitializedJSTemplate(env); BaseObject::MakeLazilyInitializedJSTemplate(env);
AsyncWrap::AddWrapMethods(env, niw); niw->Inherit(AsyncWrap::GetConstructorTemplate(env));
Local<String> nameInfoWrapString = Local<String> nameInfoWrapString =
FIXED_ONE_BYTE_STRING(env->isolate(), "GetNameInfoReqWrap"); FIXED_ONE_BYTE_STRING(env->isolate(), "GetNameInfoReqWrap");
niw->SetClassName(nameInfoWrapString); niw->SetClassName(nameInfoWrapString);
@ -2236,7 +2236,7 @@ void Initialize(Local<Object> target,
Local<FunctionTemplate> qrw = Local<FunctionTemplate> qrw =
BaseObject::MakeLazilyInitializedJSTemplate(env); BaseObject::MakeLazilyInitializedJSTemplate(env);
AsyncWrap::AddWrapMethods(env, qrw); qrw->Inherit(AsyncWrap::GetConstructorTemplate(env));
Local<String> queryWrapString = Local<String> queryWrapString =
FIXED_ONE_BYTE_STRING(env->isolate(), "QueryReqWrap"); FIXED_ONE_BYTE_STRING(env->isolate(), "QueryReqWrap");
qrw->SetClassName(queryWrapString); qrw->SetClassName(queryWrapString);
@ -2245,7 +2245,7 @@ void Initialize(Local<Object> target,
Local<FunctionTemplate> channel_wrap = Local<FunctionTemplate> channel_wrap =
env->NewFunctionTemplate(ChannelWrap::New); env->NewFunctionTemplate(ChannelWrap::New);
channel_wrap->InstanceTemplate()->SetInternalFieldCount(1); 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, "queryAny", Query<QueryAnyWrap>);
env->SetProtoMethod(channel_wrap, "queryA", Query<QueryAWrap>); env->SetProtoMethod(channel_wrap, "queryA", Query<QueryAWrap>);

View File

@ -319,7 +319,8 @@ struct PackageConfig {
V(async_hooks_destroy_function, v8::Function) \ V(async_hooks_destroy_function, v8::Function) \
V(async_hooks_init_function, v8::Function) \ V(async_hooks_init_function, v8::Function) \
V(async_hooks_promise_resolve_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(buffer_prototype_object, v8::Object) \
V(context, v8::Context) \ V(context, v8::Context) \
V(domain_callback, v8::Function) \ V(domain_callback, v8::Function) \
@ -329,6 +330,7 @@ struct PackageConfig {
V(filehandlereadwrap_template, v8::ObjectTemplate) \ V(filehandlereadwrap_template, v8::ObjectTemplate) \
V(fsreqpromise_constructor_template, v8::ObjectTemplate) \ V(fsreqpromise_constructor_template, v8::ObjectTemplate) \
V(fs_use_promises_symbol, v8::Symbol) \ V(fs_use_promises_symbol, v8::Symbol) \
V(handle_wrap_ctor_template, v8::FunctionTemplate) \
V(host_import_module_dynamically_callback, v8::Function) \ V(host_import_module_dynamically_callback, v8::Function) \
V(host_initialize_import_meta_object_callback, v8::Function) \ V(host_initialize_import_meta_object_callback, v8::Function) \
V(http2ping_constructor_template, v8::ObjectTemplate) \ V(http2ping_constructor_template, v8::ObjectTemplate) \
@ -336,6 +338,7 @@ struct PackageConfig {
V(http2stream_constructor_template, v8::ObjectTemplate) \ V(http2stream_constructor_template, v8::ObjectTemplate) \
V(immediate_callback_function, v8::Function) \ V(immediate_callback_function, v8::Function) \
V(inspector_console_api_object, v8::Object) \ V(inspector_console_api_object, v8::Object) \
V(libuv_stream_wrap_ctor_template, v8::FunctionTemplate) \
V(message_port, v8::Object) \ V(message_port, v8::Object) \
V(message_port_constructor_template, v8::FunctionTemplate) \ V(message_port_constructor_template, v8::FunctionTemplate) \
V(pipe_constructor_template, v8::FunctionTemplate) \ V(pipe_constructor_template, v8::FunctionTemplate) \

View File

@ -105,7 +105,7 @@ void FSEventWrap::Initialize(Local<Object> target,
t->InstanceTemplate()->SetInternalFieldCount(1); t->InstanceTemplate()->SetInternalFieldCount(1);
t->SetClassName(fsevent_string); t->SetClassName(fsevent_string);
AsyncWrap::AddWrapMethods(env, t); t->Inherit(AsyncWrap::GetConstructorTemplate(env));
env->SetProtoMethod(t, "start", Start); env->SetProtoMethod(t, "start", Start);
env->SetProtoMethod(t, "close", Close); env->SetProtoMethod(t, "close", Close);

View File

@ -130,13 +130,19 @@ void HandleWrap::OnClose(uv_handle_t* handle) {
} }
} }
Local<FunctionTemplate> HandleWrap::GetConstructorTemplate(Environment* env) {
void HandleWrap::AddWrapMethods(Environment* env, Local<FunctionTemplate> tmpl = env->handle_wrap_ctor_template();
Local<FunctionTemplate> t) { if (tmpl.IsEmpty()) {
env->SetProtoMethod(t, "close", HandleWrap::Close); tmpl = env->NewFunctionTemplate(nullptr);
env->SetProtoMethodNoSideEffect(t, "hasRef", HandleWrap::HasRef); tmpl->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "HandleWrap"));
env->SetProtoMethod(t, "ref", HandleWrap::Ref); tmpl->Inherit(AsyncWrap::GetConstructorTemplate(env));
env->SetProtoMethod(t, "unref", HandleWrap::Unref); 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;
} }

View File

@ -73,8 +73,8 @@ class HandleWrap : public AsyncWrap {
virtual void Close( virtual void Close(
v8::Local<v8::Value> close_callback = v8::Local<v8::Value>()); v8::Local<v8::Value> close_callback = v8::Local<v8::Value>());
static void AddWrapMethods(Environment* env, static v8::Local<v8::FunctionTemplate> GetConstructorTemplate(
v8::Local<v8::FunctionTemplate> constructor); Environment* env);
protected: protected:
HandleWrap(Environment* env, HandleWrap(Environment* env,

View File

@ -307,7 +307,7 @@ void Initialize(Local<Object> target, Local<Value> unused,
env->NewFunctionTemplate(JSBindingsConnection::New); env->NewFunctionTemplate(JSBindingsConnection::New);
tmpl->InstanceTemplate()->SetInternalFieldCount(1); tmpl->InstanceTemplate()->SetInternalFieldCount(1);
tmpl->SetClassName(conn_str); tmpl->SetClassName(conn_str);
AsyncWrap::AddWrapMethods(env, tmpl); tmpl->Inherit(AsyncWrap::GetConstructorTemplate(env));
env->SetProtoMethod(tmpl, "dispatch", JSBindingsConnection::Dispatch); env->SetProtoMethod(tmpl, "dispatch", JSBindingsConnection::Dispatch);
env->SetProtoMethod(tmpl, "disconnect", JSBindingsConnection::Disconnect); env->SetProtoMethod(tmpl, "disconnect", JSBindingsConnection::Disconnect);
target target

View File

@ -202,8 +202,7 @@ void JSStream::Initialize(Local<Object> target,
FIXED_ONE_BYTE_STRING(env->isolate(), "JSStream"); FIXED_ONE_BYTE_STRING(env->isolate(), "JSStream");
t->SetClassName(jsStreamString); t->SetClassName(jsStreamString);
t->InstanceTemplate()->SetInternalFieldCount(1); t->InstanceTemplate()->SetInternalFieldCount(1);
t->Inherit(AsyncWrap::GetConstructorTemplate(env));
AsyncWrap::AddWrapMethods(env, t);
env->SetProtoMethod(t, "finishWrite", Finish<WriteWrap>); env->SetProtoMethod(t, "finishWrite", Finish<WriteWrap>);
env->SetProtoMethod(t, "finishShutdown", Finish<ShutdownWrap>); env->SetProtoMethod(t, "finishShutdown", Finish<ShutdownWrap>);

View File

@ -2250,7 +2250,7 @@ void Initialize(Local<Object> target,
// Create FunctionTemplate for FSReqCallback // Create FunctionTemplate for FSReqCallback
Local<FunctionTemplate> fst = env->NewFunctionTemplate(NewFSReqCallback); Local<FunctionTemplate> fst = env->NewFunctionTemplate(NewFSReqCallback);
fst->InstanceTemplate()->SetInternalFieldCount(1); fst->InstanceTemplate()->SetInternalFieldCount(1);
AsyncWrap::AddWrapMethods(env, fst); fst->Inherit(AsyncWrap::GetConstructorTemplate(env));
Local<String> wrapString = Local<String> wrapString =
FIXED_ONE_BYTE_STRING(isolate, "FSReqCallback"); FIXED_ONE_BYTE_STRING(isolate, "FSReqCallback");
fst->SetClassName(wrapString); 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. // to do anything in the constructor, so we only store the instance template.
Local<FunctionTemplate> fh_rw = FunctionTemplate::New(isolate); Local<FunctionTemplate> fh_rw = FunctionTemplate::New(isolate);
fh_rw->InstanceTemplate()->SetInternalFieldCount(1); fh_rw->InstanceTemplate()->SetInternalFieldCount(1);
AsyncWrap::AddWrapMethods(env, fh_rw); fh_rw->Inherit(AsyncWrap::GetConstructorTemplate(env));
Local<String> fhWrapString = Local<String> fhWrapString =
FIXED_ONE_BYTE_STRING(isolate, "FileHandleReqWrap"); FIXED_ONE_BYTE_STRING(isolate, "FileHandleReqWrap");
fh_rw->SetClassName(fhWrapString); fh_rw->SetClassName(fhWrapString);
@ -2272,7 +2272,7 @@ void Initialize(Local<Object> target,
// Create Function Template for FSReqPromise // Create Function Template for FSReqPromise
Local<FunctionTemplate> fpt = FunctionTemplate::New(isolate); Local<FunctionTemplate> fpt = FunctionTemplate::New(isolate);
AsyncWrap::AddWrapMethods(env, fpt); fpt->Inherit(AsyncWrap::GetConstructorTemplate(env));
Local<String> promiseString = Local<String> promiseString =
FIXED_ONE_BYTE_STRING(isolate, "FSReqPromise"); FIXED_ONE_BYTE_STRING(isolate, "FSReqPromise");
fpt->SetClassName(promiseString); fpt->SetClassName(promiseString);
@ -2282,7 +2282,7 @@ void Initialize(Local<Object> target,
// Create FunctionTemplate for FileHandle // Create FunctionTemplate for FileHandle
Local<FunctionTemplate> fd = env->NewFunctionTemplate(FileHandle::New); 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, "close", FileHandle::Close);
env->SetProtoMethod(fd, "releaseFD", FileHandle::ReleaseFD); env->SetProtoMethod(fd, "releaseFD", FileHandle::ReleaseFD);
Local<ObjectTemplate> fdt = fd->InstanceTemplate(); Local<ObjectTemplate> fdt = fd->InstanceTemplate();
@ -2301,7 +2301,7 @@ void Initialize(Local<Object> target,
Local<FunctionTemplate> fdclose = FunctionTemplate::New(isolate); Local<FunctionTemplate> fdclose = FunctionTemplate::New(isolate);
fdclose->SetClassName(FIXED_ONE_BYTE_STRING(isolate, fdclose->SetClassName(FIXED_ONE_BYTE_STRING(isolate,
"FileHandleCloseReq")); "FileHandleCloseReq"));
AsyncWrap::AddWrapMethods(env, fdclose); fdclose->Inherit(AsyncWrap::GetConstructorTemplate(env));
Local<ObjectTemplate> fdcloset = fdclose->InstanceTemplate(); Local<ObjectTemplate> fdcloset = fdclose->InstanceTemplate();
fdcloset->SetInternalFieldCount(1); fdcloset->SetInternalFieldCount(1);
env->set_fdclose_constructor_template(fdcloset); env->set_fdclose_constructor_template(fdcloset);

View File

@ -2960,14 +2960,14 @@ void Initialize(Local<Object> target,
Local<FunctionTemplate> ping = FunctionTemplate::New(env->isolate()); Local<FunctionTemplate> ping = FunctionTemplate::New(env->isolate());
ping->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "Http2Ping")); ping->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "Http2Ping"));
AsyncWrap::AddWrapMethods(env, ping); ping->Inherit(AsyncWrap::GetConstructorTemplate(env));
Local<ObjectTemplate> pingt = ping->InstanceTemplate(); Local<ObjectTemplate> pingt = ping->InstanceTemplate();
pingt->SetInternalFieldCount(1); pingt->SetInternalFieldCount(1);
env->set_http2ping_constructor_template(pingt); env->set_http2ping_constructor_template(pingt);
Local<FunctionTemplate> setting = FunctionTemplate::New(env->isolate()); Local<FunctionTemplate> setting = FunctionTemplate::New(env->isolate());
setting->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "Http2Setting")); setting->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "Http2Setting"));
AsyncWrap::AddWrapMethods(env, setting); setting->Inherit(AsyncWrap::GetConstructorTemplate(env));
Local<ObjectTemplate> settingt = setting->InstanceTemplate(); Local<ObjectTemplate> settingt = setting->InstanceTemplate();
settingt->SetInternalFieldCount(1); settingt->SetInternalFieldCount(1);
env->set_http2settings_constructor_template(settingt); env->set_http2settings_constructor_template(settingt);
@ -2984,7 +2984,7 @@ void Initialize(Local<Object> target,
env->SetProtoMethod(stream, "respond", Http2Stream::Respond); env->SetProtoMethod(stream, "respond", Http2Stream::Respond);
env->SetProtoMethod(stream, "rstStream", Http2Stream::RstStream); env->SetProtoMethod(stream, "rstStream", Http2Stream::RstStream);
env->SetProtoMethod(stream, "refreshState", Http2Stream::RefreshState); env->SetProtoMethod(stream, "refreshState", Http2Stream::RefreshState);
AsyncWrap::AddWrapMethods(env, stream); stream->Inherit(AsyncWrap::GetConstructorTemplate(env));
StreamBase::AddMethods<Http2Stream>(env, stream); StreamBase::AddMethods<Http2Stream>(env, stream);
Local<ObjectTemplate> streamt = stream->InstanceTemplate(); Local<ObjectTemplate> streamt = stream->InstanceTemplate();
streamt->SetInternalFieldCount(1); streamt->SetInternalFieldCount(1);
@ -2997,7 +2997,7 @@ void Initialize(Local<Object> target,
env->NewFunctionTemplate(Http2Session::New); env->NewFunctionTemplate(Http2Session::New);
session->SetClassName(http2SessionClassName); session->SetClassName(http2SessionClassName);
session->InstanceTemplate()->SetInternalFieldCount(1); session->InstanceTemplate()->SetInternalFieldCount(1);
AsyncWrap::AddWrapMethods(env, session); session->Inherit(AsyncWrap::GetConstructorTemplate(env));
env->SetProtoMethod(session, "origin", Http2Session::Origin); env->SetProtoMethod(session, "origin", Http2Session::Origin);
env->SetProtoMethod(session, "altsvc", Http2Session::AltSvc); env->SetProtoMethod(session, "altsvc", Http2Session::AltSvc);
env->SetProtoMethod(session, "ping", Http2Session::Ping); env->SetProtoMethod(session, "ping", Http2Session::Ping);

View File

@ -763,7 +763,7 @@ void Initialize(Local<Object> target,
#undef V #undef V
target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "methods"), methods); 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, "close", Parser::Close);
env->SetProtoMethod(t, "free", Parser::Free); env->SetProtoMethod(t, "free", Parser::Free);
env->SetProtoMethod(t, "execute", Parser::Execute); env->SetProtoMethod(t, "execute", Parser::Execute);

View File

@ -722,9 +722,7 @@ MaybeLocal<Function> GetMessagePortConstructor(
Local<FunctionTemplate> m = env->NewFunctionTemplate(MessagePort::New); Local<FunctionTemplate> m = env->NewFunctionTemplate(MessagePort::New);
m->SetClassName(env->message_port_constructor_string()); m->SetClassName(env->message_port_constructor_string());
m->InstanceTemplate()->SetInternalFieldCount(1); m->InstanceTemplate()->SetInternalFieldCount(1);
m->Inherit(HandleWrap::GetConstructorTemplate(env));
AsyncWrap::AddWrapMethods(env, m);
HandleWrap::AddWrapMethods(env, m);
env->SetProtoMethod(m, "postMessage", MessagePort::PostMessage); env->SetProtoMethod(m, "postMessage", MessagePort::PostMessage);
env->SetProtoMethod(m, "start", MessagePort::Start); env->SetProtoMethod(m, "start", MessagePort::Start);

View File

@ -50,9 +50,7 @@ void StatWatcher::Initialize(Environment* env, Local<Object> target) {
Local<String> statWatcherString = Local<String> statWatcherString =
FIXED_ONE_BYTE_STRING(env->isolate(), "StatWatcher"); FIXED_ONE_BYTE_STRING(env->isolate(), "StatWatcher");
t->SetClassName(statWatcherString); t->SetClassName(statWatcherString);
t->Inherit(HandleWrap::GetConstructorTemplate(env));
AsyncWrap::AddWrapMethods(env, t);
HandleWrap::AddWrapMethods(env, t);
env->SetProtoMethod(t, "start", StatWatcher::Start); env->SetProtoMethod(t, "start", StatWatcher::Start);

View File

@ -482,8 +482,8 @@ void InitWorker(Local<Object> target,
Local<FunctionTemplate> w = env->NewFunctionTemplate(Worker::New); Local<FunctionTemplate> w = env->NewFunctionTemplate(Worker::New);
w->InstanceTemplate()->SetInternalFieldCount(1); w->InstanceTemplate()->SetInternalFieldCount(1);
w->Inherit(AsyncWrap::GetConstructorTemplate(env));
AsyncWrap::AddWrapMethods(env, w);
env->SetProtoMethod(w, "startThread", Worker::StartThread); env->SetProtoMethod(w, "startThread", Worker::StartThread);
env->SetProtoMethod(w, "stopThread", Worker::StopThread); env->SetProtoMethod(w, "stopThread", Worker::StopThread);
env->SetProtoMethod(w, "ref", Worker::Ref); env->SetProtoMethod(w, "ref", Worker::Ref);

View File

@ -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_

View File

@ -755,8 +755,8 @@ void Initialize(Local<Object> target,
Local<FunctionTemplate> z = env->NewFunctionTemplate(ZCtx::New); Local<FunctionTemplate> z = env->NewFunctionTemplate(ZCtx::New);
z->InstanceTemplate()->SetInternalFieldCount(1); z->InstanceTemplate()->SetInternalFieldCount(1);
z->Inherit(AsyncWrap::GetConstructorTemplate(env));
AsyncWrap::AddWrapMethods(env, z);
env->SetProtoMethod(z, "write", ZCtx::Write<true>); env->SetProtoMethod(z, "write", ZCtx::Write<true>);
env->SetProtoMethod(z, "writeSync", ZCtx::Write<false>); env->SetProtoMethod(z, "writeSync", ZCtx::Write<false>);
env->SetProtoMethod(z, "init", ZCtx::Init); env->SetProtoMethod(z, "init", ZCtx::Init);

View File

@ -28,7 +28,6 @@
#include "node.h" #include "node.h"
#include "node_buffer.h" #include "node_buffer.h"
#include "node_internals.h" #include "node_internals.h"
#include "node_wrap.h"
#include "connect_wrap.h" #include "connect_wrap.h"
#include "stream_base-inl.h" #include "stream_base-inl.h"
#include "stream_wrap.h" #include "stream_wrap.h"
@ -78,9 +77,7 @@ void PipeWrap::Initialize(Local<Object> target,
t->SetClassName(pipeString); t->SetClassName(pipeString);
t->InstanceTemplate()->SetInternalFieldCount(1); t->InstanceTemplate()->SetInternalFieldCount(1);
AsyncWrap::AddWrapMethods(env, t); t->Inherit(LibuvStreamWrap::GetConstructorTemplate(env));
HandleWrap::AddWrapMethods(env, t);
LibuvStreamWrap::AddMethods(env, t);
env->SetProtoMethod(t, "bind", Bind); env->SetProtoMethod(t, "bind", Bind);
env->SetProtoMethod(t, "listen", Listen); env->SetProtoMethod(t, "listen", Listen);
@ -98,7 +95,7 @@ void PipeWrap::Initialize(Local<Object> target,
// Create FunctionTemplate for PipeConnectWrap. // Create FunctionTemplate for PipeConnectWrap.
auto cwt = BaseObject::MakeLazilyInitializedJSTemplate(env); auto cwt = BaseObject::MakeLazilyInitializedJSTemplate(env);
AsyncWrap::AddWrapMethods(env, cwt); cwt->Inherit(AsyncWrap::GetConstructorTemplate(env));
Local<String> wrapString = Local<String> wrapString =
FIXED_ONE_BYTE_STRING(env->isolate(), "PipeConnectWrap"); FIXED_ONE_BYTE_STRING(env->isolate(), "PipeConnectWrap");
cwt->SetClassName(wrapString); cwt->SetClassName(wrapString);

View File

@ -20,10 +20,9 @@
// USE OR OTHER DEALINGS IN THE SOFTWARE. // USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "env-inl.h" #include "env-inl.h"
#include "handle_wrap.h"
#include "node_internals.h" #include "node_internals.h"
#include "node_wrap.h"
#include "stream_base-inl.h" #include "stream_base-inl.h"
#include "stream_wrap.h"
#include "util-inl.h" #include "util-inl.h"
#include <string.h> #include <string.h>
@ -58,8 +57,7 @@ class ProcessWrap : public HandleWrap {
FIXED_ONE_BYTE_STRING(env->isolate(), "Process"); FIXED_ONE_BYTE_STRING(env->isolate(), "Process");
constructor->SetClassName(processString); constructor->SetClassName(processString);
AsyncWrap::AddWrapMethods(env, constructor); constructor->Inherit(HandleWrap::GetConstructorTemplate(env));
HandleWrap::AddWrapMethods(env, constructor);
env->SetProtoMethod(constructor, "spawn", Spawn); env->SetProtoMethod(constructor, "spawn", Spawn);
env->SetProtoMethod(constructor, "kill", Kill); env->SetProtoMethod(constructor, "kill", Kill);
@ -92,6 +90,17 @@ class ProcessWrap : public HandleWrap {
MarkAsUninitialized(); 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, static void ParseStdioOptions(Environment* env,
Local<Object> js_options, Local<Object> js_options,
uv_process_options_t* options) { uv_process_options_t* options) {
@ -115,22 +124,10 @@ class ProcessWrap : public HandleWrap {
} else if (type->StrictEquals(env->pipe_string())) { } else if (type->StrictEquals(env->pipe_string())) {
options->stdio[i].flags = static_cast<uv_stdio_flags>( options->stdio[i].flags = static_cast<uv_stdio_flags>(
UV_CREATE_PIPE | UV_READABLE_PIPE | UV_WRITABLE_PIPE); UV_CREATE_PIPE | UV_READABLE_PIPE | UV_WRITABLE_PIPE);
Local<String> handle_key = env->handle_string(); options->stdio[i].data.stream = StreamForWrap(env, stdio);
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());
} else if (type->StrictEquals(env->wrap_string())) { } 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].flags = UV_INHERIT_STREAM;
options->stdio[i].data.stream = stream; options->stdio[i].data.stream = StreamForWrap(env, stdio);
} else { } else {
Local<String> fd_key = env->fd_string(); Local<String> fd_key = env->fd_string();
Local<Value> fd_value = stdio->Get(context, fd_key).ToLocalChecked(); Local<Value> fd_value = stdio->Get(context, fd_key).ToLocalChecked();

View File

@ -50,9 +50,7 @@ class SignalWrap : public HandleWrap {
Local<String> signalString = Local<String> signalString =
FIXED_ONE_BYTE_STRING(env->isolate(), "Signal"); FIXED_ONE_BYTE_STRING(env->isolate(), "Signal");
constructor->SetClassName(signalString); constructor->SetClassName(signalString);
constructor->Inherit(HandleWrap::GetConstructorTemplate(env));
AsyncWrap::AddWrapMethods(env, constructor);
HandleWrap::AddWrapMethods(env, constructor);
env->SetProtoMethod(constructor, "start", Start); env->SetProtoMethod(constructor, "start", Start);
env->SetProtoMethod(constructor, "stop", Stop); env->SetProtoMethod(constructor, "stop", Stop);

View File

@ -257,7 +257,7 @@ void InitializeStreamPipe(Local<Object> target,
FIXED_ONE_BYTE_STRING(env->isolate(), "StreamPipe"); FIXED_ONE_BYTE_STRING(env->isolate(), "StreamPipe");
env->SetProtoMethod(pipe, "unpipe", StreamPipe::Unpipe); env->SetProtoMethod(pipe, "unpipe", StreamPipe::Unpipe);
env->SetProtoMethod(pipe, "start", StreamPipe::Start); env->SetProtoMethod(pipe, "start", StreamPipe::Start);
AsyncWrap::AddWrapMethods(env, pipe); pipe->Inherit(AsyncWrap::GetConstructorTemplate(env));
pipe->SetClassName(stream_pipe_string); pipe->SetClassName(stream_pipe_string);
pipe->InstanceTemplate()->SetInternalFieldCount(1); pipe->InstanceTemplate()->SetInternalFieldCount(1);
target target

View File

@ -66,7 +66,7 @@ void LibuvStreamWrap::Initialize(Local<Object> target,
Local<String> wrapString = Local<String> wrapString =
FIXED_ONE_BYTE_STRING(env->isolate(), "ShutdownWrap"); FIXED_ONE_BYTE_STRING(env->isolate(), "ShutdownWrap");
sw->SetClassName(wrapString); sw->SetClassName(wrapString);
AsyncWrap::AddWrapMethods(env, sw); sw->Inherit(AsyncWrap::GetConstructorTemplate(env));
target->Set(wrapString, sw->GetFunction(env->context()).ToLocalChecked()); target->Set(wrapString, sw->GetFunction(env->context()).ToLocalChecked());
env->set_shutdown_wrap_template(sw->InstanceTemplate()); env->set_shutdown_wrap_template(sw->InstanceTemplate());
@ -76,7 +76,7 @@ void LibuvStreamWrap::Initialize(Local<Object> target,
Local<String> writeWrapString = Local<String> writeWrapString =
FIXED_ONE_BYTE_STRING(env->isolate(), "WriteWrap"); FIXED_ONE_BYTE_STRING(env->isolate(), "WriteWrap");
ww->SetClassName(writeWrapString); ww->SetClassName(writeWrapString);
AsyncWrap::AddWrapMethods(env, ww); ww->Inherit(AsyncWrap::GetConstructorTemplate(env));
target->Set(writeWrapString, target->Set(writeWrapString,
ww->GetFunction(env->context()).ToLocalChecked()); ww->GetFunction(env->context()).ToLocalChecked());
env->set_write_wrap_template(ww->InstanceTemplate()); env->set_write_wrap_template(ww->InstanceTemplate());
@ -96,20 +96,36 @@ LibuvStreamWrap::LibuvStreamWrap(Environment* env,
} }
void LibuvStreamWrap::AddMethods(Environment* env, Local<FunctionTemplate> LibuvStreamWrap::GetConstructorTemplate(
v8::Local<v8::FunctionTemplate> target) { Environment* env) {
Local<FunctionTemplate> get_write_queue_size = Local<FunctionTemplate> tmpl = env->libuv_stream_wrap_ctor_template();
FunctionTemplate::New(env->isolate(), if (tmpl.IsEmpty()) {
GetWriteQueueSize, tmpl = env->NewFunctionTemplate(nullptr);
env->as_external(), tmpl->SetClassName(
Signature::New(env->isolate(), target)); FIXED_ONE_BYTE_STRING(env->isolate(), "LibuvStreamWrap"));
target->PrototypeTemplate()->SetAccessorProperty( tmpl->Inherit(HandleWrap::GetConstructorTemplate(env));
env->write_queue_size_string(), Local<FunctionTemplate> get_write_queue_size =
get_write_queue_size, FunctionTemplate::New(env->isolate(),
Local<FunctionTemplate>(), GetWriteQueueSize,
static_cast<PropertyAttribute>(ReadOnly | DontDelete)); env->as_external(),
env->SetProtoMethod(target, "setBlocking", SetBlocking); Signature::New(env->isolate(), tmpl));
StreamBase::AddMethods<LibuvStreamWrap>(env, target); 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 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()); EscapableHandleScope scope(env->isolate());
Local<Object> wrap_obj; Local<Object> wrap_obj;
UVType* handle;
wrap_obj = WrapType::Instantiate(env, parent, WrapType::SOCKET); wrap_obj = WrapType::Instantiate(env, parent, WrapType::SOCKET);
if (wrap_obj.IsEmpty()) if (wrap_obj.IsEmpty())
return Local<Object>(); return Local<Object>();
WrapType* wrap; HandleWrap* wrap = Unwrap<HandleWrap>(wrap_obj);
ASSIGN_OR_RETURN_UNWRAP(&wrap, wrap_obj, Local<Object>()); CHECK_NOT_NULL(wrap);
handle = wrap->UVHandle(); 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(); ABORT();
return scope.Escape(wrap_obj); return scope.Escape(wrap_obj);
@ -209,11 +229,11 @@ void LibuvStreamWrap::OnUvRead(ssize_t nread, const uv_buf_t* buf) {
Local<Object> pending_obj; Local<Object> pending_obj;
if (type == UV_TCP) { 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) { } 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) { } else if (type == UV_UDP) {
pending_obj = AcceptHandle<UDPWrap, uv_udp_t>(env(), this); pending_obj = AcceptHandle<UDPWrap>(env(), this);
} else { } else {
CHECK_EQ(type, UV_UNKNOWN_HANDLE); CHECK_EQ(type, UV_UNKNOWN_HANDLE);
} }

View File

@ -76,6 +76,8 @@ class LibuvStreamWrap : public HandleWrap, public StreamBase {
ShutdownWrap* CreateShutdownWrap(v8::Local<v8::Object> object) override; ShutdownWrap* CreateShutdownWrap(v8::Local<v8::Object> object) override;
WriteWrap* CreateWriteWrap(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: protected:
LibuvStreamWrap(Environment* env, LibuvStreamWrap(Environment* env,
v8::Local<v8::Object> object, v8::Local<v8::Object> object,
@ -84,8 +86,8 @@ class LibuvStreamWrap : public HandleWrap, public StreamBase {
AsyncWrap* GetAsyncWrap() override; AsyncWrap* GetAsyncWrap() override;
static void AddMethods(Environment* env, static v8::Local<v8::FunctionTemplate> GetConstructorTemplate(
v8::Local<v8::FunctionTemplate> target); Environment* env);
protected: protected:
inline void set_fd(int fd) { inline void set_fd(int fd) {

View File

@ -88,9 +88,7 @@ void TCPWrap::Initialize(Local<Object> target,
t->InstanceTemplate()->Set(env->onread_string(), Null(env->isolate())); t->InstanceTemplate()->Set(env->onread_string(), Null(env->isolate()));
t->InstanceTemplate()->Set(env->onconnection_string(), Null(env->isolate())); t->InstanceTemplate()->Set(env->onconnection_string(), Null(env->isolate()));
AsyncWrap::AddWrapMethods(env, t, AsyncWrap::kFlagHasReset); t->Inherit(LibuvStreamWrap::GetConstructorTemplate(env));
HandleWrap::AddWrapMethods(env, t);
LibuvStreamWrap::AddMethods(env, t);
env->SetProtoMethod(t, "open", Open); env->SetProtoMethod(t, "open", Open);
env->SetProtoMethod(t, "bind", Bind); env->SetProtoMethod(t, "bind", Bind);
@ -115,7 +113,7 @@ void TCPWrap::Initialize(Local<Object> target,
// Create FunctionTemplate for TCPConnectWrap. // Create FunctionTemplate for TCPConnectWrap.
Local<FunctionTemplate> cwt = Local<FunctionTemplate> cwt =
BaseObject::MakeLazilyInitializedJSTemplate(env); BaseObject::MakeLazilyInitializedJSTemplate(env);
AsyncWrap::AddWrapMethods(env, cwt); cwt->Inherit(AsyncWrap::GetConstructorTemplate(env));
Local<String> wrapString = Local<String> wrapString =
FIXED_ONE_BYTE_STRING(env->isolate(), "TCPConnectWrap"); FIXED_ONE_BYTE_STRING(env->isolate(), "TCPConnectWrap");
cwt->SetClassName(wrapString); cwt->SetClassName(wrapString);

View File

@ -891,7 +891,7 @@ void TLSWrap::Initialize(Local<Object> target,
Local<FunctionTemplate>(), Local<FunctionTemplate>(),
static_cast<PropertyAttribute>(ReadOnly | DontDelete)); static_cast<PropertyAttribute>(ReadOnly | DontDelete));
AsyncWrap::AddWrapMethods(env, t, AsyncWrap::kFlagHasReset); t->Inherit(AsyncWrap::GetConstructorTemplate(env));
env->SetProtoMethod(t, "receive", Receive); env->SetProtoMethod(t, "receive", Receive);
env->SetProtoMethod(t, "start", Start); env->SetProtoMethod(t, "start", Start);
env->SetProtoMethod(t, "setVerifyMode", SetVerifyMode); env->SetProtoMethod(t, "setVerifyMode", SetVerifyMode);

View File

@ -24,7 +24,6 @@
#include "env-inl.h" #include "env-inl.h"
#include "handle_wrap.h" #include "handle_wrap.h"
#include "node_buffer.h" #include "node_buffer.h"
#include "node_wrap.h"
#include "stream_base-inl.h" #include "stream_base-inl.h"
#include "stream_wrap.h" #include "stream_wrap.h"
#include "util-inl.h" #include "util-inl.h"
@ -52,10 +51,7 @@ void TTYWrap::Initialize(Local<Object> target,
Local<FunctionTemplate> t = env->NewFunctionTemplate(New); Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
t->SetClassName(ttyString); t->SetClassName(ttyString);
t->InstanceTemplate()->SetInternalFieldCount(1); t->InstanceTemplate()->SetInternalFieldCount(1);
t->Inherit(LibuvStreamWrap::GetConstructorTemplate(env));
AsyncWrap::AddWrapMethods(env, t);
HandleWrap::AddWrapMethods(env, t);
LibuvStreamWrap::AddMethods(env, t);
env->SetProtoMethodNoSideEffect(t, "getWindowSize", TTYWrap::GetWindowSize); env->SetProtoMethodNoSideEffect(t, "getWindowSize", TTYWrap::GetWindowSize);
env->SetProtoMethod(t, "setRawMode", SetRawMode); env->SetProtoMethod(t, "setRawMode", SetRawMode);

View File

@ -135,8 +135,7 @@ void UDPWrap::Initialize(Local<Object> target,
env->SetProtoMethod(t, "setTTL", SetTTL); env->SetProtoMethod(t, "setTTL", SetTTL);
env->SetProtoMethod(t, "bufferSize", BufferSize); env->SetProtoMethod(t, "bufferSize", BufferSize);
AsyncWrap::AddWrapMethods(env, t); t->Inherit(HandleWrap::GetConstructorTemplate(env));
HandleWrap::AddWrapMethods(env, t);
target->Set(udpString, t->GetFunction(env->context()).ToLocalChecked()); target->Set(udpString, t->GetFunction(env->context()).ToLocalChecked());
env->set_udp_constructor_function( env->set_udp_constructor_function(
@ -145,7 +144,7 @@ void UDPWrap::Initialize(Local<Object> target,
// Create FunctionTemplate for SendWrap // Create FunctionTemplate for SendWrap
Local<FunctionTemplate> swt = Local<FunctionTemplate> swt =
BaseObject::MakeLazilyInitializedJSTemplate(env); BaseObject::MakeLazilyInitializedJSTemplate(env);
AsyncWrap::AddWrapMethods(env, swt); swt->Inherit(AsyncWrap::GetConstructorTemplate(env));
Local<String> sendWrapString = Local<String> sendWrapString =
FIXED_ONE_BYTE_STRING(env->isolate(), "SendWrap"); FIXED_ONE_BYTE_STRING(env->isolate(), "SendWrap");
swt->SetClassName(sendWrapString); swt->SetClassName(sendWrapString);

View File

@ -32,24 +32,26 @@ const UDP = internalBinding('udp_wrap').UDP;
UDP.prototype.fd; UDP.prototype.fd;
}, TypeError); }, TypeError);
const StreamWrapProto = Object.getPrototypeOf(TTY.prototype);
// Should not throw for Object.getOwnPropertyDescriptor // Should not throw for Object.getOwnPropertyDescriptor
assert.strictEqual( assert.strictEqual(
typeof Object.getOwnPropertyDescriptor(TTY.prototype, 'bytesRead'), typeof Object.getOwnPropertyDescriptor(StreamWrapProto, 'bytesRead'),
'object' 'object'
); );
assert.strictEqual( assert.strictEqual(
typeof Object.getOwnPropertyDescriptor(TTY.prototype, 'fd'), typeof Object.getOwnPropertyDescriptor(StreamWrapProto, 'fd'),
'object' 'object'
); );
assert.strictEqual( assert.strictEqual(
typeof Object.getOwnPropertyDescriptor(TTY.prototype, '_externalStream'), typeof Object.getOwnPropertyDescriptor(StreamWrapProto, '_externalStream'),
'object' 'object'
); );
assert.strictEqual( assert.strictEqual(
typeof Object.getOwnPropertyDescriptor(UDP.prototype, 'fd'), typeof Object.getOwnPropertyDescriptor(StreamWrapProto, 'fd'),
'object' 'object'
); );
} }