Skip to content

Commit be84cee

Browse files
committed
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 #30475 (comment) for details. PR-URL: #30530 Reviewed-By: Jiawen Geng <[email protected]> Reviewed-By: David Carlier <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent bccfd12 commit be84cee

10 files changed

+462
-327
lines changed

node.gyp

+1
Original file line numberDiff line numberDiff line change
@@ -613,6 +613,7 @@
613613
'src/node_dir.h',
614614
'src/node_errors.h',
615615
'src/node_file.h',
616+
'src/node_file-inl.h',
616617
'src/node_http2.h',
617618
'src/node_http2_state.h',
618619
'src/node_i18n.h',

src/env.cc

+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "node_process.h"
1212
#include "node_v8_platform-inl.h"
1313
#include "node_worker.h"
14+
#include "req_wrap-inl.h"
1415
#include "tracing/agent.h"
1516
#include "tracing/traced_value.h"
1617
#include "util-inl.h"
@@ -35,6 +36,7 @@ using v8::HandleScope;
3536
using v8::Integer;
3637
using v8::Isolate;
3738
using v8::Local;
39+
using v8::MaybeLocal;
3840
using v8::NewStringType;
3941
using v8::Number;
4042
using v8::Object;

src/node_dir.cc

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
#include "node_dir.h"
2+
#include "node_file-inl.h"
23
#include "node_process.h"
4+
#include "memory_tracker-inl.h"
35
#include "util.h"
46

57
#include "tracing/trace_event.h"
68

7-
#include "req_wrap-inl.h"
89
#include "string_bytes.h"
910

1011
#include <fcntl.h>
@@ -85,6 +86,10 @@ DirHandle::~DirHandle() {
8586
CHECK(closed_); // We have to be closed at the point
8687
}
8788

89+
void DirHandle::MemoryInfo(MemoryTracker* tracker) const {
90+
tracker->TrackFieldWithSize("dir", sizeof(*dir_));
91+
}
92+
8893
// Close the directory handle if it hasn't already been closed. A process
8994
// warning will be emitted using a SetImmediate to avoid calling back to
9095
// JS during GC. If closing the fd fails at this point, a fatal exception

src/node_dir.h

+4-9
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
55

66
#include "node_file.h"
7-
#include "node.h"
8-
#include "req_wrap-inl.h"
97

108
namespace node {
119

@@ -20,16 +18,13 @@ class DirHandle : public AsyncWrap {
2018
~DirHandle() override;
2119

2220
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);
2624

2725
inline uv_dir_t* dir() { return dir_; }
2826

29-
void MemoryInfo(MemoryTracker* tracker) const override {
30-
tracker->TrackFieldWithSize("dir", sizeof(*dir_));
31-
}
32-
27+
void MemoryInfo(MemoryTracker* tracker) const override;
3328
SET_MEMORY_INFO_NAME(DirHandle)
3429
SET_SELF_SIZE(DirHandle)
3530

src/node_file-inl.h

+283
Original file line numberDiff line numberDiff 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_

0 commit comments

Comments
 (0)