From 52a3e3560484ec3ad4479ef80d829f7c99d39e80 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Mon, 18 Nov 2019 14:49:56 +0100 Subject: src: clean up node_file.h - Move inline functions into an `-inl.h` file - Move override function definitions into `.cc` files - Remove `using` statements from header files - Make data fields of classes private - Mark classes at the end of hierarchies as `final` This is also partially being done in an attempt to avoid a particular internal compiler error, see https://github.com/nodejs/node/pull/30475#issuecomment-554740850 for details. PR-URL: https://github.com/nodejs/node/pull/30530 Reviewed-By: Jiawen Geng Reviewed-By: David Carlier Reviewed-By: James M Snell --- src/node_file.h | 382 ++++++++++++++------------------------------------------ 1 file changed, 92 insertions(+), 290 deletions(-) (limited to 'src/node_file.h') diff --git a/src/node_file.h b/src/node_file.h index 84f4032cc2..1042baaf8f 100644 --- a/src/node_file.h +++ b/src/node_file.h @@ -6,113 +6,70 @@ #include "node.h" #include "aliased_buffer.h" #include "stream_base.h" -#include "memory_tracker-inl.h" -#include "req_wrap-inl.h" #include namespace node { - -using v8::Context; -using v8::FunctionCallbackInfo; -using v8::HandleScope; -using v8::Local; -using v8::MaybeLocal; -using v8::Object; -using v8::Promise; -using v8::Undefined; -using v8::Value; - namespace fs { // structure used to store state during a complex operation, e.g., mkdirp. class FSContinuationData : public MemoryRetainer { public: - FSContinuationData(uv_fs_t* req, int mode, uv_fs_cb done_cb) - : req(req), mode(mode), done_cb(done_cb) { - } - - uv_fs_t* req; - int mode; - std::vector paths{}; + inline FSContinuationData(uv_fs_t* req, int mode, uv_fs_cb done_cb); - void PushPath(std::string&& path) { - paths.emplace_back(std::move(path)); - } - - void PushPath(const std::string& path) { - paths.push_back(path); - } + inline void PushPath(std::string&& path); + inline void PushPath(const std::string& path); + inline std::string PopPath(); + inline void Done(int result); - std::string PopPath() { - CHECK_GT(paths.size(), 0); - std::string path = std::move(paths.back()); - paths.pop_back(); - return path; - } - - void Done(int result) { - req->result = result; - done_cb(req); - } - - void MemoryInfo(MemoryTracker* tracker) const override { - tracker->TrackField("paths", paths); - } + int mode() const { return mode_; } + const std::vector& paths() const { return paths_; } + void MemoryInfo(MemoryTracker* tracker) const override; SET_MEMORY_INFO_NAME(FSContinuationData) SET_SELF_SIZE(FSContinuationData) private: - uv_fs_cb done_cb; + uv_fs_cb done_cb_; + uv_fs_t* req_; + int mode_; + std::vector paths_; }; class FSReqBase : public ReqWrap { public: typedef MaybeStackBuffer FSReqBuffer; - std::unique_ptr continuation_data = nullptr; - - FSReqBase(Environment* env, Local req, AsyncWrap::ProviderType type, - bool use_bigint) - : ReqWrap(env, req, type), use_bigint_(use_bigint) { - } - void Init(const char* syscall, - const char* data, - size_t len, - enum encoding encoding) { - syscall_ = syscall; - encoding_ = encoding; - - if (data != nullptr) { - CHECK(!has_data_); - buffer_.AllocateSufficientStorage(len + 1); - buffer_.SetLengthAndZeroTerminate(len); - memcpy(*buffer_, data, len); - has_data_ = true; - } - } - - FSReqBuffer& Init(const char* syscall, size_t len, - enum encoding encoding) { - syscall_ = syscall; - encoding_ = encoding; - - buffer_.AllocateSufficientStorage(len + 1); - has_data_ = false; // so that the data does not show up in error messages - return buffer_; - } - - virtual void Reject(Local reject) = 0; - virtual void Resolve(Local value) = 0; + inline FSReqBase(Environment* env, + v8::Local req, + AsyncWrap::ProviderType type, + bool use_bigint); + ~FSReqBase() override; + + inline void Init(const char* syscall, + const char* data, + size_t len, + enum encoding encoding); + inline FSReqBuffer& Init(const char* syscall, size_t len, + enum encoding encoding); + + virtual void Reject(v8::Local reject) = 0; + virtual void Resolve(v8::Local value) = 0; virtual void ResolveStat(const uv_stat_t* stat) = 0; - virtual void SetReturnValue(const FunctionCallbackInfo& args) = 0; + virtual void SetReturnValue( + const v8::FunctionCallbackInfo& args) = 0; const char* syscall() const { return syscall_; } const char* data() const { return has_data_ ? *buffer_ : nullptr; } enum encoding encoding() const { return encoding_; } - bool use_bigint() const { return use_bigint_; } + FSContinuationData* continuation_data() const { + return continuation_data_.get(); + } + void set_continuation_data(std::unique_ptr data) { + continuation_data_ = std::move(data); + } + static FSReqBase* from_req(uv_fs_t* req) { return static_cast(ReqWrap::from_req(req)); } @@ -120,7 +77,10 @@ class FSReqBase : public ReqWrap { FSReqBase(const FSReqBase&) = delete; FSReqBase& operator=(const FSReqBase&) = delete; + void MemoryInfo(MemoryTracker* tracker) const override; + private: + std::unique_ptr continuation_data_; enum encoding encoding_ = UTF8; bool has_data_ = false; const char* syscall_ = nullptr; @@ -131,19 +91,16 @@ class FSReqBase : public ReqWrap { FSReqBuffer buffer_; }; -class FSReqCallback : public FSReqBase { +class FSReqCallback final : public FSReqBase { public: - FSReqCallback(Environment* env, Local req, bool use_bigint) - : FSReqBase(env, req, AsyncWrap::PROVIDER_FSREQCALLBACK, use_bigint) { } + inline FSReqCallback(Environment* env, + v8::Local req, + bool use_bigint); - void Reject(Local reject) override; - void Resolve(Local value) override; + void Reject(v8::Local reject) override; + void Resolve(v8::Local value) override; void ResolveStat(const uv_stat_t* stat) override; - void SetReturnValue(const FunctionCallbackInfo& args) override; - - void MemoryInfo(MemoryTracker* tracker) const override { - tracker->TrackField("continuation_data", continuation_data); - } + void SetReturnValue(const v8::FunctionCallbackInfo& args) override; SET_MEMORY_INFO_NAME(FSReqCallback) SET_SELF_SIZE(FSReqCallback) @@ -153,120 +110,27 @@ class FSReqCallback : public FSReqBase { }; template -constexpr void FillStatsArray(AliasedBufferBase* fields, - const uv_stat_t* s, - const size_t offset = 0) { -#define SET_FIELD_WITH_STAT(stat_offset, stat) \ - fields->SetValue(offset + static_cast(FsStatsOffset::stat_offset), \ - static_cast(stat)) - -#define SET_FIELD_WITH_TIME_STAT(stat_offset, stat) \ - /* NOLINTNEXTLINE(runtime/int) */ \ - SET_FIELD_WITH_STAT(stat_offset, static_cast(stat)) - - SET_FIELD_WITH_STAT(kDev, s->st_dev); - SET_FIELD_WITH_STAT(kMode, s->st_mode); - SET_FIELD_WITH_STAT(kNlink, s->st_nlink); - SET_FIELD_WITH_STAT(kUid, s->st_uid); - SET_FIELD_WITH_STAT(kGid, s->st_gid); - SET_FIELD_WITH_STAT(kRdev, s->st_rdev); - SET_FIELD_WITH_STAT(kBlkSize, s->st_blksize); - SET_FIELD_WITH_STAT(kIno, s->st_ino); - SET_FIELD_WITH_STAT(kSize, s->st_size); - SET_FIELD_WITH_STAT(kBlocks, s->st_blocks); - - SET_FIELD_WITH_TIME_STAT(kATimeSec, s->st_atim.tv_sec); - SET_FIELD_WITH_TIME_STAT(kATimeNsec, s->st_atim.tv_nsec); - SET_FIELD_WITH_TIME_STAT(kMTimeSec, s->st_mtim.tv_sec); - SET_FIELD_WITH_TIME_STAT(kMTimeNsec, s->st_mtim.tv_nsec); - SET_FIELD_WITH_TIME_STAT(kCTimeSec, s->st_ctim.tv_sec); - SET_FIELD_WITH_TIME_STAT(kCTimeNsec, s->st_ctim.tv_nsec); - SET_FIELD_WITH_TIME_STAT(kBirthTimeSec, s->st_birthtim.tv_sec); - SET_FIELD_WITH_TIME_STAT(kBirthTimeNsec, s->st_birthtim.tv_nsec); - -#undef SET_FIELD_WITH_TIME_STAT -#undef SET_FIELD_WITH_STAT -} - -inline Local FillGlobalStatsArray(Environment* env, - const bool use_bigint, - const uv_stat_t* s, - const bool second = false) { - const ptrdiff_t offset = - second ? static_cast(FsStatsOffset::kFsStatsFieldsNumber) : 0; - if (use_bigint) { - auto* const arr = env->fs_stats_field_bigint_array(); - FillStatsArray(arr, s, offset); - return arr->GetJSArray(); - } else { - auto* const arr = env->fs_stats_field_array(); - FillStatsArray(arr, s, offset); - return arr->GetJSArray(); - } -} +void FillStatsArray(AliasedBufferBase* fields, + const uv_stat_t* s, + const size_t offset = 0); + +inline v8::Local FillGlobalStatsArray(Environment* env, + const bool use_bigint, + const uv_stat_t* s, + const bool second = false); template -class FSReqPromise : public FSReqBase { +class FSReqPromise final : public FSReqBase { public: - static FSReqPromise* New(Environment* env, bool use_bigint) { - v8::Local obj; - if (!env->fsreqpromise_constructor_template() - ->NewInstance(env->context()) - .ToLocal(&obj)) { - return nullptr; - } - v8::Local resolver; - if (!v8::Promise::Resolver::New(env->context()).ToLocal(&resolver) || - obj->Set(env->context(), env->promise_string(), resolver).IsNothing()) { - return nullptr; - } - return new FSReqPromise(env, obj, use_bigint); - } - - ~FSReqPromise() override { - // Validate that the promise was explicitly resolved or rejected. - CHECK(finished_); - } - - void Reject(Local reject) override { - finished_ = true; - HandleScope scope(env()->isolate()); - InternalCallbackScope callback_scope(this); - Local value = - object()->Get(env()->context(), - env()->promise_string()).ToLocalChecked(); - Local resolver = value.As(); - USE(resolver->Reject(env()->context(), reject).FromJust()); - } - - void Resolve(Local value) override { - finished_ = true; - HandleScope scope(env()->isolate()); - InternalCallbackScope callback_scope(this); - Local val = - object()->Get(env()->context(), - env()->promise_string()).ToLocalChecked(); - Local resolver = val.As(); - USE(resolver->Resolve(env()->context(), value).FromJust()); - } - - void ResolveStat(const uv_stat_t* stat) override { - FillStatsArray(&stats_field_array_, stat); - Resolve(stats_field_array_.GetJSArray()); - } - - void SetReturnValue(const FunctionCallbackInfo& args) override { - Local val = - object()->Get(env()->context(), - env()->promise_string()).ToLocalChecked(); - Local resolver = val.As(); - args.GetReturnValue().Set(resolver->GetPromise()); - } + static inline FSReqPromise* New(Environment* env, bool use_bigint); + inline ~FSReqPromise() override; - void MemoryInfo(MemoryTracker* tracker) const override { - tracker->TrackField("stats_field_array", stats_field_array_); - tracker->TrackField("continuation_data", continuation_data); - } + inline void Reject(v8::Local reject) override; + inline void Resolve(v8::Local value) override; + inline void ResolveStat(const uv_stat_t* stat) override; + inline void SetReturnValue( + const v8::FunctionCallbackInfo& args) override; + inline void MemoryInfo(MemoryTracker* tracker) const override; SET_MEMORY_INFO_NAME(FSReqPromise) SET_SELF_SIZE(FSReqPromise) @@ -277,17 +141,15 @@ class FSReqPromise : public FSReqBase { FSReqPromise& operator=(const FSReqPromise&&) = delete; private: - FSReqPromise(Environment* env, v8::Local obj, bool use_bigint) - : FSReqBase(env, obj, AsyncWrap::PROVIDER_FSREQPROMISE, use_bigint), - stats_field_array_( - env->isolate(), - static_cast(FsStatsOffset::kFsStatsFieldsNumber)) {} + inline FSReqPromise(Environment* env, + v8::Local obj, + bool use_bigint); bool finished_ = false; AliasedBufferT stats_field_array_; }; -class FSReqAfterScope { +class FSReqAfterScope final { public: FSReqAfterScope(FSReqBase* wrap, uv_fs_t* req); ~FSReqAfterScope(); @@ -304,17 +166,18 @@ class FSReqAfterScope { private: FSReqBase* wrap_ = nullptr; uv_fs_t* req_ = nullptr; - HandleScope handle_scope_; - Context::Scope context_scope_; + v8::HandleScope handle_scope_; + v8::Context::Scope context_scope_; }; class FileHandle; // A request wrap specifically for uv_fs_read()s scheduled for reading // from a FileHandle. -class FileHandleReadWrap : public ReqWrap { +class FileHandleReadWrap final : public ReqWrap { public: FileHandleReadWrap(FileHandle* handle, v8::Local obj); + ~FileHandleReadWrap() override; static inline FileHandleReadWrap* from_req(uv_fs_t* req) { return static_cast(ReqWrap::from_req(req)); @@ -333,7 +196,7 @@ class FileHandleReadWrap : public ReqWrap { // A wrapper for a file descriptor that will automatically close the fd when // the object is garbage collected -class FileHandle : public AsyncWrap, public StreamBase { +class FileHandle final : public AsyncWrap, public StreamBase { public: static FileHandle* New(Environment* env, int fd, @@ -346,10 +209,10 @@ class FileHandle : public AsyncWrap, public StreamBase { // Will asynchronously close the FD and return a Promise that will // be resolved once closing is complete. - static void Close(const FunctionCallbackInfo& args); + static void Close(const v8::FunctionCallbackInfo& args); // Releases ownership of the FD. - static void ReleaseFD(const FunctionCallbackInfo& args); + static void ReleaseFD(const v8::FunctionCallbackInfo& args); // StreamBase interface: int ReadStart() override; @@ -366,13 +229,9 @@ class FileHandle : public AsyncWrap, public StreamBase { int DoWrite(WriteWrap* w, uv_buf_t* bufs, size_t count, - uv_stream_t* send_handle) override { - return UV_ENOSYS; // Not implemented (yet). - } + uv_stream_t* send_handle) override; - void MemoryInfo(MemoryTracker* tracker) const override { - tracker->TrackField("current_read", current_read_); - } + void MemoryInfo(MemoryTracker* tracker) const override; SET_MEMORY_INFO_NAME(FileHandle) SET_SELF_SIZE(FileHandle) @@ -389,36 +248,24 @@ class FileHandle : public AsyncWrap, public StreamBase { void Close(); void AfterClose(); - class CloseReq : public ReqWrap { + class CloseReq final : public ReqWrap { public: CloseReq(Environment* env, - Local obj, - Local promise, - Local ref) - : ReqWrap(env, obj, AsyncWrap::PROVIDER_FILEHANDLECLOSEREQ) { - promise_.Reset(env->isolate(), promise); - ref_.Reset(env->isolate(), ref); - } - - ~CloseReq() override { - uv_fs_req_cleanup(req()); - promise_.Reset(); - ref_.Reset(); - } + v8::Local obj, + v8::Local promise, + v8::Local ref); + ~CloseReq() override; FileHandle* file_handle(); - void MemoryInfo(MemoryTracker* tracker) const override { - tracker->TrackField("promise", promise_); - tracker->TrackField("ref", ref_); - } + void MemoryInfo(MemoryTracker* tracker) const override; SET_MEMORY_INFO_NAME(CloseReq) SET_SELF_SIZE(CloseReq) void Resolve(); - void Reject(Local reason); + void Reject(v8::Local reason); static CloseReq* from_req(uv_fs_t* req) { return static_cast(ReqWrap::from_req(req)); @@ -430,12 +277,12 @@ class FileHandle : public AsyncWrap, public StreamBase { CloseReq& operator=(const CloseReq&&) = delete; private: - v8::Global promise_{}; - v8::Global ref_{}; + v8::Global promise_{}; + v8::Global ref_{}; }; // Asynchronous close - inline MaybeLocal ClosePromise(); + v8::MaybeLocal ClosePromise(); int fd_; bool closing_ = false; @@ -467,53 +314,23 @@ class FSReqWrapSync { // that nullptr indicates a synchronous call, rather than a failure. // Failure conditions should be disambiguated and handled appropriately. inline FSReqBase* GetReqWrap(Environment* env, v8::Local value, - bool use_bigint = false) { - if (value->IsObject()) { - return Unwrap(value.As()); - } else if (value->StrictEquals(env->fs_use_promises_symbol())) { - if (use_bigint) { - return FSReqPromise::New(env, use_bigint); - } else { - return FSReqPromise::New(env, use_bigint); - } - } - return nullptr; -} + bool use_bigint = false); // Returns nullptr if the operation fails from the start. template inline FSReqBase* AsyncDestCall(Environment* env, FSReqBase* req_wrap, - const v8::FunctionCallbackInfo& args, + const v8::FunctionCallbackInfo& args, const char* syscall, const char* dest, size_t len, enum encoding enc, uv_fs_cb after, - Func fn, Args... fn_args) { - CHECK_NOT_NULL(req_wrap); - req_wrap->Init(syscall, dest, len, enc); - int err = req_wrap->Dispatch(fn, fn_args..., after); - if (err < 0) { - uv_fs_t* uv_req = req_wrap->req(); - uv_req->result = err; - uv_req->path = nullptr; - after(uv_req); // after may delete req_wrap if there is an error - req_wrap = nullptr; - } else { - req_wrap->SetReturnValue(args); - } - - return req_wrap; -} + Func fn, Args... fn_args); // Returns nullptr if the operation fails from the start. template inline FSReqBase* AsyncCall(Environment* env, FSReqBase* req_wrap, - const v8::FunctionCallbackInfo& args, + const v8::FunctionCallbackInfo& args, const char* syscall, enum encoding enc, - uv_fs_cb after, Func fn, Args... fn_args) { - return AsyncDestCall(env, req_wrap, args, - syscall, nullptr, 0, enc, - after, fn, fn_args...); -} + uv_fs_cb after, Func fn, Args... fn_args); // Template counterpart of SYNC_CALL, except that it only puts // the error number and the syscall in the context instead of @@ -522,22 +339,7 @@ inline FSReqBase* AsyncCall(Environment* env, template inline int SyncCall(Environment* env, v8::Local ctx, FSReqWrapSync* req_wrap, const char* syscall, - Func fn, Args... args) { - env->PrintSyncTrace(); - int err = fn(env->event_loop(), &(req_wrap->req), args..., nullptr); - if (err < 0) { - v8::Local context = env->context(); - v8::Local ctx_obj = ctx.As(); - v8::Isolate* isolate = env->isolate(); - ctx_obj->Set(context, - env->errno_string(), - v8::Integer::New(isolate, err)).Check(); - ctx_obj->Set(context, - env->syscall_string(), - OneByteString(isolate, syscall)).Check(); - } - return err; -} + Func fn, Args... args); } // namespace fs -- cgit v1.2.3