• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "async_wrap-inl.h"
2 #include "base_object-inl.h"
3 #include "debug_utils-inl.h"
4 #include "env-inl.h"
5 #include "memory_tracker-inl.h"
6 #include "node.h"
7 #include "node_errors.h"
8 #include "node_external_reference.h"
9 #include "node_internals.h"
10 #include "node_process-inl.h"
11 #include "util-inl.h"
12 #include "uv.h"
13 #include "v8-fast-api-calls.h"
14 #include "v8.h"
15 
16 #include <vector>
17 
18 #if HAVE_INSPECTOR
19 #include "inspector_io.h"
20 #endif
21 
22 #include <climits>  // PATH_MAX
23 #include <cstdio>
24 
25 #if defined(_MSC_VER)
26 #include <direct.h>
27 #include <io.h>
28 #define umask _umask
29 typedef int mode_t;
30 #else
31 #include <pthread.h>
32 #include <sys/resource.h>  // getrlimit, setrlimit
33 #include <termios.h>  // tcgetattr, tcsetattr
34 #endif
35 
36 namespace node {
37 
38 using v8::Array;
39 using v8::ArrayBuffer;
40 using v8::CFunction;
41 using v8::Context;
42 using v8::Float64Array;
43 using v8::FunctionCallbackInfo;
44 using v8::HeapStatistics;
45 using v8::Integer;
46 using v8::Isolate;
47 using v8::Local;
48 using v8::NewStringType;
49 using v8::Number;
50 using v8::Object;
51 using v8::String;
52 using v8::Uint32;
53 using v8::Value;
54 
55 namespace per_process {
56 Mutex umask_mutex;
57 }   // namespace per_process
58 
59 // Microseconds in a second, as a float, used in CPUUsage() below
60 #define MICROS_PER_SEC 1e6
61 // used in Hrtime() and Uptime() below
62 #define NANOS_PER_SEC 1000000000
63 
Abort(const FunctionCallbackInfo<Value> & args)64 static void Abort(const FunctionCallbackInfo<Value>& args) {
65   Abort();
66 }
67 
68 // For internal testing only, not exposed to userland.
CauseSegfault(const FunctionCallbackInfo<Value> & args)69 static void CauseSegfault(const FunctionCallbackInfo<Value>& args) {
70   // This should crash hard all platforms.
71   volatile void** d = static_cast<volatile void**>(nullptr);
72   *d = nullptr;
73 }
74 
Chdir(const FunctionCallbackInfo<Value> & args)75 static void Chdir(const FunctionCallbackInfo<Value>& args) {
76   Environment* env = Environment::GetCurrent(args);
77   CHECK(env->owns_process_state());
78 
79   CHECK_EQ(args.Length(), 1);
80   CHECK(args[0]->IsString());
81   Utf8Value path(env->isolate(), args[0]);
82   int err = uv_chdir(*path);
83   if (err) {
84     // Also include the original working directory, since that will usually
85     // be helpful information when debugging a `chdir()` failure.
86     char buf[PATH_MAX_BYTES];
87     size_t cwd_len = sizeof(buf);
88     uv_cwd(buf, &cwd_len);
89     return env->ThrowUVException(err, "chdir", nullptr, buf, *path);
90   }
91 }
92 
get_fields_array_buffer(const FunctionCallbackInfo<Value> & args,size_t index,size_t array_length)93 inline Local<ArrayBuffer> get_fields_array_buffer(
94     const FunctionCallbackInfo<Value>& args,
95     size_t index,
96     size_t array_length) {
97   CHECK(args[index]->IsFloat64Array());
98   Local<Float64Array> arr = args[index].As<Float64Array>();
99   CHECK_EQ(arr->Length(), array_length);
100   return arr->Buffer();
101 }
102 
103 // CPUUsage use libuv's uv_getrusage() this-process resource usage accessor,
104 // to access ru_utime (user CPU time used) and ru_stime (system CPU time used),
105 // which are uv_timeval_t structs (long tv_sec, long tv_usec).
106 // Returns those values as Float64 microseconds in the elements of the array
107 // passed to the function.
CPUUsage(const FunctionCallbackInfo<Value> & args)108 static void CPUUsage(const FunctionCallbackInfo<Value>& args) {
109   Environment* env = Environment::GetCurrent(args);
110   uv_rusage_t rusage;
111 
112   // Call libuv to get the values we'll return.
113   int err = uv_getrusage(&rusage);
114   if (err)
115     return env->ThrowUVException(err, "uv_getrusage");
116 
117   // Get the double array pointer from the Float64Array argument.
118   Local<ArrayBuffer> ab = get_fields_array_buffer(args, 0, 2);
119   double* fields = static_cast<double*>(ab->Data());
120 
121   // Set the Float64Array elements to be user / system values in microseconds.
122   fields[0] = MICROS_PER_SEC * rusage.ru_utime.tv_sec + rusage.ru_utime.tv_usec;
123   fields[1] = MICROS_PER_SEC * rusage.ru_stime.tv_sec + rusage.ru_stime.tv_usec;
124 }
125 
Cwd(const FunctionCallbackInfo<Value> & args)126 static void Cwd(const FunctionCallbackInfo<Value>& args) {
127   Environment* env = Environment::GetCurrent(args);
128   CHECK(env->has_run_bootstrapping_code());
129   char buf[PATH_MAX_BYTES];
130   size_t cwd_len = sizeof(buf);
131   int err = uv_cwd(buf, &cwd_len);
132   if (err)
133     return env->ThrowUVException(err, "uv_cwd");
134 
135   Local<String> cwd = String::NewFromUtf8(env->isolate(),
136                                           buf,
137                                           NewStringType::kNormal,
138                                           cwd_len).ToLocalChecked();
139   args.GetReturnValue().Set(cwd);
140 }
141 
Kill(const FunctionCallbackInfo<Value> & args)142 static void Kill(const FunctionCallbackInfo<Value>& args) {
143   Environment* env = Environment::GetCurrent(args);
144   Local<Context> context = env->context();
145 
146   if (args.Length() < 2) {
147     THROW_ERR_MISSING_ARGS(env, "Bad argument.");
148   }
149 
150   int pid;
151   if (!args[0]->Int32Value(context).To(&pid)) return;
152   int sig;
153   if (!args[1]->Int32Value(context).To(&sig)) return;
154 
155   uv_pid_t own_pid = uv_os_getpid();
156   if (sig > 0 &&
157       (pid == 0 || pid == -1 || pid == own_pid || pid == -own_pid) &&
158       !HasSignalJSHandler(sig)) {
159     // This is most likely going to terminate this process.
160     // It's not an exact method but it might be close enough.
161     RunAtExit(env);
162   }
163 
164   int err = uv_kill(pid, sig);
165   args.GetReturnValue().Set(err);
166 }
167 
Rss(const FunctionCallbackInfo<Value> & args)168 static void Rss(const FunctionCallbackInfo<Value>& args) {
169   Environment* env = Environment::GetCurrent(args);
170 
171   size_t rss;
172   int err = uv_resident_set_memory(&rss);
173   if (err)
174     return env->ThrowUVException(err, "uv_resident_set_memory");
175 
176   args.GetReturnValue().Set(static_cast<double>(rss));
177 }
178 
MemoryUsage(const FunctionCallbackInfo<Value> & args)179 static void MemoryUsage(const FunctionCallbackInfo<Value>& args) {
180   Environment* env = Environment::GetCurrent(args);
181 
182   Isolate* isolate = env->isolate();
183   // V8 memory usage
184   HeapStatistics v8_heap_stats;
185   isolate->GetHeapStatistics(&v8_heap_stats);
186 
187   NodeArrayBufferAllocator* array_buffer_allocator =
188       env->isolate_data()->node_allocator();
189 
190   // Get the double array pointer from the Float64Array argument.
191   Local<ArrayBuffer> ab = get_fields_array_buffer(args, 0, 5);
192   double* fields = static_cast<double*>(ab->Data());
193 
194   size_t rss;
195   int err = uv_resident_set_memory(&rss);
196   if (err)
197     return env->ThrowUVException(err, "uv_resident_set_memory");
198 
199   fields[0] = static_cast<double>(rss);
200   fields[1] = static_cast<double>(v8_heap_stats.total_heap_size());
201   fields[2] = static_cast<double>(v8_heap_stats.used_heap_size());
202   fields[3] = static_cast<double>(v8_heap_stats.external_memory());
203   fields[4] =
204       array_buffer_allocator == nullptr
205           ? 0
206           : static_cast<double>(array_buffer_allocator->total_mem_usage());
207 }
208 
GetConstrainedMemory(const FunctionCallbackInfo<Value> & args)209 static void GetConstrainedMemory(const FunctionCallbackInfo<Value>& args) {
210   uint64_t value = uv_get_constrained_memory();
211   if (value != 0) {
212     args.GetReturnValue().Set(static_cast<double>(value));
213   }
214 }
215 
RawDebug(const FunctionCallbackInfo<Value> & args)216 void RawDebug(const FunctionCallbackInfo<Value>& args) {
217   CHECK(args.Length() == 1 && args[0]->IsString() &&
218         "must be called with a single string");
219   Utf8Value message(args.GetIsolate(), args[0]);
220   FPrintF(stderr, "%s\n", message);
221   fflush(stderr);
222 }
223 
Umask(const FunctionCallbackInfo<Value> & args)224 static void Umask(const FunctionCallbackInfo<Value>& args) {
225   Environment* env = Environment::GetCurrent(args);
226   CHECK(env->has_run_bootstrapping_code());
227   CHECK_EQ(args.Length(), 1);
228   CHECK(args[0]->IsUndefined() || args[0]->IsUint32());
229   Mutex::ScopedLock scoped_lock(per_process::umask_mutex);
230 
231   uint32_t old;
232   if (args[0]->IsUndefined()) {
233     old = umask(0);
234     umask(static_cast<mode_t>(old));
235   } else {
236     int oct = args[0].As<Uint32>()->Value();
237     old = umask(static_cast<mode_t>(oct));
238   }
239 
240   args.GetReturnValue().Set(old);
241 }
242 
Uptime(const FunctionCallbackInfo<Value> & args)243 static void Uptime(const FunctionCallbackInfo<Value>& args) {
244   Environment* env = Environment::GetCurrent(args);
245 
246   uv_update_time(env->event_loop());
247   double uptime =
248       static_cast<double>(uv_hrtime() - per_process::node_start_time);
249   Local<Number> result = Number::New(env->isolate(), uptime / NANOS_PER_SEC);
250   args.GetReturnValue().Set(result);
251 }
252 
GetActiveRequests(const FunctionCallbackInfo<Value> & args)253 static void GetActiveRequests(const FunctionCallbackInfo<Value>& args) {
254   Environment* env = Environment::GetCurrent(args);
255 
256   std::vector<Local<Value>> request_v;
257   for (ReqWrapBase* req_wrap : *env->req_wrap_queue()) {
258     AsyncWrap* w = req_wrap->GetAsyncWrap();
259     if (w->persistent().IsEmpty())
260       continue;
261     request_v.emplace_back(w->GetOwner());
262   }
263 
264   args.GetReturnValue().Set(
265       Array::New(env->isolate(), request_v.data(), request_v.size()));
266 }
267 
268 // Non-static, friend of HandleWrap. Could have been a HandleWrap method but
269 // implemented here for consistency with GetActiveRequests().
GetActiveHandles(const FunctionCallbackInfo<Value> & args)270 void GetActiveHandles(const FunctionCallbackInfo<Value>& args) {
271   Environment* env = Environment::GetCurrent(args);
272 
273   std::vector<Local<Value>> handle_v;
274   for (auto w : *env->handle_wrap_queue()) {
275     if (!HandleWrap::HasRef(w))
276       continue;
277     handle_v.emplace_back(w->GetOwner());
278   }
279   args.GetReturnValue().Set(
280       Array::New(env->isolate(), handle_v.data(), handle_v.size()));
281 }
282 
GetActiveResourcesInfo(const FunctionCallbackInfo<Value> & args)283 static void GetActiveResourcesInfo(const FunctionCallbackInfo<Value>& args) {
284   Environment* env = Environment::GetCurrent(args);
285   std::vector<Local<Value>> resources_info;
286 
287   // Active requests
288   for (ReqWrapBase* req_wrap : *env->req_wrap_queue()) {
289     AsyncWrap* w = req_wrap->GetAsyncWrap();
290     if (w->persistent().IsEmpty()) continue;
291     resources_info.emplace_back(
292         OneByteString(env->isolate(), w->MemoryInfoName()));
293   }
294 
295   // Active handles
296   for (HandleWrap* w : *env->handle_wrap_queue()) {
297     if (w->persistent().IsEmpty() || !HandleWrap::HasRef(w)) continue;
298     resources_info.emplace_back(
299         OneByteString(env->isolate(), w->MemoryInfoName()));
300   }
301 
302   // Active timeouts
303   resources_info.insert(resources_info.end(),
304                         env->timeout_info()[0],
305                         OneByteString(env->isolate(), "Timeout"));
306 
307   // Active immediates
308   resources_info.insert(resources_info.end(),
309                         env->immediate_info()->ref_count(),
310                         OneByteString(env->isolate(), "Immediate"));
311 
312   args.GetReturnValue().Set(
313       Array::New(env->isolate(), resources_info.data(), resources_info.size()));
314 }
315 
ResourceUsage(const FunctionCallbackInfo<Value> & args)316 static void ResourceUsage(const FunctionCallbackInfo<Value>& args) {
317   Environment* env = Environment::GetCurrent(args);
318 
319   uv_rusage_t rusage;
320   int err = uv_getrusage(&rusage);
321   if (err)
322     return env->ThrowUVException(err, "uv_getrusage");
323 
324   Local<ArrayBuffer> ab = get_fields_array_buffer(args, 0, 16);
325   double* fields = static_cast<double*>(ab->Data());
326 
327   fields[0] = MICROS_PER_SEC * rusage.ru_utime.tv_sec + rusage.ru_utime.tv_usec;
328   fields[1] = MICROS_PER_SEC * rusage.ru_stime.tv_sec + rusage.ru_stime.tv_usec;
329   fields[2] = static_cast<double>(rusage.ru_maxrss);
330   fields[3] = static_cast<double>(rusage.ru_ixrss);
331   fields[4] = static_cast<double>(rusage.ru_idrss);
332   fields[5] = static_cast<double>(rusage.ru_isrss);
333   fields[6] = static_cast<double>(rusage.ru_minflt);
334   fields[7] = static_cast<double>(rusage.ru_majflt);
335   fields[8] = static_cast<double>(rusage.ru_nswap);
336   fields[9] = static_cast<double>(rusage.ru_inblock);
337   fields[10] = static_cast<double>(rusage.ru_oublock);
338   fields[11] = static_cast<double>(rusage.ru_msgsnd);
339   fields[12] = static_cast<double>(rusage.ru_msgrcv);
340   fields[13] = static_cast<double>(rusage.ru_nsignals);
341   fields[14] = static_cast<double>(rusage.ru_nvcsw);
342   fields[15] = static_cast<double>(rusage.ru_nivcsw);
343 }
344 
345 #ifdef __POSIX__
DebugProcess(const FunctionCallbackInfo<Value> & args)346 static void DebugProcess(const FunctionCallbackInfo<Value>& args) {
347   Environment* env = Environment::GetCurrent(args);
348 
349   if (args.Length() < 1) {
350     return THROW_ERR_MISSING_ARGS(env, "Invalid number of arguments.");
351   }
352 
353   CHECK(args[0]->IsNumber());
354   pid_t pid = args[0].As<Integer>()->Value();
355   int r = kill(pid, SIGUSR1);
356 
357   if (r != 0) {
358     return env->ThrowErrnoException(errno, "kill");
359   }
360 }
361 #endif  // __POSIX__
362 
363 #ifdef _WIN32
GetDebugSignalHandlerMappingName(DWORD pid,wchar_t * buf,size_t buf_len)364 static int GetDebugSignalHandlerMappingName(DWORD pid,
365                                             wchar_t* buf,
366                                             size_t buf_len) {
367   return _snwprintf(buf, buf_len, L"node-debug-handler-%u", pid);
368 }
369 
DebugProcess(const FunctionCallbackInfo<Value> & args)370 static void DebugProcess(const FunctionCallbackInfo<Value>& args) {
371   Environment* env = Environment::GetCurrent(args);
372   Isolate* isolate = args.GetIsolate();
373 
374   if (args.Length() < 1) {
375     return THROW_ERR_MISSING_ARGS(env, "Invalid number of arguments.");
376   }
377 
378   HANDLE process = nullptr;
379   HANDLE thread = nullptr;
380   HANDLE mapping = nullptr;
381   wchar_t mapping_name[32];
382   LPTHREAD_START_ROUTINE* handler = nullptr;
383   DWORD pid = 0;
384 
385   auto cleanup = OnScopeLeave([&]() {
386     if (process != nullptr) CloseHandle(process);
387     if (thread != nullptr) CloseHandle(thread);
388     if (handler != nullptr) UnmapViewOfFile(handler);
389     if (mapping != nullptr) CloseHandle(mapping);
390   });
391 
392   CHECK(args[0]->IsNumber());
393   pid = static_cast<DWORD>(args[0].As<Integer>()->Value());
394 
395   process =
396       OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION |
397                       PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ,
398                   FALSE,
399                   pid);
400   if (process == nullptr) {
401     isolate->ThrowException(
402         WinapiErrnoException(isolate, GetLastError(), "OpenProcess"));
403     return;
404   }
405 
406   if (GetDebugSignalHandlerMappingName(
407           pid, mapping_name, arraysize(mapping_name)) < 0) {
408     env->ThrowErrnoException(errno, "sprintf");
409     return;
410   }
411 
412   mapping = OpenFileMappingW(FILE_MAP_READ, FALSE, mapping_name);
413   if (mapping == nullptr) {
414     isolate->ThrowException(
415         WinapiErrnoException(isolate, GetLastError(), "OpenFileMappingW"));
416     return;
417   }
418 
419   handler = reinterpret_cast<LPTHREAD_START_ROUTINE*>(
420       MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, sizeof *handler));
421   if (handler == nullptr || *handler == nullptr) {
422     isolate->ThrowException(
423         WinapiErrnoException(isolate, GetLastError(), "MapViewOfFile"));
424     return;
425   }
426 
427   thread =
428       CreateRemoteThread(process, nullptr, 0, *handler, nullptr, 0, nullptr);
429   if (thread == nullptr) {
430     isolate->ThrowException(
431         WinapiErrnoException(isolate, GetLastError(), "CreateRemoteThread"));
432     return;
433   }
434 
435   // Wait for the thread to terminate
436   if (WaitForSingleObject(thread, INFINITE) != WAIT_OBJECT_0) {
437     isolate->ThrowException(
438         WinapiErrnoException(isolate, GetLastError(), "WaitForSingleObject"));
439     return;
440   }
441 }
442 #endif  // _WIN32
443 
DebugEnd(const FunctionCallbackInfo<Value> & args)444 static void DebugEnd(const FunctionCallbackInfo<Value>& args) {
445 #if HAVE_INSPECTOR
446   Environment* env = Environment::GetCurrent(args);
447   if (env->inspector_agent()->IsListening()) {
448     env->inspector_agent()->Stop();
449   }
450 #endif
451 }
452 
ReallyExit(const FunctionCallbackInfo<Value> & args)453 static void ReallyExit(const FunctionCallbackInfo<Value>& args) {
454   Environment* env = Environment::GetCurrent(args);
455   RunAtExit(env);
456   int code = args[0]->Int32Value(env->context()).FromMaybe(0);
457   env->Exit(code);
458 }
459 
460 namespace process {
461 
BindingData(Realm * realm,v8::Local<v8::Object> object)462 BindingData::BindingData(Realm* realm, v8::Local<v8::Object> object)
463     : SnapshotableObject(realm, object, type_int) {
464   Isolate* isolate = realm->isolate();
465   Local<Context> context = realm->context();
466   Local<ArrayBuffer> ab = ArrayBuffer::New(isolate, kBufferSize);
467   array_buffer_.Reset(isolate, ab);
468   object->Set(context, FIXED_ONE_BYTE_STRING(isolate, "hrtimeBuffer"), ab)
469       .ToChecked();
470   backing_store_ = ab->GetBackingStore();
471 }
472 
473 v8::CFunction BindingData::fast_number_(v8::CFunction::Make(FastNumber));
474 v8::CFunction BindingData::fast_bigint_(v8::CFunction::Make(FastBigInt));
475 
AddMethods()476 void BindingData::AddMethods() {
477   Local<Context> ctx = env()->context();
478   SetFastMethodNoSideEffect(ctx, object(), "hrtime", SlowNumber, &fast_number_);
479   SetFastMethodNoSideEffect(
480       ctx, object(), "hrtimeBigInt", SlowBigInt, &fast_bigint_);
481 }
482 
RegisterExternalReferences(ExternalReferenceRegistry * registry)483 void BindingData::RegisterExternalReferences(
484     ExternalReferenceRegistry* registry) {
485   registry->Register(SlowNumber);
486   registry->Register(SlowBigInt);
487   registry->Register(FastNumber);
488   registry->Register(FastBigInt);
489   registry->Register(fast_number_.GetTypeInfo());
490   registry->Register(fast_bigint_.GetTypeInfo());
491 }
492 
FromV8Value(Local<Value> value)493 BindingData* BindingData::FromV8Value(Local<Value> value) {
494   Local<Object> v8_object = value.As<Object>();
495   return static_cast<BindingData*>(
496       v8_object->GetAlignedPointerFromInternalField(BaseObject::kSlot));
497 }
498 
MemoryInfo(MemoryTracker * tracker) const499 void BindingData::MemoryInfo(MemoryTracker* tracker) const {
500   tracker->TrackField("array_buffer", array_buffer_);
501 }
502 
503 // This is the legacy version of hrtime before BigInt was introduced in
504 // JavaScript.
505 // The value returned by uv_hrtime() is a 64-bit int representing nanoseconds,
506 // so this function instead fills in an Uint32Array with 3 entries,
507 // to avoid any integer overflow possibility.
508 // The first two entries contain the second part of the value
509 // broken into the upper/lower 32 bits to be converted back in JS,
510 // because there is no Uint64Array in JS.
511 // The third entry contains the remaining nanosecond part of the value.
NumberImpl(BindingData * receiver)512 void BindingData::NumberImpl(BindingData* receiver) {
513   // Make sure we don't accidentally access buffers wiped for snapshot.
514   CHECK(!receiver->array_buffer_.IsEmpty());
515   uint64_t t = uv_hrtime();
516   uint32_t* fields = static_cast<uint32_t*>(receiver->backing_store_->Data());
517   fields[0] = (t / NANOS_PER_SEC) >> 32;
518   fields[1] = (t / NANOS_PER_SEC) & 0xffffffff;
519   fields[2] = t % NANOS_PER_SEC;
520 }
521 
BigIntImpl(BindingData * receiver)522 void BindingData::BigIntImpl(BindingData* receiver) {
523   // Make sure we don't accidentally access buffers wiped for snapshot.
524   CHECK(!receiver->array_buffer_.IsEmpty());
525   uint64_t t = uv_hrtime();
526   uint64_t* fields = static_cast<uint64_t*>(receiver->backing_store_->Data());
527   fields[0] = t;
528 }
529 
SlowBigInt(const FunctionCallbackInfo<Value> & args)530 void BindingData::SlowBigInt(const FunctionCallbackInfo<Value>& args) {
531   BigIntImpl(FromJSObject<BindingData>(args.Holder()));
532 }
533 
SlowNumber(const v8::FunctionCallbackInfo<v8::Value> & args)534 void BindingData::SlowNumber(const v8::FunctionCallbackInfo<v8::Value>& args) {
535   NumberImpl(FromJSObject<BindingData>(args.Holder()));
536 }
537 
PrepareForSerialization(Local<Context> context,v8::SnapshotCreator * creator)538 bool BindingData::PrepareForSerialization(Local<Context> context,
539                                           v8::SnapshotCreator* creator) {
540   // It's not worth keeping.
541   // Release it, we will recreate it when the instance is dehydrated.
542   array_buffer_.Reset();
543   // Return true because we need to maintain the reference to the binding from
544   // JS land.
545   return true;
546 }
547 
Serialize(int index)548 InternalFieldInfoBase* BindingData::Serialize(int index) {
549   DCHECK_EQ(index, BaseObject::kEmbedderType);
550   InternalFieldInfo* info =
551       InternalFieldInfoBase::New<InternalFieldInfo>(type());
552   return info;
553 }
554 
Deserialize(Local<Context> context,Local<Object> holder,int index,InternalFieldInfoBase * info)555 void BindingData::Deserialize(Local<Context> context,
556                               Local<Object> holder,
557                               int index,
558                               InternalFieldInfoBase* info) {
559   DCHECK_EQ(index, BaseObject::kEmbedderType);
560   v8::HandleScope scope(context->GetIsolate());
561   Realm* realm = Realm::GetCurrent(context);
562   // Recreate the buffer in the constructor.
563   BindingData* binding = realm->AddBindingData<BindingData>(context, holder);
564   CHECK_NOT_NULL(binding);
565 }
566 
Initialize(Local<Object> target,Local<Value> unused,Local<Context> context,void * priv)567 static void Initialize(Local<Object> target,
568                        Local<Value> unused,
569                        Local<Context> context,
570                        void* priv) {
571   Realm* realm = Realm::GetCurrent(context);
572   Environment* env = realm->env();
573   BindingData* const binding_data =
574       realm->AddBindingData<BindingData>(context, target);
575   if (binding_data == nullptr) return;
576   binding_data->AddMethods();
577 
578   // define various internal methods
579   if (env->owns_process_state()) {
580     SetMethod(context, target, "_debugProcess", DebugProcess);
581     SetMethod(context, target, "abort", Abort);
582     SetMethod(context, target, "causeSegfault", CauseSegfault);
583     SetMethod(context, target, "chdir", Chdir);
584   }
585 
586   SetMethod(context, target, "umask", Umask);
587   SetMethod(context, target, "memoryUsage", MemoryUsage);
588   SetMethod(context, target, "constrainedMemory", GetConstrainedMemory);
589   SetMethod(context, target, "rss", Rss);
590   SetMethod(context, target, "cpuUsage", CPUUsage);
591   SetMethod(context, target, "resourceUsage", ResourceUsage);
592 
593   SetMethod(context, target, "_debugEnd", DebugEnd);
594   SetMethod(context, target, "_getActiveRequests", GetActiveRequests);
595   SetMethod(context, target, "_getActiveHandles", GetActiveHandles);
596   SetMethod(context, target, "getActiveResourcesInfo", GetActiveResourcesInfo);
597   SetMethod(context, target, "_kill", Kill);
598   SetMethod(context, target, "_rawDebug", RawDebug);
599 
600   SetMethodNoSideEffect(context, target, "cwd", Cwd);
601   SetMethod(context, target, "dlopen", binding::DLOpen);
602   SetMethod(context, target, "reallyExit", ReallyExit);
603   SetMethodNoSideEffect(context, target, "uptime", Uptime);
604   SetMethod(context, target, "patchProcessObject", PatchProcessObject);
605 }
606 
RegisterExternalReferences(ExternalReferenceRegistry * registry)607 void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
608   BindingData::RegisterExternalReferences(registry);
609 
610   registry->Register(DebugProcess);
611   registry->Register(DebugEnd);
612   registry->Register(Abort);
613   registry->Register(CauseSegfault);
614   registry->Register(Chdir);
615 
616   registry->Register(Umask);
617   registry->Register(RawDebug);
618   registry->Register(MemoryUsage);
619   registry->Register(GetConstrainedMemory);
620   registry->Register(Rss);
621   registry->Register(CPUUsage);
622   registry->Register(ResourceUsage);
623 
624   registry->Register(GetActiveRequests);
625   registry->Register(GetActiveHandles);
626   registry->Register(GetActiveResourcesInfo);
627   registry->Register(Kill);
628 
629   registry->Register(Cwd);
630   registry->Register(binding::DLOpen);
631   registry->Register(ReallyExit);
632   registry->Register(Uptime);
633   registry->Register(PatchProcessObject);
634 }
635 
636 }  // namespace process
637 }  // namespace node
638 
639 NODE_BINDING_CONTEXT_AWARE_INTERNAL(process_methods, node::process::Initialize)
640 NODE_BINDING_EXTERNAL_REFERENCE(process_methods,
641                                 node::process::RegisterExternalReferences)
642