@@ -148,6 +148,92 @@ class FSReqCallback : public FSReqBase {
148
148
DISALLOW_COPY_AND_ASSIGN (FSReqCallback);
149
149
};
150
150
151
+ // Wordaround a GCC4.9 bug that C++14 N3652 was not implemented
152
+ // Refs: https://www.gnu.org/software/gcc/projects/cxx-status.html#cxx14
153
+ // Refs: https://isocpp.org/files/papers/N3652.html
154
+ #if __cpp_constexpr < 201304
155
+ # define constexpr inline
156
+ #endif
157
+
158
+ template <typename NativeT,
159
+ // SFINAE limit NativeT to arithmetic types
160
+ typename = std::enable_if<std::is_arithmetic<NativeT>::value>>
161
+ constexpr NativeT ToNative (uv_timespec_t ts) {
162
+ // This template has exactly two specializations below.
163
+ static_assert (std::is_arithmetic<NativeT>::value == false , " Not implemented" );
164
+ UNREACHABLE ();
165
+ }
166
+
167
+ template <>
168
+ constexpr double ToNative (uv_timespec_t ts) {
169
+ // We need to do a static_cast since the original FS values are ulong.
170
+ /* NOLINTNEXTLINE(runtime/int) */
171
+ const auto u_sec = static_cast <unsigned long >(ts.tv_sec );
172
+ const double full_sec = u_sec * 1000.0 ;
173
+ /* NOLINTNEXTLINE(runtime/int) */
174
+ const auto u_nsec = static_cast <unsigned long >(ts.tv_nsec );
175
+ const double full_nsec = u_nsec / 1000'000.0 ;
176
+ return full_sec + full_nsec;
177
+ }
178
+
179
+ template <>
180
+ constexpr uint64_t ToNative (uv_timespec_t ts) {
181
+ // We need to do a static_cast since the original FS values are ulong.
182
+ /* NOLINTNEXTLINE(runtime/int) */
183
+ const auto u_sec = static_cast <unsigned long >(ts.tv_sec );
184
+ const auto full_sec = static_cast <uint64_t >(u_sec) * 1000UL ;
185
+ /* NOLINTNEXTLINE(runtime/int) */
186
+ const auto u_nsec = static_cast <unsigned long >(ts.tv_nsec );
187
+ const auto full_nsec = static_cast <uint64_t >(u_nsec) / 1000'000UL ;
188
+ return full_sec + full_nsec;
189
+ }
190
+
191
+ #undef constexpr // end N3652 bug workaround
192
+
193
+ template <typename NativeT, typename V8T>
194
+ constexpr void FillStatsArray (AliasedBuffer<NativeT, V8T>* fields,
195
+ const uv_stat_t * s, const size_t offset = 0 ) {
196
+ fields->SetValue (offset + 0 , s->st_dev );
197
+ fields->SetValue (offset + 1 , s->st_mode );
198
+ fields->SetValue (offset + 2 , s->st_nlink );
199
+ fields->SetValue (offset + 3 , s->st_uid );
200
+ fields->SetValue (offset + 4 , s->st_gid );
201
+ fields->SetValue (offset + 5 , s->st_rdev );
202
+ #if defined(__POSIX__)
203
+ fields->SetValue (offset + 6 , s->st_blksize );
204
+ #else
205
+ fields->SetValue (offset + 6 , 0 );
206
+ #endif
207
+ fields->SetValue (offset + 7 , s->st_ino );
208
+ fields->SetValue (offset + 8 , s->st_size );
209
+ #if defined(__POSIX__)
210
+ fields->SetValue (offset + 9 , s->st_blocks );
211
+ #else
212
+ fields->SetValue (offset + 9 , 0 );
213
+ #endif
214
+ // Dates.
215
+ fields->SetValue (offset + 10 , ToNative<NativeT>(s->st_atim ));
216
+ fields->SetValue (offset + 11 , ToNative<NativeT>(s->st_mtim ));
217
+ fields->SetValue (offset + 12 , ToNative<NativeT>(s->st_ctim ));
218
+ fields->SetValue (offset + 13 , ToNative<NativeT>(s->st_birthtim ));
219
+ }
220
+
221
+ inline Local<Value> FillGlobalStatsArray (Environment* env,
222
+ const bool use_bigint,
223
+ const uv_stat_t * s,
224
+ const bool second = false ) {
225
+ const ptrdiff_t offset = second ? kFsStatsFieldsNumber : 0 ;
226
+ if (use_bigint) {
227
+ auto * const arr = env->fs_stats_field_bigint_array ();
228
+ FillStatsArray (arr, s, offset);
229
+ return arr->GetJSArray ();
230
+ } else {
231
+ auto * const arr = env->fs_stats_field_array ();
232
+ FillStatsArray (arr, s, offset);
233
+ return arr->GetJSArray ();
234
+ }
235
+ }
236
+
151
237
template <typename NativeT = double , typename V8T = v8::Float64Array>
152
238
class FSReqPromise : public FSReqBase {
153
239
public:
@@ -157,7 +243,7 @@ class FSReqPromise : public FSReqBase {
157
243
->NewInstance(env->context ()).ToLocalChecked(),
158
244
AsyncWrap::PROVIDER_FSREQPROMISE,
159
245
use_bigint),
160
- stats_field_array_(env->isolate (), env->kFsStatsFieldsLength ) {
246
+ stats_field_array_(env->isolate (), kFsStatsFieldsNumber ) {
161
247
auto resolver = Promise::Resolver::New (env->context ()).ToLocalChecked ();
162
248
object ()->Set (env->context (), env->promise_string (),
163
249
resolver).FromJust ();
@@ -191,7 +277,8 @@ class FSReqPromise : public FSReqBase {
191
277
}
192
278
193
279
void ResolveStat (const uv_stat_t * stat) override {
194
- Resolve (node::FillStatsArray (&stats_field_array_, stat));
280
+ FillStatsArray (&stats_field_array_, stat);
281
+ Resolve (stats_field_array_.GetJSArray ());
195
282
}
196
283
197
284
void SetReturnValue (const FunctionCallbackInfo<Value>& args) override {
0 commit comments