aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/js_stream.cc6
-rw-r--r--src/node_file.cc5
-rw-r--r--src/node_http2.cc5
-rw-r--r--src/pipe_wrap.cc3
-rw-r--r--src/stream_base-inl.h142
-rw-r--r--src/stream_base.cc87
-rw-r--r--src/stream_base.h26
-rw-r--r--src/stream_wrap.cc5
-rw-r--r--src/tcp_wrap.cc3
-rw-r--r--src/tls_wrap.cc5
-rw-r--r--src/tty_wrap.cc3
11 files changed, 132 insertions, 158 deletions
diff --git a/src/js_stream.cc b/src/js_stream.cc
index ae1aa7cd30..e5f4273476 100644
--- a/src/js_stream.cc
+++ b/src/js_stream.cc
@@ -27,6 +27,7 @@ JSStream::JSStream(Environment* env, Local<Object> obj)
: AsyncWrap(env, obj, AsyncWrap::PROVIDER_JSSTREAM),
StreamBase(env) {
MakeWeak();
+ StreamBase::AttachToObject(obj);
}
@@ -203,7 +204,8 @@ void JSStream::Initialize(Local<Object> target,
Local<String> jsStreamString =
FIXED_ONE_BYTE_STRING(env->isolate(), "JSStream");
t->SetClassName(jsStreamString);
- t->InstanceTemplate()->SetInternalFieldCount(1);
+ t->InstanceTemplate()
+ ->SetInternalFieldCount(StreamBase::kStreamBaseField + 1);
t->Inherit(AsyncWrap::GetConstructorTemplate(env));
env->SetProtoMethod(t, "finishWrite", Finish<WriteWrap>);
@@ -211,7 +213,7 @@ void JSStream::Initialize(Local<Object> target,
env->SetProtoMethod(t, "readBuffer", ReadBuffer);
env->SetProtoMethod(t, "emitEOF", EmitEOF);
- StreamBase::AddMethods<JSStream>(env, t);
+ StreamBase::AddMethods(env, t);
target->Set(env->context(),
jsStreamString,
t->GetFunction(context).ToLocalChecked()).FromJust();
diff --git a/src/node_file.cc b/src/node_file.cc
index dd658e2ecf..f4106ce647 100644
--- a/src/node_file.cc
+++ b/src/node_file.cc
@@ -111,6 +111,7 @@ FileHandle::FileHandle(Environment* env, Local<Object> obj, int fd)
StreamBase(env),
fd_(fd) {
MakeWeak();
+ StreamBase::AttachToObject(GetObject());
}
FileHandle* FileHandle::New(Environment* env, int fd, Local<Object> obj) {
@@ -2227,11 +2228,11 @@ void Initialize(Local<Object> target,
env->SetProtoMethod(fd, "close", FileHandle::Close);
env->SetProtoMethod(fd, "releaseFD", FileHandle::ReleaseFD);
Local<ObjectTemplate> fdt = fd->InstanceTemplate();
- fdt->SetInternalFieldCount(1);
+ fdt->SetInternalFieldCount(StreamBase::kStreamBaseField + 1);
Local<String> handleString =
FIXED_ONE_BYTE_STRING(isolate, "FileHandle");
fd->SetClassName(handleString);
- StreamBase::AddMethods<FileHandle>(env, fd);
+ StreamBase::AddMethods(env, fd);
target
->Set(context, handleString,
fd->GetFunction(env->context()).ToLocalChecked())
diff --git a/src/node_http2.cc b/src/node_http2.cc
index 1857eb78b2..62e66620db 100644
--- a/src/node_http2.cc
+++ b/src/node_http2.cc
@@ -1868,6 +1868,7 @@ Http2Stream::Http2Stream(Http2Session* session,
id_(id),
current_headers_category_(category) {
MakeWeak();
+ StreamBase::AttachToObject(GetObject());
statistics_.start_time = uv_hrtime();
// Limit the number of header pairs
@@ -3008,9 +3009,9 @@ void Initialize(Local<Object> target,
env->SetProtoMethod(stream, "rstStream", Http2Stream::RstStream);
env->SetProtoMethod(stream, "refreshState", Http2Stream::RefreshState);
stream->Inherit(AsyncWrap::GetConstructorTemplate(env));
- StreamBase::AddMethods<Http2Stream>(env, stream);
+ StreamBase::AddMethods(env, stream);
Local<ObjectTemplate> streamt = stream->InstanceTemplate();
- streamt->SetInternalFieldCount(1);
+ streamt->SetInternalFieldCount(StreamBase::kStreamBaseField + 1);
env->set_http2stream_constructor_template(streamt);
target->Set(context,
FIXED_ONE_BYTE_STRING(env->isolate(), "Http2Stream"),
diff --git a/src/pipe_wrap.cc b/src/pipe_wrap.cc
index 2354533ddf..0103129a66 100644
--- a/src/pipe_wrap.cc
+++ b/src/pipe_wrap.cc
@@ -74,7 +74,8 @@ void PipeWrap::Initialize(Local<Object> target,
Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
Local<String> pipeString = FIXED_ONE_BYTE_STRING(env->isolate(), "Pipe");
t->SetClassName(pipeString);
- t->InstanceTemplate()->SetInternalFieldCount(1);
+ t->InstanceTemplate()
+ ->SetInternalFieldCount(StreamBase::kStreamBaseField + 1);
t->Inherit(LibuvStreamWrap::GetConstructorTemplate(env));
diff --git a/src/stream_base-inl.h b/src/stream_base-inl.h
index 9cff67cd9f..f9a67872f9 100644
--- a/src/stream_base-inl.h
+++ b/src/stream_base-inl.h
@@ -273,144 +273,16 @@ inline WriteWrap* StreamBase::CreateWriteWrap(
return new SimpleWriteWrap<AsyncWrap>(this, object);
}
-template <class Base>
-void StreamBase::AddMethods(Environment* env, Local<FunctionTemplate> t) {
- HandleScope scope(env->isolate());
-
- enum PropertyAttribute attributes =
- static_cast<PropertyAttribute>(
- v8::ReadOnly | v8::DontDelete | v8::DontEnum);
-
- Local<Signature> signature = Signature::New(env->isolate(), t);
-
- Local<FunctionTemplate> get_fd_templ =
- env->NewFunctionTemplate(GetFD<Base>,
- signature,
- v8::ConstructorBehavior::kThrow,
- v8::SideEffectType::kHasNoSideEffect);
-
- Local<FunctionTemplate> get_external_templ =
- env->NewFunctionTemplate(GetExternal<Base>,
- signature,
- v8::ConstructorBehavior::kThrow,
- v8::SideEffectType::kHasNoSideEffect);
-
- Local<FunctionTemplate> get_bytes_read_templ =
- env->NewFunctionTemplate(GetBytesRead<Base>,
- signature,
- v8::ConstructorBehavior::kThrow,
- v8::SideEffectType::kHasNoSideEffect);
-
- Local<FunctionTemplate> get_bytes_written_templ =
- env->NewFunctionTemplate(GetBytesWritten<Base>,
- signature,
- v8::ConstructorBehavior::kThrow,
- v8::SideEffectType::kHasNoSideEffect);
-
- t->PrototypeTemplate()->SetAccessorProperty(env->fd_string(),
- get_fd_templ,
- Local<FunctionTemplate>(),
- attributes);
-
- t->PrototypeTemplate()->SetAccessorProperty(env->external_stream_string(),
- get_external_templ,
- Local<FunctionTemplate>(),
- attributes);
-
- t->PrototypeTemplate()->SetAccessorProperty(env->bytes_read_string(),
- get_bytes_read_templ,
- Local<FunctionTemplate>(),
- attributes);
-
- t->PrototypeTemplate()->SetAccessorProperty(env->bytes_written_string(),
- get_bytes_written_templ,
- Local<FunctionTemplate>(),
- attributes);
-
- env->SetProtoMethod(t, "readStart", JSMethod<Base, &StreamBase::ReadStartJS>);
- env->SetProtoMethod(t, "readStop", JSMethod<Base, &StreamBase::ReadStopJS>);
- env->SetProtoMethod(t, "shutdown", JSMethod<Base, &StreamBase::Shutdown>);
- env->SetProtoMethod(t, "writev", JSMethod<Base, &StreamBase::Writev>);
- env->SetProtoMethod(t,
- "writeBuffer",
- JSMethod<Base, &StreamBase::WriteBuffer>);
- env->SetProtoMethod(t,
- "writeAsciiString",
- JSMethod<Base, &StreamBase::WriteString<ASCII> >);
- env->SetProtoMethod(t,
- "writeUtf8String",
- JSMethod<Base, &StreamBase::WriteString<UTF8> >);
- env->SetProtoMethod(t,
- "writeUcs2String",
- JSMethod<Base, &StreamBase::WriteString<UCS2> >);
- env->SetProtoMethod(t,
- "writeLatin1String",
- JSMethod<Base, &StreamBase::WriteString<LATIN1> >);
+inline void StreamBase::AttachToObject(v8::Local<v8::Object> obj) {
+ obj->SetAlignedPointerInInternalField(kStreamBaseField, this);
}
+inline StreamBase* StreamBase::FromObject(v8::Local<v8::Object> obj) {
+ if (obj->GetAlignedPointerFromInternalField(0) == nullptr)
+ return nullptr;
-template <class Base>
-void StreamBase::GetFD(const FunctionCallbackInfo<Value>& args) {
- // Mimic implementation of StreamBase::GetFD() and UDPWrap::GetFD().
- Base* handle;
- ASSIGN_OR_RETURN_UNWRAP(&handle,
- args.This(),
- args.GetReturnValue().Set(UV_EINVAL));
-
- StreamBase* wrap = static_cast<StreamBase*>(handle);
- if (!wrap->IsAlive())
- return args.GetReturnValue().Set(UV_EINVAL);
-
- args.GetReturnValue().Set(wrap->GetFD());
-}
-
-template <class Base>
-void StreamBase::GetBytesRead(const FunctionCallbackInfo<Value>& args) {
- Base* handle;
- ASSIGN_OR_RETURN_UNWRAP(&handle,
- args.This(),
- args.GetReturnValue().Set(0));
-
- StreamBase* wrap = static_cast<StreamBase*>(handle);
- // uint64_t -> double. 53bits is enough for all real cases.
- args.GetReturnValue().Set(static_cast<double>(wrap->bytes_read_));
-}
-
-template <class Base>
-void StreamBase::GetBytesWritten(const FunctionCallbackInfo<Value>& args) {
- Base* handle;
- ASSIGN_OR_RETURN_UNWRAP(&handle,
- args.This(),
- args.GetReturnValue().Set(0));
-
- StreamBase* wrap = static_cast<StreamBase*>(handle);
- // uint64_t -> double. 53bits is enough for all real cases.
- args.GetReturnValue().Set(static_cast<double>(wrap->bytes_written_));
-}
-
-template <class Base>
-void StreamBase::GetExternal(const FunctionCallbackInfo<Value>& args) {
- Base* handle;
- ASSIGN_OR_RETURN_UNWRAP(&handle, args.This());
-
- StreamBase* wrap = static_cast<StreamBase*>(handle);
- Local<External> ext = External::New(args.GetIsolate(), wrap);
- args.GetReturnValue().Set(ext);
-}
-
-
-template <class Base,
- int (StreamBase::*Method)(const FunctionCallbackInfo<Value>& args)>
-void StreamBase::JSMethod(const FunctionCallbackInfo<Value>& args) {
- Base* handle;
- ASSIGN_OR_RETURN_UNWRAP(&handle, args.Holder());
-
- StreamBase* wrap = static_cast<StreamBase*>(handle);
- if (!wrap->IsAlive())
- return args.GetReturnValue().Set(UV_EINVAL);
-
- AsyncHooks::DefaultTriggerAsyncIdScope trigger_scope(handle);
- args.GetReturnValue().Set((wrap->*Method)(args));
+ return static_cast<StreamBase*>(
+ obj->GetAlignedPointerFromInternalField(kStreamBaseField));
}
diff --git a/src/stream_base.cc b/src/stream_base.cc
index 24210e1e26..bf7003e127 100644
--- a/src/stream_base.cc
+++ b/src/stream_base.cc
@@ -327,6 +327,93 @@ Local<Object> StreamBase::GetObject() {
return GetAsyncWrap()->object();
}
+void StreamBase::AddMethod(Environment* env,
+ Local<Signature> signature,
+ enum PropertyAttribute attributes,
+ Local<FunctionTemplate> t,
+ JSMethodFunction* stream_method,
+ Local<String> string) {
+ Local<FunctionTemplate> templ =
+ env->NewFunctionTemplate(stream_method,
+ signature,
+ v8::ConstructorBehavior::kThrow,
+ v8::SideEffectType::kHasNoSideEffect);
+ t->PrototypeTemplate()->SetAccessorProperty(
+ string, templ, Local<FunctionTemplate>(), attributes);
+}
+
+void StreamBase::AddMethods(Environment* env, Local<FunctionTemplate> t) {
+ HandleScope scope(env->isolate());
+
+ enum PropertyAttribute attributes = static_cast<PropertyAttribute>(
+ v8::ReadOnly | v8::DontDelete | v8::DontEnum);
+ Local<Signature> sig = Signature::New(env->isolate(), t);
+
+ AddMethod(env, sig, attributes, t, GetFD, env->fd_string());
+ AddMethod(
+ env, sig, attributes, t, GetExternal, env->external_stream_string());
+ AddMethod(env, sig, attributes, t, GetBytesRead, env->bytes_read_string());
+ AddMethod(
+ env, sig, attributes, t, GetBytesWritten, env->bytes_written_string());
+ env->SetProtoMethod(t, "readStart", JSMethod<&StreamBase::ReadStartJS>);
+ env->SetProtoMethod(t, "readStop", JSMethod<&StreamBase::ReadStopJS>);
+ env->SetProtoMethod(t, "shutdown", JSMethod<&StreamBase::Shutdown>);
+ env->SetProtoMethod(t, "writev", JSMethod<&StreamBase::Writev>);
+ env->SetProtoMethod(t, "writeBuffer", JSMethod<&StreamBase::WriteBuffer>);
+ env->SetProtoMethod(
+ t, "writeAsciiString", JSMethod<&StreamBase::WriteString<ASCII>>);
+ env->SetProtoMethod(
+ t, "writeUtf8String", JSMethod<&StreamBase::WriteString<UTF8>>);
+ env->SetProtoMethod(
+ t, "writeUcs2String", JSMethod<&StreamBase::WriteString<UCS2>>);
+ env->SetProtoMethod(
+ t, "writeLatin1String", JSMethod<&StreamBase::WriteString<LATIN1>>);
+}
+
+void StreamBase::GetFD(const FunctionCallbackInfo<Value>& args) {
+ // Mimic implementation of StreamBase::GetFD() and UDPWrap::GetFD().
+ StreamBase* wrap = StreamBase::FromObject(args.This().As<Object>());
+ if (wrap == nullptr) return args.GetReturnValue().Set(UV_EINVAL);
+
+ if (!wrap->IsAlive()) return args.GetReturnValue().Set(UV_EINVAL);
+
+ args.GetReturnValue().Set(wrap->GetFD());
+}
+
+void StreamBase::GetBytesRead(const FunctionCallbackInfo<Value>& args) {
+ StreamBase* wrap = StreamBase::FromObject(args.This().As<Object>());
+ if (wrap == nullptr) return args.GetReturnValue().Set(0);
+
+ // uint64_t -> double. 53bits is enough for all real cases.
+ args.GetReturnValue().Set(static_cast<double>(wrap->bytes_read_));
+}
+
+void StreamBase::GetBytesWritten(const FunctionCallbackInfo<Value>& args) {
+ StreamBase* wrap = StreamBase::FromObject(args.This().As<Object>());
+ if (wrap == nullptr) return args.GetReturnValue().Set(0);
+
+ // uint64_t -> double. 53bits is enough for all real cases.
+ args.GetReturnValue().Set(static_cast<double>(wrap->bytes_written_));
+}
+
+void StreamBase::GetExternal(const FunctionCallbackInfo<Value>& args) {
+ StreamBase* wrap = StreamBase::FromObject(args.This().As<Object>());
+ if (wrap == nullptr) return;
+
+ Local<External> ext = External::New(args.GetIsolate(), wrap);
+ args.GetReturnValue().Set(ext);
+}
+
+template <int (StreamBase::*Method)(const FunctionCallbackInfo<Value>& args)>
+void StreamBase::JSMethod(const FunctionCallbackInfo<Value>& args) {
+ StreamBase* wrap = StreamBase::FromObject(args.Holder().As<Object>());
+ if (wrap == nullptr) return;
+
+ if (!wrap->IsAlive()) return args.GetReturnValue().Set(UV_EINVAL);
+
+ AsyncHooks::DefaultTriggerAsyncIdScope trigger_scope(wrap->GetAsyncWrap());
+ args.GetReturnValue().Set((wrap->*Method)(args));
+}
int StreamResource::DoTryWrite(uv_buf_t** bufs, size_t* count) {
// No TryWrite by default
diff --git a/src/stream_base.h b/src/stream_base.h
index bf15dbc91e..c7145a2ab2 100644
--- a/src/stream_base.h
+++ b/src/stream_base.h
@@ -25,6 +25,7 @@ struct StreamWriteResult {
size_t bytes;
};
+using JSMethodFunction = void(const v8::FunctionCallbackInfo<v8::Value>& args);
class StreamReq {
public:
@@ -259,9 +260,9 @@ class StreamResource {
class StreamBase : public StreamResource {
public:
- template <class Base>
- static inline void AddMethods(Environment* env,
- v8::Local<v8::FunctionTemplate> target);
+ static constexpr int kStreamBaseField = 1;
+ static void AddMethods(Environment* env,
+ v8::Local<v8::FunctionTemplate> target);
virtual bool IsAlive() = 0;
virtual bool IsClosing() = 0;
@@ -305,6 +306,8 @@ class StreamBase : public StreamResource {
virtual AsyncWrap* GetAsyncWrap() = 0;
virtual v8::Local<v8::Object> GetObject();
+ static StreamBase* FromObject(v8::Local<v8::Object> obj);
+
protected:
explicit StreamBase(Environment* env);
@@ -317,20 +320,13 @@ class StreamBase : public StreamResource {
template <enum encoding enc>
int WriteString(const v8::FunctionCallbackInfo<v8::Value>& args);
- template <class Base>
static void GetFD(const v8::FunctionCallbackInfo<v8::Value>& args);
-
- template <class Base>
static void GetExternal(const v8::FunctionCallbackInfo<v8::Value>& args);
-
- template <class Base>
static void GetBytesRead(const v8::FunctionCallbackInfo<v8::Value>& args);
-
- template <class Base>
static void GetBytesWritten(const v8::FunctionCallbackInfo<v8::Value>& args);
+ void AttachToObject(v8::Local<v8::Object> obj);
- template <class Base,
- int (StreamBase::*Method)(
+ template <int (StreamBase::*Method)(
const v8::FunctionCallbackInfo<v8::Value>& args)>
static void JSMethod(const v8::FunctionCallbackInfo<v8::Value>& args);
@@ -348,6 +344,12 @@ class StreamBase : public StreamResource {
EmitToJSStreamListener default_listener_;
void SetWriteResult(const StreamWriteResult& res);
+ static void AddMethod(Environment* env,
+ v8::Local<v8::Signature> sig,
+ enum v8::PropertyAttribute attributes,
+ v8::Local<v8::FunctionTemplate> t,
+ JSMethodFunction* stream_method,
+ v8::Local<v8::String> str);
friend class WriteWrap;
friend class ShutdownWrap;
diff --git a/src/stream_wrap.cc b/src/stream_wrap.cc
index 7e1ba36922..0cf9f1a114 100644
--- a/src/stream_wrap.cc
+++ b/src/stream_wrap.cc
@@ -123,6 +123,7 @@ LibuvStreamWrap::LibuvStreamWrap(Environment* env,
provider),
StreamBase(env),
stream_(stream) {
+ StreamBase::AttachToObject(object);
}
@@ -134,6 +135,8 @@ Local<FunctionTemplate> LibuvStreamWrap::GetConstructorTemplate(
tmpl->SetClassName(
FIXED_ONE_BYTE_STRING(env->isolate(), "LibuvStreamWrap"));
tmpl->Inherit(HandleWrap::GetConstructorTemplate(env));
+ tmpl->InstanceTemplate()->SetInternalFieldCount(
+ StreamBase::kStreamBaseField + 1);
Local<FunctionTemplate> get_write_queue_size =
FunctionTemplate::New(env->isolate(),
GetWriteQueueSize,
@@ -145,7 +148,7 @@ Local<FunctionTemplate> LibuvStreamWrap::GetConstructorTemplate(
Local<FunctionTemplate>(),
static_cast<PropertyAttribute>(ReadOnly | DontDelete));
env->SetProtoMethod(tmpl, "setBlocking", SetBlocking);
- StreamBase::AddMethods<LibuvStreamWrap>(env, tmpl);
+ StreamBase::AddMethods(env, tmpl);
env->set_libuv_stream_wrap_ctor_template(tmpl);
}
return tmpl;
diff --git a/src/tcp_wrap.cc b/src/tcp_wrap.cc
index 43c6ea5958..af9806e488 100644
--- a/src/tcp_wrap.cc
+++ b/src/tcp_wrap.cc
@@ -79,7 +79,8 @@ void TCPWrap::Initialize(Local<Object> target,
Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
Local<String> tcpString = FIXED_ONE_BYTE_STRING(env->isolate(), "TCP");
t->SetClassName(tcpString);
- t->InstanceTemplate()->SetInternalFieldCount(1);
+ t->InstanceTemplate()
+ ->SetInternalFieldCount(StreamBase::kStreamBaseField + 1);
// Init properties
t->InstanceTemplate()->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "reading"),
diff --git a/src/tls_wrap.cc b/src/tls_wrap.cc
index 15a71f410a..84fc6e299e 100644
--- a/src/tls_wrap.cc
+++ b/src/tls_wrap.cc
@@ -58,6 +58,7 @@ TLSWrap::TLSWrap(Environment* env,
StreamBase(env),
sc_(sc) {
MakeWeak();
+ StreamBase::AttachToObject(GetObject());
// sc comes from an Unwrap. Make sure it was assigned.
CHECK_NOT_NULL(sc);
@@ -958,6 +959,8 @@ void TLSWrap::Initialize(Local<Object> target,
Local<String> tlsWrapString =
FIXED_ONE_BYTE_STRING(env->isolate(), "TLSWrap");
t->SetClassName(tlsWrapString);
+ t->InstanceTemplate()
+ ->SetInternalFieldCount(StreamBase::kStreamBaseField + 1);
Local<FunctionTemplate> get_write_queue_size =
FunctionTemplate::New(env->isolate(),
@@ -978,7 +981,7 @@ void TLSWrap::Initialize(Local<Object> target,
env->SetProtoMethod(t, "destroySSL", DestroySSL);
env->SetProtoMethod(t, "enableCertCb", EnableCertCb);
- StreamBase::AddMethods<TLSWrap>(env, t);
+ StreamBase::AddMethods(env, t);
SSLWrap<TLSWrap>::AddMethods(env, t);
env->SetProtoMethod(t, "getServername", GetServername);
diff --git a/src/tty_wrap.cc b/src/tty_wrap.cc
index 7b8a7ed227..423f53c014 100644
--- a/src/tty_wrap.cc
+++ b/src/tty_wrap.cc
@@ -51,7 +51,8 @@ void TTYWrap::Initialize(Local<Object> target,
Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
t->SetClassName(ttyString);
- t->InstanceTemplate()->SetInternalFieldCount(1);
+ t->InstanceTemplate()
+ ->SetInternalFieldCount(StreamBase::kStreamBaseField + 1);
t->Inherit(LibuvStreamWrap::GetConstructorTemplate(env));
env->SetProtoMethodNoSideEffect(t, "getWindowSize", TTYWrap::GetWindowSize);