| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent c79f485 commit 33064a1
10 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -616,6 +616,7 @@ | |||
| 616 | 616 | 'src/node_dir.h', | |
| 617 | 617 | 'src/node_errors.h', | |
| 618 | 618 | 'src/node_file.h', | |
| 619 | + 'src/node_file-inl.h', | ||
| 619 | 620 | 'src/node_http_parser_impl.h', | |
| 620 | 621 | 'src/node_http2.h', | |
| 621 | 622 | 'src/node_http2_state.h', | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -11,6 +11,7 @@ | |||
| 11 | 11 | #include "node_process.h" | |
| 12 | 12 | #include "node_v8_platform-inl.h" | |
| 13 | 13 | #include "node_worker.h" | |
| 14 | + #include "req_wrap-inl.h" | ||
| 14 | 15 | #include "tracing/agent.h" | |
| 15 | 16 | #include "tracing/traced_value.h" | |
| 16 | 17 | #include "util-inl.h" | |
@@ -35,6 +36,7 @@ using v8::HandleScope; | |||
| 35 | 36 | using v8::Integer; | |
| 36 | 37 | using v8::Isolate; | |
| 37 | 38 | using v8::Local; | |
| 39 | + using v8::MaybeLocal; | ||
| 38 | 40 | using v8::NewStringType; | |
| 39 | 41 | using v8::Number; | |
| 40 | 42 | using v8::Object; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,10 +1,11 @@ | |||
| 1 | 1 | #include "node_dir.h" | |
| 2 | + #include "node_file-inl.h" | ||
| 2 | 3 | #include "node_process.h" | |
| 4 | + #include "memory_tracker-inl.h" | ||
| 3 | 5 | #include "util.h" | |
| 4 | 6 | ||
| 5 | 7 | #include "tracing/trace_event.h" | |
| 6 | 8 | ||
| 7 | - #include "req_wrap-inl.h" | ||
| 8 | 9 | #include "string_bytes.h" | |
| 9 | 10 | ||
| 10 | 11 | #include <fcntl.h> | |
@@ -85,6 +86,10 @@ DirHandle::~DirHandle() { | |||
| 85 | 86 | CHECK(closed_); // We have to be closed at the point | |
| 86 | 87 | } | |
| 87 | 88 | ||
| 89 | + void DirHandle::MemoryInfo(MemoryTracker* tracker) const { | ||
| 90 | + tracker->TrackFieldWithSize("dir", sizeof(*dir_)); | ||
| 91 | + } | ||
| 92 | + | ||
| 88 | 93 | // Close the directory handle if it hasn't already been closed. A process | |
| 89 | 94 | // warning will be emitted using a SetImmediate to avoid calling back to | |
| 90 | 95 | // JS during GC. If closing the fd fails at this point, a fatal exception | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -4,8 +4,6 @@ | |||
| 4 | 4 | #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS | |
| 5 | 5 | ||
| 6 | 6 | #include "node_file.h" | |
| 7 | - #include "node.h" | ||
| 8 | - #include "req_wrap-inl.h" | ||
| 9 | 7 | ||
| 10 | 8 | namespace node { | |
| 11 | 9 | ||
@@ -20,16 +18,13 @@ class DirHandle : public AsyncWrap { | |||
| 20 | 18 | ~DirHandle() override; | |
| 21 | 19 | ||
| 22 | 20 | static void New(const v8::FunctionCallbackInfo<v8::Value>& args); | |
| 23 | - static void Open(const v8::FunctionCallbackInfo<Value>& args); | ||
| 24 | - static void Read(const v8::FunctionCallbackInfo<Value>& args); | ||
| 25 | - static void Close(const v8::FunctionCallbackInfo<Value>& args); | ||
| 21 | + static void Open(const v8::FunctionCallbackInfo<v8::Value>& args); | ||
| 22 | + static void Read(const v8::FunctionCallbackInfo<v8::Value>& args); | ||
| 23 | + static void Close(const v8::FunctionCallbackInfo<v8::Value>& args); | ||
| 26 | 24 | ||
| 27 | 25 | inline uv_dir_t* dir() { return dir_; } | |
| 28 | 26 | ||
| 29 | - void MemoryInfo(MemoryTracker* tracker) const override { | ||
| 30 | - tracker->TrackFieldWithSize("dir", sizeof(*dir_)); | ||
| 31 | - } | ||
| 32 | - | ||
| 27 | + void MemoryInfo(MemoryTracker* tracker) const override; | ||
| 33 | 28 | SET_MEMORY_INFO_NAME(DirHandle) | |
| 34 | 29 | SET_SELF_SIZE(DirHandle) | |
| 35 | 30 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,283 @@ | |||
| 1 | + #ifndef SRC_NODE_FILE_INL_H_ | ||
| 2 | + #define SRC_NODE_FILE_INL_H_ | ||
| 3 | + | ||
| 4 | + #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS | ||
| 5 | + | ||
| 6 | + #include "node_file.h" | ||
| 7 | + #include "req_wrap-inl.h" | ||
| 8 | + | ||
| 9 | + namespace node { | ||
| 10 | + namespace fs { | ||
| 11 | + | ||
| 12 | + FSContinuationData::FSContinuationData(uv_fs_t* req, int mode, uv_fs_cb done_cb) | ||
| 13 | + : done_cb_(done_cb), req_(req), mode_(mode) { | ||
| 14 | + } | ||
| 15 | + | ||
| 16 | + void FSContinuationData::PushPath(std::string&& path) { | ||
| 17 | + paths_.emplace_back(std::move(path)); | ||
| 18 | + } | ||
| 19 | + | ||
| 20 | + void FSContinuationData::PushPath(const std::string& path) { | ||
| 21 | + paths_.push_back(path); | ||
| 22 | + } | ||
| 23 | + | ||
| 24 | + std::string FSContinuationData::PopPath() { | ||
| 25 | + CHECK_GT(paths_.size(), 0); | ||
| 26 | + std::string path = std::move(paths_.back()); | ||
| 27 | + paths_.pop_back(); | ||
| 28 | + return path; | ||
| 29 | + } | ||
| 30 | + | ||
| 31 | + void FSContinuationData::Done(int result) { | ||
| 32 | + req_->result = result; | ||
| 33 | + done_cb_(req_); | ||
| 34 | + } | ||
| 35 | + | ||
| 36 | + FSReqBase::FSReqBase(Environment* env, | ||
| 37 | + v8::Local<v8::Object> req, | ||
| 38 | + AsyncWrap::ProviderType type, | ||
| 39 | + bool use_bigint) | ||
| 40 | + : ReqWrap(env, req, type), use_bigint_(use_bigint) { | ||
| 41 | + } | ||
| 42 | + | ||
| 43 | + void FSReqBase::Init(const char* syscall, | ||
| 44 | + const char* data, | ||
| 45 | + size_t len, | ||
| 46 | + enum encoding encoding) { | ||
| 47 | + syscall_ = syscall; | ||
| 48 | + encoding_ = encoding; | ||
| 49 | + | ||
| 50 | + if (data != nullptr) { | ||
| 51 | + CHECK(!has_data_); | ||
| 52 | + buffer_.AllocateSufficientStorage(len + 1); | ||
| 53 | + buffer_.SetLengthAndZeroTerminate(len); | ||
| 54 | + memcpy(*buffer_, data, len); | ||
| 55 | + has_data_ = true; | ||
| 56 | + } | ||
| 57 | + } | ||
| 58 | + | ||
| 59 | + FSReqBase::FSReqBuffer& | ||
| 60 | + FSReqBase::Init(const char* syscall, size_t len, enum encoding encoding) { | ||
| 61 | + syscall_ = syscall; | ||
| 62 | + encoding_ = encoding; | ||
| 63 | + | ||
| 64 | + buffer_.AllocateSufficientStorage(len + 1); | ||
| 65 | + has_data_ = false; // so that the data does not show up in error messages | ||
| 66 | + return buffer_; | ||
| 67 | + } | ||
| 68 | + | ||
| 69 | + FSReqCallback::FSReqCallback(Environment* env, | ||
| 70 | + v8::Local<v8::Object> req, bool use_bigint) | ||
| 71 | + : FSReqBase(env, req, AsyncWrap::PROVIDER_FSREQCALLBACK, use_bigint) {} | ||
| 72 | + | ||
| 73 | + template <typename NativeT, typename V8T> | ||
| 74 | + void FillStatsArray(AliasedBufferBase<NativeT, V8T>* fields, | ||
| 75 | + const uv_stat_t* s, | ||
| 76 | + const size_t offset) { | ||
| 77 | + #define SET_FIELD_WITH_STAT(stat_offset, stat) \ | ||
| 78 | + fields->SetValue(offset + static_cast<size_t>(FsStatsOffset::stat_offset), \ | ||
| 79 | + static_cast<NativeT>(stat)) | ||
| 80 | + | ||
| 81 | + #define SET_FIELD_WITH_TIME_STAT(stat_offset, stat) \ | ||
| 82 | + /* NOLINTNEXTLINE(runtime/int) */ \ | ||
| 83 | + SET_FIELD_WITH_STAT(stat_offset, static_cast<unsigned long>(stat)) | ||
| 84 | + | ||
| 85 | + SET_FIELD_WITH_STAT(kDev, s->st_dev); | ||
| 86 | + SET_FIELD_WITH_STAT(kMode, s->st_mode); | ||
| 87 | + SET_FIELD_WITH_STAT(kNlink, s->st_nlink); | ||
| 88 | + SET_FIELD_WITH_STAT(kUid, s->st_uid); | ||
| 89 | + SET_FIELD_WITH_STAT(kGid, s->st_gid); | ||
| 90 | + SET_FIELD_WITH_STAT(kRdev, s->st_rdev); | ||
| 91 | + SET_FIELD_WITH_STAT(kBlkSize, s->st_blksize); | ||
| 92 | + SET_FIELD_WITH_STAT(kIno, s->st_ino); | ||
| 93 | + SET_FIELD_WITH_STAT(kSize, s->st_size); | ||
| 94 | + SET_FIELD_WITH_STAT(kBlocks, s->st_blocks); | ||
| 95 | + | ||
| 96 | + SET_FIELD_WITH_TIME_STAT(kATimeSec, s->st_atim.tv_sec); | ||
| 97 | + SET_FIELD_WITH_TIME_STAT(kATimeNsec, s->st_atim.tv_nsec); | ||
| 98 | + SET_FIELD_WITH_TIME_STAT(kMTimeSec, s->st_mtim.tv_sec); | ||
| 99 | + SET_FIELD_WITH_TIME_STAT(kMTimeNsec, s->st_mtim.tv_nsec); | ||
| 100 | + SET_FIELD_WITH_TIME_STAT(kCTimeSec, s->st_ctim.tv_sec); | ||
| 101 | + SET_FIELD_WITH_TIME_STAT(kCTimeNsec, s->st_ctim.tv_nsec); | ||
| 102 | + SET_FIELD_WITH_TIME_STAT(kBirthTimeSec, s->st_birthtim.tv_sec); | ||
| 103 | + SET_FIELD_WITH_TIME_STAT(kBirthTimeNsec, s->st_birthtim.tv_nsec); | ||
| 104 | + | ||
| 105 | + #undef SET_FIELD_WITH_TIME_STAT | ||
| 106 | + #undef SET_FIELD_WITH_STAT | ||
| 107 | + } | ||
| 108 | + | ||
| 109 | + v8::Local<v8::Value> FillGlobalStatsArray(Environment* env, | ||
| 110 | + const bool use_bigint, | ||
| 111 | + const uv_stat_t* s, | ||
| 112 | + const bool second) { | ||
| 113 | + const ptrdiff_t offset = | ||
| 114 | + second ? static_cast<ptrdiff_t>(FsStatsOffset::kFsStatsFieldsNumber) : 0; | ||
| 115 | + if (use_bigint) { | ||
| 116 | + auto* const arr = env->fs_stats_field_bigint_array(); | ||
| 117 | + FillStatsArray(arr, s, offset); | ||
| 118 | + return arr->GetJSArray(); | ||
| 119 | + } else { | ||
| 120 | + auto* const arr = env->fs_stats_field_array(); | ||
| 121 | + FillStatsArray(arr, s, offset); | ||
| 122 | + return arr->GetJSArray(); | ||
| 123 | + } | ||
| 124 | + } | ||
| 125 | + | ||
| 126 | + template <typename AliasedBufferT> | ||
| 127 | + FSReqPromise<AliasedBufferT>* | ||
| 128 | + FSReqPromise<AliasedBufferT>::New(Environment* env, bool use_bigint) { | ||
| 129 | + v8::Local<v8::Object> obj; | ||
| 130 | + if (!env->fsreqpromise_constructor_template() | ||
| 131 | + ->NewInstance(env->context()) | ||
| 132 | + .ToLocal(&obj)) { | ||
| 133 | + return nullptr; | ||
| 134 | + } | ||
| 135 | + v8::Local<v8::Promise::Resolver> resolver; | ||
| 136 | + if (!v8::Promise::Resolver::New(env->context()).ToLocal(&resolver) || | ||
| 137 | + obj->Set(env->context(), env->promise_string(), resolver).IsNothing()) { | ||
| 138 | + return nullptr; | ||
| 139 | + } | ||
| 140 | + return new FSReqPromise(env, obj, use_bigint); | ||
| 141 | + } | ||
| 142 | + | ||
| 143 | + template <typename AliasedBufferT> | ||
| 144 | + FSReqPromise<AliasedBufferT>::~FSReqPromise() { | ||
| 145 | + // Validate that the promise was explicitly resolved or rejected. | ||
| 146 | + CHECK(finished_); | ||
| 147 | + } | ||
| 148 | + | ||
| 149 | + template <typename AliasedBufferT> | ||
| 150 | + FSReqPromise<AliasedBufferT>::FSReqPromise( | ||
| 151 | + Environment* env, | ||
| 152 | + v8::Local<v8::Object> obj, | ||
| 153 | + bool use_bigint) | ||
| 154 | + : FSReqBase(env, obj, AsyncWrap::PROVIDER_FSREQPROMISE, use_bigint), | ||
| 155 | + stats_field_array_( | ||
| 156 | + env->isolate(), | ||
| 157 | + static_cast<size_t>(FsStatsOffset::kFsStatsFieldsNumber)) {} | ||
| 158 | + | ||
| 159 | + template <typename AliasedBufferT> | ||
| 160 | + void FSReqPromise<AliasedBufferT>::Reject(v8::Local<v8::Value> reject) { | ||
| 161 | + finished_ = true; | ||
| 162 | + v8::HandleScope scope(env()->isolate()); | ||
| 163 | + InternalCallbackScope callback_scope(this); | ||
| 164 | + v8::Local<v8::Value> value = | ||
| 165 | + object()->Get(env()->context(), | ||
| 166 | + env()->promise_string()).ToLocalChecked(); | ||
| 167 | + v8::Local<v8::Promise::Resolver> resolver = value.As<v8::Promise::Resolver>(); | ||
| 168 | + USE(resolver->Reject(env()->context(), reject).FromJust()); | ||
| 169 | + } | ||
| 170 | + | ||
| 171 | + template <typename AliasedBufferT> | ||
| 172 | + void FSReqPromise<AliasedBufferT>::Resolve(v8::Local<v8::Value> value) { | ||
| 173 | + finished_ = true; | ||
| 174 | + v8::HandleScope scope(env()->isolate()); | ||
| 175 | + InternalCallbackScope callback_scope(this); | ||
| 176 | + v8::Local<v8::Value> val = | ||
| 177 | + object()->Get(env()->context(), | ||
| 178 | + env()->promise_string()).ToLocalChecked(); | ||
| 179 | + v8::Local<v8::Promise::Resolver> resolver = val.As<v8::Promise::Resolver>(); | ||
| 180 | + USE(resolver->Resolve(env()->context(), value).FromJust()); | ||
| 181 | + } | ||
| 182 | + | ||
| 183 | + template <typename AliasedBufferT> | ||
| 184 | + void FSReqPromise<AliasedBufferT>::ResolveStat(const uv_stat_t* stat) { | ||
| 185 | + FillStatsArray(&stats_field_array_, stat); | ||
| 186 | + Resolve(stats_field_array_.GetJSArray()); | ||
| 187 | + } | ||
| 188 | + | ||
| 189 | + template <typename AliasedBufferT> | ||
| 190 | + void FSReqPromise<AliasedBufferT>::SetReturnValue( | ||
| 191 | + const v8::FunctionCallbackInfo<v8::Value>& args) { | ||
| 192 | + v8::Local<v8::Value> val = | ||
| 193 | + object()->Get(env()->context(), | ||
| 194 | + env()->promise_string()).ToLocalChecked(); | ||
| 195 | + v8::Local<v8::Promise::Resolver> resolver = val.As<v8::Promise::Resolver>(); | ||
| 196 | + args.GetReturnValue().Set(resolver->GetPromise()); | ||
| 197 | + } | ||
| 198 | + | ||
| 199 | + template <typename AliasedBufferT> | ||
| 200 | + void FSReqPromise<AliasedBufferT>::MemoryInfo(MemoryTracker* tracker) const { | ||
| 201 | + FSReqBase::MemoryInfo(tracker); | ||
| 202 | + tracker->TrackField("stats_field_array", stats_field_array_); | ||
| 203 | + } | ||
| 204 | + | ||
| 205 | + FSReqBase* GetReqWrap(Environment* env, v8::Local<v8::Value> value, | ||
| 206 | + bool use_bigint) { | ||
| 207 | + if (value->IsObject()) { | ||
| 208 | + return Unwrap<FSReqBase>(value.As<v8::Object>()); | ||
| 209 | + } else if (value->StrictEquals(env->fs_use_promises_symbol())) { | ||
| 210 | + if (use_bigint) { | ||
| 211 | + return FSReqPromise<AliasedBigUint64Array>::New(env, use_bigint); | ||
| 212 | + } else { | ||
| 213 | + return FSReqPromise<AliasedFloat64Array>::New(env, use_bigint); | ||
| 214 | + } | ||
| 215 | + } | ||
| 216 | + return nullptr; | ||
| 217 | + } | ||
| 218 | + | ||
| 219 | + // Returns nullptr if the operation fails from the start. | ||
| 220 | + template <typename Func, typename... Args> | ||
| 221 | + FSReqBase* AsyncDestCall(Environment* env, FSReqBase* req_wrap, | ||
| 222 | + const v8::FunctionCallbackInfo<v8::Value>& args, | ||
| 223 | + const char* syscall, const char* dest, | ||
| 224 | + size_t len, enum encoding enc, uv_fs_cb after, | ||
| 225 | + Func fn, Args... fn_args) { | ||
| 226 | + CHECK_NOT_NULL(req_wrap); | ||
| 227 | + req_wrap->Init(syscall, dest, len, enc); | ||
| 228 | + int err = req_wrap->Dispatch(fn, fn_args..., after); | ||
| 229 | + if (err < 0) { | ||
| 230 | + uv_fs_t* uv_req = req_wrap->req(); | ||
| 231 | + uv_req->result = err; | ||
| 232 | + uv_req->path = nullptr; | ||
| 233 | + after(uv_req); // after may delete req_wrap if there is an error | ||
| 234 | + req_wrap = nullptr; | ||
| 235 | + } else { | ||
| 236 | + req_wrap->SetReturnValue(args); | ||
| 237 | + } | ||
| 238 | + | ||
| 239 | + return req_wrap; | ||
| 240 | + } | ||
| 241 | + | ||
| 242 | + // Returns nullptr if the operation fails from the start. | ||
| 243 | + template <typename Func, typename... Args> | ||
| 244 | + FSReqBase* AsyncCall(Environment* env, | ||
| 245 | + FSReqBase* req_wrap, | ||
| 246 | + const v8::FunctionCallbackInfo<v8::Value>& args, | ||
| 247 | + const char* syscall, enum encoding enc, | ||
| 248 | + uv_fs_cb after, Func fn, Args... fn_args) { | ||
| 249 | + return AsyncDestCall(env, req_wrap, args, | ||
| 250 | + syscall, nullptr, 0, enc, | ||
| 251 | + after, fn, fn_args...); | ||
| 252 | + } | ||
| 253 | + | ||
| 254 | + // Template counterpart of SYNC_CALL, except that it only puts | ||
| 255 | + // the error number and the syscall in the context instead of | ||
| 256 | + // creating an error in the C++ land. | ||
| 257 | + // ctx must be checked using value->IsObject() before being passed. | ||
| 258 | + template <typename Func, typename... Args> | ||
| 259 | + int SyncCall(Environment* env, v8::Local<v8::Value> ctx, | ||
| 260 | + FSReqWrapSync* req_wrap, const char* syscall, | ||
| 261 | + Func fn, Args... args) { | ||
| 262 | + env->PrintSyncTrace(); | ||
| 263 | + int err = fn(env->event_loop(), &(req_wrap->req), args..., nullptr); | ||
| 264 | + if (err < 0) { | ||
| 265 | + v8::Local<v8::Context> context = env->context(); | ||
| 266 | + v8::Local<v8::Object> ctx_obj = ctx.As<v8::Object>(); | ||
| 267 | + v8::Isolate* isolate = env->isolate(); | ||
| 268 | + ctx_obj->Set(context, | ||
| 269 | + env->errno_string(), | ||
| 270 | + v8::Integer::New(isolate, err)).Check(); | ||
| 271 | + ctx_obj->Set(context, | ||
| 272 | + env->syscall_string(), | ||
| 273 | + OneByteString(isolate, syscall)).Check(); | ||
| 274 | + } | ||
| 275 | + return err; | ||
| 276 | + } | ||
| 277 | + | ||
| 278 | + } // namespace fs | ||
| 279 | + } // namespace node | ||
| 280 | + | ||
| 281 | + #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS | ||
| 282 | + | ||
| 283 | + #endif // SRC_NODE_FILE_INL_H_ | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments