diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/js_stream.cc | 6 | ||||
-rw-r--r-- | src/node_file.cc | 5 | ||||
-rw-r--r-- | src/node_http2.cc | 5 | ||||
-rw-r--r-- | src/pipe_wrap.cc | 3 | ||||
-rw-r--r-- | src/stream_base-inl.h | 142 | ||||
-rw-r--r-- | src/stream_base.cc | 87 | ||||
-rw-r--r-- | src/stream_base.h | 26 | ||||
-rw-r--r-- | src/stream_wrap.cc | 5 | ||||
-rw-r--r-- | src/tcp_wrap.cc | 3 | ||||
-rw-r--r-- | src/tls_wrap.cc | 5 | ||||
-rw-r--r-- | src/tty_wrap.cc | 3 |
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); |