summaryrefslogtreecommitdiff
path: root/src/node_file.h
diff options
context:
space:
mode:
authorAnna Henningsen <anna@addaleax.net>2019-11-18 14:49:56 +0100
committergengjiawen <technicalcute@gmail.com>2019-11-30 08:51:06 +0000
commit52a3e3560484ec3ad4479ef80d829f7c99d39e80 (patch)
tree550033e4de5f83add146bfccec15bd6dc70a2f9c /src/node_file.h
parent6c4cf862d0f17be7a4113d720567d3ce8f2d6fac (diff)
downloadandroid-node-v8-52a3e3560484ec3ad4479ef80d829f7c99d39e80.tar.gz
android-node-v8-52a3e3560484ec3ad4479ef80d829f7c99d39e80.tar.bz2
android-node-v8-52a3e3560484ec3ad4479ef80d829f7c99d39e80.zip
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 <technicalcute@gmail.com> Reviewed-By: David Carlier <devnexen@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Diffstat (limited to 'src/node_file.h')
-rw-r--r--src/node_file.h382
1 files changed, 92 insertions, 290 deletions
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 <iostream>
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<std::string> 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<std::string>& 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<std::string> paths_;
};
class FSReqBase : public ReqWrap<uv_fs_t> {
public:
typedef MaybeStackBuffer<char, 64> FSReqBuffer;
- std::unique_ptr<FSContinuationData> continuation_data = nullptr;
-
- FSReqBase(Environment* env, Local<Object> 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<Value> reject) = 0;
- virtual void Resolve(Local<Value> value) = 0;
+ inline FSReqBase(Environment* env,
+ v8::Local<v8::Object> 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<v8::Value> reject) = 0;
+ virtual void Resolve(v8::Local<v8::Value> value) = 0;
virtual void ResolveStat(const uv_stat_t* stat) = 0;
- virtual void SetReturnValue(const FunctionCallbackInfo<Value>& args) = 0;
+ virtual void SetReturnValue(
+ const v8::FunctionCallbackInfo<v8::Value>& 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<FSContinuationData> data) {
+ continuation_data_ = std::move(data);
+ }
+
static FSReqBase* from_req(uv_fs_t* req) {
return static_cast<FSReqBase*>(ReqWrap::from_req(req));
}
@@ -120,7 +77,10 @@ class FSReqBase : public ReqWrap<uv_fs_t> {
FSReqBase(const FSReqBase&) = delete;
FSReqBase& operator=(const FSReqBase&) = delete;
+ void MemoryInfo(MemoryTracker* tracker) const override;
+
private:
+ std::unique_ptr<FSContinuationData> continuation_data_;
enum encoding encoding_ = UTF8;
bool has_data_ = false;
const char* syscall_ = nullptr;
@@ -131,19 +91,16 @@ class FSReqBase : public ReqWrap<uv_fs_t> {
FSReqBuffer buffer_;
};
-class FSReqCallback : public FSReqBase {
+class FSReqCallback final : public FSReqBase {
public:
- FSReqCallback(Environment* env, Local<Object> req, bool use_bigint)
- : FSReqBase(env, req, AsyncWrap::PROVIDER_FSREQCALLBACK, use_bigint) { }
+ inline FSReqCallback(Environment* env,
+ v8::Local<v8::Object> req,
+ bool use_bigint);
- void Reject(Local<Value> reject) override;
- void Resolve(Local<Value> value) override;
+ void Reject(v8::Local<v8::Value> reject) override;
+ void Resolve(v8::Local<v8::Value> value) override;
void ResolveStat(const uv_stat_t* stat) override;
- void SetReturnValue(const FunctionCallbackInfo<Value>& args) override;
-
- void MemoryInfo(MemoryTracker* tracker) const override {
- tracker->TrackField("continuation_data", continuation_data);
- }
+ void SetReturnValue(const v8::FunctionCallbackInfo<v8::Value>& args) override;
SET_MEMORY_INFO_NAME(FSReqCallback)
SET_SELF_SIZE(FSReqCallback)
@@ -153,120 +110,27 @@ class FSReqCallback : public FSReqBase {
};
template <typename NativeT, typename V8T>
-constexpr void FillStatsArray(AliasedBufferBase<NativeT, V8T>* fields,
- const uv_stat_t* s,
- const size_t offset = 0) {
-#define SET_FIELD_WITH_STAT(stat_offset, stat) \
- fields->SetValue(offset + static_cast<size_t>(FsStatsOffset::stat_offset), \
- static_cast<NativeT>(stat))
-
-#define SET_FIELD_WITH_TIME_STAT(stat_offset, stat) \
- /* NOLINTNEXTLINE(runtime/int) */ \
- SET_FIELD_WITH_STAT(stat_offset, static_cast<unsigned long>(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<Value> FillGlobalStatsArray(Environment* env,
- const bool use_bigint,
- const uv_stat_t* s,
- const bool second = false) {
- const ptrdiff_t offset =
- second ? static_cast<ptrdiff_t>(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<NativeT, V8T>* fields,
+ const uv_stat_t* s,
+ const size_t offset = 0);
+
+inline v8::Local<v8::Value> FillGlobalStatsArray(Environment* env,
+ const bool use_bigint,
+ const uv_stat_t* s,
+ const bool second = false);
template <typename AliasedBufferT>
-class FSReqPromise : public FSReqBase {
+class FSReqPromise final : public FSReqBase {
public:
- static FSReqPromise* New(Environment* env, bool use_bigint) {
- v8::Local<Object> obj;
- if (!env->fsreqpromise_constructor_template()
- ->NewInstance(env->context())
- .ToLocal(&obj)) {
- return nullptr;
- }
- v8::Local<v8::Promise::Resolver> 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<Value> reject) override {
- finished_ = true;
- HandleScope scope(env()->isolate());
- InternalCallbackScope callback_scope(this);
- Local<Value> value =
- object()->Get(env()->context(),
- env()->promise_string()).ToLocalChecked();
- Local<Promise::Resolver> resolver = value.As<Promise::Resolver>();
- USE(resolver->Reject(env()->context(), reject).FromJust());
- }
-
- void Resolve(Local<Value> value) override {
- finished_ = true;
- HandleScope scope(env()->isolate());
- InternalCallbackScope callback_scope(this);
- Local<Value> val =
- object()->Get(env()->context(),
- env()->promise_string()).ToLocalChecked();
- Local<Promise::Resolver> resolver = val.As<Promise::Resolver>();
- 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<Value>& args) override {
- Local<Value> val =
- object()->Get(env()->context(),
- env()->promise_string()).ToLocalChecked();
- Local<Promise::Resolver> resolver = val.As<Promise::Resolver>();
- 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<v8::Value> reject) override;
+ inline void Resolve(v8::Local<v8::Value> value) override;
+ inline void ResolveStat(const uv_stat_t* stat) override;
+ inline void SetReturnValue(
+ const v8::FunctionCallbackInfo<v8::Value>& 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<v8::Object> obj, bool use_bigint)
- : FSReqBase(env, obj, AsyncWrap::PROVIDER_FSREQPROMISE, use_bigint),
- stats_field_array_(
- env->isolate(),
- static_cast<size_t>(FsStatsOffset::kFsStatsFieldsNumber)) {}
+ inline FSReqPromise(Environment* env,
+ v8::Local<v8::Object> 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<uv_fs_t> {
+class FileHandleReadWrap final : public ReqWrap<uv_fs_t> {
public:
FileHandleReadWrap(FileHandle* handle, v8::Local<v8::Object> obj);
+ ~FileHandleReadWrap() override;
static inline FileHandleReadWrap* from_req(uv_fs_t* req) {
return static_cast<FileHandleReadWrap*>(ReqWrap::from_req(req));
@@ -333,7 +196,7 @@ class FileHandleReadWrap : public ReqWrap<uv_fs_t> {
// 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<Value>& args);
+ static void Close(const v8::FunctionCallbackInfo<v8::Value>& args);
// Releases ownership of the FD.
- static void ReleaseFD(const FunctionCallbackInfo<Value>& args);
+ static void ReleaseFD(const v8::FunctionCallbackInfo<v8::Value>& 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<uv_fs_t> {
+ class CloseReq final : public ReqWrap<uv_fs_t> {
public:
CloseReq(Environment* env,
- Local<Object> obj,
- Local<Promise> promise,
- Local<Value> 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<v8::Object> obj,
+ v8::Local<v8::Promise> promise,
+ v8::Local<v8::Value> 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<Value> reason);
+ void Reject(v8::Local<v8::Value> reason);
static CloseReq* from_req(uv_fs_t* req) {
return static_cast<CloseReq*>(ReqWrap::from_req(req));
@@ -430,12 +277,12 @@ class FileHandle : public AsyncWrap, public StreamBase {
CloseReq& operator=(const CloseReq&&) = delete;
private:
- v8::Global<Promise> promise_{};
- v8::Global<Value> ref_{};
+ v8::Global<v8::Promise> promise_{};
+ v8::Global<v8::Value> ref_{};
};
// Asynchronous close
- inline MaybeLocal<Promise> ClosePromise();
+ v8::MaybeLocal<v8::Promise> 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<v8::Value> value,
- bool use_bigint = false) {
- if (value->IsObject()) {
- return Unwrap<FSReqBase>(value.As<Object>());
- } else if (value->StrictEquals(env->fs_use_promises_symbol())) {
- if (use_bigint) {
- return FSReqPromise<AliasedBigUint64Array>::New(env, use_bigint);
- } else {
- return FSReqPromise<AliasedFloat64Array>::New(env, use_bigint);
- }
- }
- return nullptr;
-}
+ bool use_bigint = false);
// Returns nullptr if the operation fails from the start.
template <typename Func, typename... Args>
inline FSReqBase* AsyncDestCall(Environment* env, FSReqBase* req_wrap,
- const v8::FunctionCallbackInfo<Value>& args,
+ const v8::FunctionCallbackInfo<v8::Value>& 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 <typename Func, typename... Args>
inline FSReqBase* AsyncCall(Environment* env,
FSReqBase* req_wrap,
- const v8::FunctionCallbackInfo<Value>& args,
+ const v8::FunctionCallbackInfo<v8::Value>& 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 <typename Func, typename... Args>
inline int SyncCall(Environment* env, v8::Local<v8::Value> 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> context = env->context();
- v8::Local<Object> ctx_obj = ctx.As<v8::Object>();
- 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