@@ -148,6 +148,92 @@ class FSReqCallback : public FSReqBase {
148148  DISALLOW_COPY_AND_ASSIGN (FSReqCallback);
149149};
150150
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+ 
151237template  <typename  NativeT = double , typename  V8T = v8::Float64Array>
152238class  FSReqPromise  : public  FSReqBase  {
153239 public: 
@@ -157,7 +243,7 @@ class FSReqPromise : public FSReqBase {
157243                      ->NewInstance(env->context ()).ToLocalChecked(),
158244                  AsyncWrap::PROVIDER_FSREQPROMISE,
159245                  use_bigint),
160-         stats_field_array_(env->isolate (), env->kFsStatsFieldsLength ) {
246+         stats_field_array_(env->isolate (), kFsStatsFieldsNumber ) {
161247    auto  resolver = Promise::Resolver::New (env->context ()).ToLocalChecked ();
162248    object ()->Set (env->context (), env->promise_string (),
163249                  resolver).FromJust ();
@@ -191,7 +277,8 @@ class FSReqPromise : public FSReqBase {
191277  }
192278
193279  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 ());
195282  }
196283
197284  void  SetReturnValue (const  FunctionCallbackInfo<Value>& args) override  {
0 commit comments