revise installing a license file
[platform/upstream/nodejs.git] / src / node.cc
1 #include "node.h"
2 #include "node_buffer.h"
3 #include "node_constants.h"
4 #include "node_file.h"
5 #include "node_http_parser.h"
6 #include "node_javascript.h"
7 #include "node_version.h"
8 #include "node_internals.h"
9 #include "node_revert.h"
10
11 #if defined HAVE_PERFCTR
12 #include "node_counters.h"
13 #endif
14
15 #if HAVE_OPENSSL
16 #include "node_crypto.h"
17 #endif
18
19 #if defined(NODE_HAVE_I18N_SUPPORT)
20 #include "node_i18n.h"
21 #endif
22
23 #if defined HAVE_DTRACE || defined HAVE_ETW
24 #include "node_dtrace.h"
25 #endif
26
27 #if defined HAVE_LTTNG
28 #include "node_lttng.h"
29 #endif
30
31 #include "ares.h"
32 #include "async-wrap.h"
33 #include "async-wrap-inl.h"
34 #include "env.h"
35 #include "env-inl.h"
36 #include "handle_wrap.h"
37 #include "req-wrap.h"
38 #include "req-wrap-inl.h"
39 #include "string_bytes.h"
40 #include "util.h"
41 #include "uv.h"
42 #include "libplatform/libplatform.h"
43 #include "v8-debug.h"
44 #include "v8-profiler.h"
45 #include "zlib.h"
46
47 #include <errno.h>
48 #include <limits.h>  // PATH_MAX
49 #include <locale.h>
50 #include <signal.h>
51 #include <stdio.h>
52 #include <stdlib.h>
53 #include <string.h>
54 #include <sys/types.h>
55 #include <vector>
56
57 #if defined(NODE_HAVE_I18N_SUPPORT)
58 #include <unicode/uvernum.h>
59 #endif
60
61 #if defined(LEAK_SANITIZER)
62 #include <sanitizer/lsan_interface.h>
63 #endif
64
65 #if defined(_MSC_VER)
66 #include <direct.h>
67 #include <io.h>
68 #define strcasecmp _stricmp
69 #define getpid GetCurrentProcessId
70 #define umask _umask
71 typedef int mode_t;
72 #else
73 #include <sys/resource.h>  // getrlimit, setrlimit
74 #include <unistd.h>  // setuid, getuid
75 #endif
76
77 #if defined(__POSIX__) && !defined(__ANDROID__)
78 #include <pwd.h>  // getpwnam()
79 #include <grp.h>  // getgrnam()
80 #endif
81
82 #ifdef __APPLE__
83 #include <crt_externs.h>
84 #define environ (*_NSGetEnviron())
85 #elif !defined(_MSC_VER)
86 extern char **environ;
87 #endif
88
89 #ifdef __APPLE__
90 #include "atomic-polyfill.h"  // NOLINT(build/include_order)
91 namespace node { template <typename T> using atomic = nonstd::atomic<T>; }
92 #else
93 #include <atomic>
94 namespace node { template <typename T> using atomic = std::atomic<T>; }
95 #endif
96
97 namespace node {
98
99 using v8::Array;
100 using v8::ArrayBuffer;
101 using v8::Boolean;
102 using v8::Context;
103 using v8::EscapableHandleScope;
104 using v8::Exception;
105 using v8::Function;
106 using v8::FunctionCallbackInfo;
107 using v8::FunctionTemplate;
108 using v8::HandleScope;
109 using v8::HeapStatistics;
110 using v8::Integer;
111 using v8::Isolate;
112 using v8::Local;
113 using v8::Locker;
114 using v8::Message;
115 using v8::Number;
116 using v8::Object;
117 using v8::ObjectTemplate;
118 using v8::Promise;
119 using v8::PromiseRejectMessage;
120 using v8::PropertyCallbackInfo;
121 using v8::SealHandleScope;
122 using v8::StackFrame;
123 using v8::StackTrace;
124 using v8::String;
125 using v8::TryCatch;
126 using v8::Uint32;
127 using v8::Uint32Array;
128 using v8::V8;
129 using v8::Value;
130
131 static bool print_eval = false;
132 static bool force_repl = false;
133 static bool syntax_check_only = false;
134 static bool trace_deprecation = false;
135 static bool throw_deprecation = false;
136 static bool trace_sync_io = false;
137 static bool track_heap_objects = false;
138 static const char* eval_string = nullptr;
139 static unsigned int preload_module_count = 0;
140 static const char** preload_modules = nullptr;
141 static bool use_debug_agent = false;
142 static bool debug_wait_connect = false;
143 static int debug_port = 5858;
144 static bool prof_process = false;
145 static bool v8_is_profiling = false;
146 static bool node_is_initialized = false;
147 static node_module* modpending;
148 static node_module* modlist_builtin;
149 static node_module* modlist_linked;
150 static node_module* modlist_addon;
151
152 #if defined(NODE_HAVE_I18N_SUPPORT)
153 // Path to ICU data (for i18n / Intl)
154 static const char* icu_data_dir = nullptr;
155 #endif
156
157 // used by C++ modules as well
158 bool no_deprecation = false;
159
160 // process-relative uptime base, initialized at start-up
161 static double prog_start_time;
162 static bool debugger_running;
163 static uv_async_t dispatch_debug_messages_async;
164
165 static node::atomic<Isolate*> node_isolate;
166 static v8::Platform* default_platform;
167
168
169 static void PrintErrorString(const char* format, ...) {
170   va_list ap;
171   va_start(ap, format);
172 #ifdef _WIN32
173   HANDLE stderr_handle = GetStdHandle(STD_ERROR_HANDLE);
174
175   // Check if stderr is something other than a tty/console
176   if (stderr_handle == INVALID_HANDLE_VALUE ||
177       stderr_handle == nullptr ||
178       uv_guess_handle(_fileno(stderr)) != UV_TTY) {
179     vfprintf(stderr, format, ap);
180     va_end(ap);
181     return;
182   }
183
184   // Fill in any placeholders
185   int n = _vscprintf(format, ap);
186   std::vector<char> out(n + 1);
187   vsprintf(out.data(), format, ap);
188
189   // Get required wide buffer size
190   n = MultiByteToWideChar(CP_UTF8, 0, out.data(), -1, nullptr, 0);
191
192   std::vector<wchar_t> wbuf(n);
193   MultiByteToWideChar(CP_UTF8, 0, out.data(), -1, wbuf.data(), n);
194   WriteConsoleW(stderr_handle, wbuf.data(), n, nullptr, nullptr);
195 #else
196   vfprintf(stderr, format, ap);
197 #endif
198   va_end(ap);
199 }
200
201
202 static void CheckImmediate(uv_check_t* handle) {
203   Environment* env = Environment::from_immediate_check_handle(handle);
204   HandleScope scope(env->isolate());
205   Context::Scope context_scope(env->context());
206   MakeCallback(env, env->process_object(), env->immediate_callback_string());
207 }
208
209
210 static void IdleImmediateDummy(uv_idle_t* handle) {
211   // Do nothing. Only for maintaining event loop.
212   // TODO(bnoordhuis) Maybe make libuv accept nullptr idle callbacks.
213 }
214
215
216 static inline const char *errno_string(int errorno) {
217 #define ERRNO_CASE(e)  case e: return #e;
218   switch (errorno) {
219 #ifdef EACCES
220   ERRNO_CASE(EACCES);
221 #endif
222
223 #ifdef EADDRINUSE
224   ERRNO_CASE(EADDRINUSE);
225 #endif
226
227 #ifdef EADDRNOTAVAIL
228   ERRNO_CASE(EADDRNOTAVAIL);
229 #endif
230
231 #ifdef EAFNOSUPPORT
232   ERRNO_CASE(EAFNOSUPPORT);
233 #endif
234
235 #ifdef EAGAIN
236   ERRNO_CASE(EAGAIN);
237 #endif
238
239 #ifdef EWOULDBLOCK
240 # if EAGAIN != EWOULDBLOCK
241   ERRNO_CASE(EWOULDBLOCK);
242 # endif
243 #endif
244
245 #ifdef EALREADY
246   ERRNO_CASE(EALREADY);
247 #endif
248
249 #ifdef EBADF
250   ERRNO_CASE(EBADF);
251 #endif
252
253 #ifdef EBADMSG
254   ERRNO_CASE(EBADMSG);
255 #endif
256
257 #ifdef EBUSY
258   ERRNO_CASE(EBUSY);
259 #endif
260
261 #ifdef ECANCELED
262   ERRNO_CASE(ECANCELED);
263 #endif
264
265 #ifdef ECHILD
266   ERRNO_CASE(ECHILD);
267 #endif
268
269 #ifdef ECONNABORTED
270   ERRNO_CASE(ECONNABORTED);
271 #endif
272
273 #ifdef ECONNREFUSED
274   ERRNO_CASE(ECONNREFUSED);
275 #endif
276
277 #ifdef ECONNRESET
278   ERRNO_CASE(ECONNRESET);
279 #endif
280
281 #ifdef EDEADLK
282   ERRNO_CASE(EDEADLK);
283 #endif
284
285 #ifdef EDESTADDRREQ
286   ERRNO_CASE(EDESTADDRREQ);
287 #endif
288
289 #ifdef EDOM
290   ERRNO_CASE(EDOM);
291 #endif
292
293 #ifdef EDQUOT
294   ERRNO_CASE(EDQUOT);
295 #endif
296
297 #ifdef EEXIST
298   ERRNO_CASE(EEXIST);
299 #endif
300
301 #ifdef EFAULT
302   ERRNO_CASE(EFAULT);
303 #endif
304
305 #ifdef EFBIG
306   ERRNO_CASE(EFBIG);
307 #endif
308
309 #ifdef EHOSTUNREACH
310   ERRNO_CASE(EHOSTUNREACH);
311 #endif
312
313 #ifdef EIDRM
314   ERRNO_CASE(EIDRM);
315 #endif
316
317 #ifdef EILSEQ
318   ERRNO_CASE(EILSEQ);
319 #endif
320
321 #ifdef EINPROGRESS
322   ERRNO_CASE(EINPROGRESS);
323 #endif
324
325 #ifdef EINTR
326   ERRNO_CASE(EINTR);
327 #endif
328
329 #ifdef EINVAL
330   ERRNO_CASE(EINVAL);
331 #endif
332
333 #ifdef EIO
334   ERRNO_CASE(EIO);
335 #endif
336
337 #ifdef EISCONN
338   ERRNO_CASE(EISCONN);
339 #endif
340
341 #ifdef EISDIR
342   ERRNO_CASE(EISDIR);
343 #endif
344
345 #ifdef ELOOP
346   ERRNO_CASE(ELOOP);
347 #endif
348
349 #ifdef EMFILE
350   ERRNO_CASE(EMFILE);
351 #endif
352
353 #ifdef EMLINK
354   ERRNO_CASE(EMLINK);
355 #endif
356
357 #ifdef EMSGSIZE
358   ERRNO_CASE(EMSGSIZE);
359 #endif
360
361 #ifdef EMULTIHOP
362   ERRNO_CASE(EMULTIHOP);
363 #endif
364
365 #ifdef ENAMETOOLONG
366   ERRNO_CASE(ENAMETOOLONG);
367 #endif
368
369 #ifdef ENETDOWN
370   ERRNO_CASE(ENETDOWN);
371 #endif
372
373 #ifdef ENETRESET
374   ERRNO_CASE(ENETRESET);
375 #endif
376
377 #ifdef ENETUNREACH
378   ERRNO_CASE(ENETUNREACH);
379 #endif
380
381 #ifdef ENFILE
382   ERRNO_CASE(ENFILE);
383 #endif
384
385 #ifdef ENOBUFS
386   ERRNO_CASE(ENOBUFS);
387 #endif
388
389 #ifdef ENODATA
390   ERRNO_CASE(ENODATA);
391 #endif
392
393 #ifdef ENODEV
394   ERRNO_CASE(ENODEV);
395 #endif
396
397 #ifdef ENOENT
398   ERRNO_CASE(ENOENT);
399 #endif
400
401 #ifdef ENOEXEC
402   ERRNO_CASE(ENOEXEC);
403 #endif
404
405 #ifdef ENOLINK
406   ERRNO_CASE(ENOLINK);
407 #endif
408
409 #ifdef ENOLCK
410 # if ENOLINK != ENOLCK
411   ERRNO_CASE(ENOLCK);
412 # endif
413 #endif
414
415 #ifdef ENOMEM
416   ERRNO_CASE(ENOMEM);
417 #endif
418
419 #ifdef ENOMSG
420   ERRNO_CASE(ENOMSG);
421 #endif
422
423 #ifdef ENOPROTOOPT
424   ERRNO_CASE(ENOPROTOOPT);
425 #endif
426
427 #ifdef ENOSPC
428   ERRNO_CASE(ENOSPC);
429 #endif
430
431 #ifdef ENOSR
432   ERRNO_CASE(ENOSR);
433 #endif
434
435 #ifdef ENOSTR
436   ERRNO_CASE(ENOSTR);
437 #endif
438
439 #ifdef ENOSYS
440   ERRNO_CASE(ENOSYS);
441 #endif
442
443 #ifdef ENOTCONN
444   ERRNO_CASE(ENOTCONN);
445 #endif
446
447 #ifdef ENOTDIR
448   ERRNO_CASE(ENOTDIR);
449 #endif
450
451 #ifdef ENOTEMPTY
452 # if ENOTEMPTY != EEXIST
453   ERRNO_CASE(ENOTEMPTY);
454 # endif
455 #endif
456
457 #ifdef ENOTSOCK
458   ERRNO_CASE(ENOTSOCK);
459 #endif
460
461 #ifdef ENOTSUP
462   ERRNO_CASE(ENOTSUP);
463 #else
464 # ifdef EOPNOTSUPP
465   ERRNO_CASE(EOPNOTSUPP);
466 # endif
467 #endif
468
469 #ifdef ENOTTY
470   ERRNO_CASE(ENOTTY);
471 #endif
472
473 #ifdef ENXIO
474   ERRNO_CASE(ENXIO);
475 #endif
476
477
478 #ifdef EOVERFLOW
479   ERRNO_CASE(EOVERFLOW);
480 #endif
481
482 #ifdef EPERM
483   ERRNO_CASE(EPERM);
484 #endif
485
486 #ifdef EPIPE
487   ERRNO_CASE(EPIPE);
488 #endif
489
490 #ifdef EPROTO
491   ERRNO_CASE(EPROTO);
492 #endif
493
494 #ifdef EPROTONOSUPPORT
495   ERRNO_CASE(EPROTONOSUPPORT);
496 #endif
497
498 #ifdef EPROTOTYPE
499   ERRNO_CASE(EPROTOTYPE);
500 #endif
501
502 #ifdef ERANGE
503   ERRNO_CASE(ERANGE);
504 #endif
505
506 #ifdef EROFS
507   ERRNO_CASE(EROFS);
508 #endif
509
510 #ifdef ESPIPE
511   ERRNO_CASE(ESPIPE);
512 #endif
513
514 #ifdef ESRCH
515   ERRNO_CASE(ESRCH);
516 #endif
517
518 #ifdef ESTALE
519   ERRNO_CASE(ESTALE);
520 #endif
521
522 #ifdef ETIME
523   ERRNO_CASE(ETIME);
524 #endif
525
526 #ifdef ETIMEDOUT
527   ERRNO_CASE(ETIMEDOUT);
528 #endif
529
530 #ifdef ETXTBSY
531   ERRNO_CASE(ETXTBSY);
532 #endif
533
534 #ifdef EXDEV
535   ERRNO_CASE(EXDEV);
536 #endif
537
538   default: return "";
539   }
540 }
541
542 const char *signo_string(int signo) {
543 #define SIGNO_CASE(e)  case e: return #e;
544   switch (signo) {
545 #ifdef SIGHUP
546   SIGNO_CASE(SIGHUP);
547 #endif
548
549 #ifdef SIGINT
550   SIGNO_CASE(SIGINT);
551 #endif
552
553 #ifdef SIGQUIT
554   SIGNO_CASE(SIGQUIT);
555 #endif
556
557 #ifdef SIGILL
558   SIGNO_CASE(SIGILL);
559 #endif
560
561 #ifdef SIGTRAP
562   SIGNO_CASE(SIGTRAP);
563 #endif
564
565 #ifdef SIGABRT
566   SIGNO_CASE(SIGABRT);
567 #endif
568
569 #ifdef SIGIOT
570 # if SIGABRT != SIGIOT
571   SIGNO_CASE(SIGIOT);
572 # endif
573 #endif
574
575 #ifdef SIGBUS
576   SIGNO_CASE(SIGBUS);
577 #endif
578
579 #ifdef SIGFPE
580   SIGNO_CASE(SIGFPE);
581 #endif
582
583 #ifdef SIGKILL
584   SIGNO_CASE(SIGKILL);
585 #endif
586
587 #ifdef SIGUSR1
588   SIGNO_CASE(SIGUSR1);
589 #endif
590
591 #ifdef SIGSEGV
592   SIGNO_CASE(SIGSEGV);
593 #endif
594
595 #ifdef SIGUSR2
596   SIGNO_CASE(SIGUSR2);
597 #endif
598
599 #ifdef SIGPIPE
600   SIGNO_CASE(SIGPIPE);
601 #endif
602
603 #ifdef SIGALRM
604   SIGNO_CASE(SIGALRM);
605 #endif
606
607   SIGNO_CASE(SIGTERM);
608
609 #ifdef SIGCHLD
610   SIGNO_CASE(SIGCHLD);
611 #endif
612
613 #ifdef SIGSTKFLT
614   SIGNO_CASE(SIGSTKFLT);
615 #endif
616
617
618 #ifdef SIGCONT
619   SIGNO_CASE(SIGCONT);
620 #endif
621
622 #ifdef SIGSTOP
623   SIGNO_CASE(SIGSTOP);
624 #endif
625
626 #ifdef SIGTSTP
627   SIGNO_CASE(SIGTSTP);
628 #endif
629
630 #ifdef SIGBREAK
631   SIGNO_CASE(SIGBREAK);
632 #endif
633
634 #ifdef SIGTTIN
635   SIGNO_CASE(SIGTTIN);
636 #endif
637
638 #ifdef SIGTTOU
639   SIGNO_CASE(SIGTTOU);
640 #endif
641
642 #ifdef SIGURG
643   SIGNO_CASE(SIGURG);
644 #endif
645
646 #ifdef SIGXCPU
647   SIGNO_CASE(SIGXCPU);
648 #endif
649
650 #ifdef SIGXFSZ
651   SIGNO_CASE(SIGXFSZ);
652 #endif
653
654 #ifdef SIGVTALRM
655   SIGNO_CASE(SIGVTALRM);
656 #endif
657
658 #ifdef SIGPROF
659   SIGNO_CASE(SIGPROF);
660 #endif
661
662 #ifdef SIGWINCH
663   SIGNO_CASE(SIGWINCH);
664 #endif
665
666 #ifdef SIGIO
667   SIGNO_CASE(SIGIO);
668 #endif
669
670 #ifdef SIGPOLL
671 # if SIGPOLL != SIGIO
672   SIGNO_CASE(SIGPOLL);
673 # endif
674 #endif
675
676 #ifdef SIGLOST
677 # if SIGLOST != SIGABRT
678   SIGNO_CASE(SIGLOST);
679 # endif
680 #endif
681
682 #ifdef SIGPWR
683 # if SIGPWR != SIGLOST
684   SIGNO_CASE(SIGPWR);
685 # endif
686 #endif
687
688 #ifdef SIGSYS
689   SIGNO_CASE(SIGSYS);
690 #endif
691
692   default: return "";
693   }
694 }
695
696
697 // Convenience methods
698
699
700 void ThrowError(v8::Isolate* isolate, const char* errmsg) {
701   Environment::GetCurrent(isolate)->ThrowError(errmsg);
702 }
703
704
705 void ThrowTypeError(v8::Isolate* isolate, const char* errmsg) {
706   Environment::GetCurrent(isolate)->ThrowTypeError(errmsg);
707 }
708
709
710 void ThrowRangeError(v8::Isolate* isolate, const char* errmsg) {
711   Environment::GetCurrent(isolate)->ThrowRangeError(errmsg);
712 }
713
714
715 void ThrowErrnoException(v8::Isolate* isolate,
716                          int errorno,
717                          const char* syscall,
718                          const char* message,
719                          const char* path) {
720   Environment::GetCurrent(isolate)->ThrowErrnoException(errorno,
721                                                         syscall,
722                                                         message,
723                                                         path);
724 }
725
726
727 void ThrowUVException(v8::Isolate* isolate,
728                       int errorno,
729                       const char* syscall,
730                       const char* message,
731                       const char* path,
732                       const char* dest) {
733   Environment::GetCurrent(isolate)
734       ->ThrowUVException(errorno, syscall, message, path, dest);
735 }
736
737
738 Local<Value> ErrnoException(Isolate* isolate,
739                             int errorno,
740                             const char *syscall,
741                             const char *msg,
742                             const char *path) {
743   Environment* env = Environment::GetCurrent(isolate);
744
745   Local<Value> e;
746   Local<String> estring = OneByteString(env->isolate(), errno_string(errorno));
747   if (msg == nullptr || msg[0] == '\0') {
748     msg = strerror(errorno);
749   }
750   Local<String> message = OneByteString(env->isolate(), msg);
751
752   Local<String> cons =
753       String::Concat(estring, FIXED_ONE_BYTE_STRING(env->isolate(), ", "));
754   cons = String::Concat(cons, message);
755
756   Local<String> path_string;
757   if (path != nullptr) {
758     // FIXME(bnoordhuis) It's questionable to interpret the file path as UTF-8.
759     path_string = String::NewFromUtf8(env->isolate(), path);
760   }
761
762   if (path_string.IsEmpty() == false) {
763     cons = String::Concat(cons, FIXED_ONE_BYTE_STRING(env->isolate(), " '"));
764     cons = String::Concat(cons, path_string);
765     cons = String::Concat(cons, FIXED_ONE_BYTE_STRING(env->isolate(), "'"));
766   }
767   e = Exception::Error(cons);
768
769   Local<Object> obj = e->ToObject(env->isolate());
770   obj->Set(env->errno_string(), Integer::New(env->isolate(), errorno));
771   obj->Set(env->code_string(), estring);
772
773   if (path_string.IsEmpty() == false) {
774     obj->Set(env->path_string(), path_string);
775   }
776
777   if (syscall != nullptr) {
778     obj->Set(env->syscall_string(), OneByteString(env->isolate(), syscall));
779   }
780
781   return e;
782 }
783
784
785 static Local<String> StringFromPath(Isolate* isolate, const char* path) {
786 #ifdef _WIN32
787   if (strncmp(path, "\\\\?\\UNC\\", 8) == 0) {
788     return String::Concat(FIXED_ONE_BYTE_STRING(isolate, "\\\\"),
789                           String::NewFromUtf8(isolate, path + 8));
790   } else if (strncmp(path, "\\\\?\\", 4) == 0) {
791     return String::NewFromUtf8(isolate, path + 4);
792   }
793 #endif
794
795   return String::NewFromUtf8(isolate, path);
796 }
797
798
799 Local<Value> UVException(Isolate* isolate,
800                          int errorno,
801                          const char* syscall,
802                          const char* msg,
803                          const char* path) {
804   return UVException(isolate, errorno, syscall, msg, path, nullptr);
805 }
806
807
808 Local<Value> UVException(Isolate* isolate,
809                          int errorno,
810                          const char* syscall,
811                          const char* msg,
812                          const char* path,
813                          const char* dest) {
814   Environment* env = Environment::GetCurrent(isolate);
815
816   if (!msg || !msg[0])
817     msg = uv_strerror(errorno);
818
819   Local<String> js_code = OneByteString(isolate, uv_err_name(errorno));
820   Local<String> js_syscall = OneByteString(isolate, syscall);
821   Local<String> js_path;
822   Local<String> js_dest;
823
824   Local<String> js_msg = js_code;
825   js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate, ": "));
826   js_msg = String::Concat(js_msg, OneByteString(isolate, msg));
827   js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate, ", "));
828   js_msg = String::Concat(js_msg, js_syscall);
829
830   if (path != nullptr) {
831     js_path = StringFromPath(isolate, path);
832
833     js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate, " '"));
834     js_msg = String::Concat(js_msg, js_path);
835     js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate, "'"));
836   }
837
838   if (dest != nullptr) {
839     js_dest = StringFromPath(isolate, dest);
840
841     js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate, " -> '"));
842     js_msg = String::Concat(js_msg, js_dest);
843     js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate, "'"));
844   }
845
846   Local<Object> e = Exception::Error(js_msg)->ToObject(isolate);
847
848   // TODO(piscisaureus) errno should probably go; the user has no way of
849   // knowing which uv errno value maps to which error.
850   e->Set(env->errno_string(), Integer::New(isolate, errorno));
851   e->Set(env->code_string(), js_code);
852   e->Set(env->syscall_string(), js_syscall);
853   if (!js_path.IsEmpty())
854     e->Set(env->path_string(), js_path);
855   if (!js_dest.IsEmpty())
856     e->Set(env->dest_string(), js_dest);
857
858   return e;
859 }
860
861
862 // Look up environment variable unless running as setuid root.
863 inline const char* secure_getenv(const char* key) {
864 #ifndef _WIN32
865   if (getuid() != geteuid() || getgid() != getegid())
866     return nullptr;
867 #endif
868   return getenv(key);
869 }
870
871
872 #ifdef _WIN32
873 // Does about the same as strerror(),
874 // but supports all windows error messages
875 static const char *winapi_strerror(const int errorno, bool* must_free) {
876   char *errmsg = nullptr;
877
878   FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
879       FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, errorno,
880       MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&errmsg, 0, nullptr);
881
882   if (errmsg) {
883     *must_free = true;
884
885     // Remove trailing newlines
886     for (int i = strlen(errmsg) - 1;
887         i >= 0 && (errmsg[i] == '\n' || errmsg[i] == '\r'); i--) {
888       errmsg[i] = '\0';
889     }
890
891     return errmsg;
892   } else {
893     // FormatMessage failed
894     *must_free = false;
895     return "Unknown error";
896   }
897 }
898
899
900 Local<Value> WinapiErrnoException(Isolate* isolate,
901                                   int errorno,
902                                   const char* syscall,
903                                   const char* msg,
904                                   const char* path) {
905   Environment* env = Environment::GetCurrent(isolate);
906   Local<Value> e;
907   bool must_free = false;
908   if (!msg || !msg[0]) {
909     msg = winapi_strerror(errorno, &must_free);
910   }
911   Local<String> message = OneByteString(env->isolate(), msg);
912
913   if (path) {
914     Local<String> cons1 =
915         String::Concat(message, FIXED_ONE_BYTE_STRING(isolate, " '"));
916     Local<String> cons2 =
917         String::Concat(cons1, String::NewFromUtf8(isolate, path));
918     Local<String> cons3 =
919         String::Concat(cons2, FIXED_ONE_BYTE_STRING(isolate, "'"));
920     e = Exception::Error(cons3);
921   } else {
922     e = Exception::Error(message);
923   }
924
925   Local<Object> obj = e->ToObject(env->isolate());
926   obj->Set(env->errno_string(), Integer::New(isolate, errorno));
927
928   if (path != nullptr) {
929     obj->Set(env->path_string(), String::NewFromUtf8(isolate, path));
930   }
931
932   if (syscall != nullptr) {
933     obj->Set(env->syscall_string(), OneByteString(isolate, syscall));
934   }
935
936   if (must_free)
937     LocalFree((HLOCAL)msg);
938
939   return e;
940 }
941 #endif
942
943
944 void* ArrayBufferAllocator::Allocate(size_t size) {
945   if (env_ == nullptr || !env_->array_buffer_allocator_info()->no_zero_fill())
946     return calloc(size, 1);
947   env_->array_buffer_allocator_info()->reset_fill_flag();
948   return malloc(size);
949 }
950
951 static bool DomainHasErrorHandler(const Environment* env,
952                                   const Local<Object>& domain) {
953   HandleScope scope(env->isolate());
954
955   Local<Value> domain_event_listeners_v = domain->Get(env->events_string());
956   if (!domain_event_listeners_v->IsObject())
957     return false;
958
959   Local<Object> domain_event_listeners_o =
960       domain_event_listeners_v.As<Object>();
961
962   Local<Value> domain_error_listeners_v =
963       domain_event_listeners_o->Get(env->error_string());
964
965   if (domain_error_listeners_v->IsFunction() ||
966       (domain_error_listeners_v->IsArray() &&
967       domain_error_listeners_v.As<Array>()->Length() > 0))
968     return true;
969
970   return false;
971 }
972
973 static bool TopDomainHasErrorHandler(const Environment* env) {
974   HandleScope scope(env->isolate());
975
976   if (!env->using_domains())
977     return false;
978
979   Local<Array> domains_stack_array = env->domains_stack_array().As<Array>();
980   if (domains_stack_array->Length() == 0)
981     return false;
982
983   uint32_t domains_stack_length = domains_stack_array->Length();
984   if (domains_stack_length == 0)
985     return false;
986
987   Local<Value> top_domain_v =
988       domains_stack_array->Get(domains_stack_length - 1);
989
990   if (!top_domain_v->IsObject())
991     return false;
992
993   Local<Object> top_domain = top_domain_v.As<Object>();
994   if (DomainHasErrorHandler(env, top_domain))
995     return true;
996
997   return false;
998 }
999
1000
1001 static bool ShouldAbortOnUncaughtException(Isolate* isolate) {
1002   HandleScope scope(isolate);
1003
1004   Environment* env = Environment::GetCurrent(isolate);
1005   Local<Object> process_object = env->process_object();
1006   Local<String> emitting_top_level_domain_error_key =
1007     env->emitting_top_level_domain_error_string();
1008   bool isEmittingTopLevelDomainError =
1009       process_object->Get(emitting_top_level_domain_error_key)->BooleanValue();
1010
1011   return isEmittingTopLevelDomainError || !TopDomainHasErrorHandler(env);
1012 }
1013
1014
1015 void SetupDomainUse(const FunctionCallbackInfo<Value>& args) {
1016   Environment* env = Environment::GetCurrent(args);
1017
1018   if (env->using_domains())
1019     return;
1020   env->set_using_domains(true);
1021
1022   HandleScope scope(env->isolate());
1023   Local<Object> process_object = env->process_object();
1024
1025   Local<String> tick_callback_function_key = env->tick_domain_cb_string();
1026   Local<Function> tick_callback_function =
1027       process_object->Get(tick_callback_function_key).As<Function>();
1028
1029   if (!tick_callback_function->IsFunction()) {
1030     fprintf(stderr, "process._tickDomainCallback assigned to non-function\n");
1031     ABORT();
1032   }
1033
1034   process_object->Set(env->tick_callback_string(), tick_callback_function);
1035   env->set_tick_callback_function(tick_callback_function);
1036
1037   CHECK(args[0]->IsArray());
1038   env->set_domain_array(args[0].As<Array>());
1039
1040   CHECK(args[1]->IsArray());
1041   env->set_domains_stack_array(args[1].As<Array>());
1042
1043   // Do a little housekeeping.
1044   env->process_object()->Delete(
1045       FIXED_ONE_BYTE_STRING(args.GetIsolate(), "_setupDomainUse"));
1046
1047   uint32_t* const fields = env->domain_flag()->fields();
1048   uint32_t const fields_count = env->domain_flag()->fields_count();
1049
1050   Local<ArrayBuffer> array_buffer =
1051       ArrayBuffer::New(env->isolate(), fields, sizeof(*fields) * fields_count);
1052
1053   args.GetReturnValue().Set(Uint32Array::New(array_buffer, 0, fields_count));
1054 }
1055
1056 void RunMicrotasks(const FunctionCallbackInfo<Value>& args) {
1057   args.GetIsolate()->RunMicrotasks();
1058 }
1059
1060
1061 void SetupNextTick(const FunctionCallbackInfo<Value>& args) {
1062   Environment* env = Environment::GetCurrent(args);
1063
1064   CHECK(args[0]->IsFunction());
1065   CHECK(args[1]->IsObject());
1066
1067   env->set_tick_callback_function(args[0].As<Function>());
1068
1069   env->SetMethod(args[1].As<Object>(), "runMicrotasks", RunMicrotasks);
1070
1071   // Do a little housekeeping.
1072   env->process_object()->Delete(
1073       FIXED_ONE_BYTE_STRING(args.GetIsolate(), "_setupNextTick"));
1074
1075   // Values use to cross communicate with processNextTick.
1076   uint32_t* const fields = env->tick_info()->fields();
1077   uint32_t const fields_count = env->tick_info()->fields_count();
1078
1079   Local<ArrayBuffer> array_buffer =
1080       ArrayBuffer::New(env->isolate(), fields, sizeof(*fields) * fields_count);
1081
1082   args.GetReturnValue().Set(Uint32Array::New(array_buffer, 0, fields_count));
1083 }
1084
1085 void PromiseRejectCallback(PromiseRejectMessage message) {
1086   Local<Promise> promise = message.GetPromise();
1087   Isolate* isolate = promise->GetIsolate();
1088   Local<Value> value = message.GetValue();
1089   Local<Integer> event = Integer::New(isolate, message.GetEvent());
1090
1091   Environment* env = Environment::GetCurrent(isolate);
1092   Local<Function> callback = env->promise_reject_function();
1093
1094   if (value.IsEmpty())
1095     value = Undefined(isolate);
1096
1097   Local<Value> args[] = { event, promise, value };
1098   Local<Object> process = env->process_object();
1099
1100   callback->Call(process, ARRAY_SIZE(args), args);
1101 }
1102
1103 void SetupPromises(const FunctionCallbackInfo<Value>& args) {
1104   Environment* env = Environment::GetCurrent(args);
1105   Isolate* isolate = env->isolate();
1106
1107   CHECK(args[0]->IsFunction());
1108
1109   isolate->SetPromiseRejectCallback(PromiseRejectCallback);
1110   env->set_promise_reject_function(args[0].As<Function>());
1111
1112   env->process_object()->Delete(
1113       FIXED_ONE_BYTE_STRING(args.GetIsolate(), "_setupPromises"));
1114 }
1115
1116
1117 Local<Value> MakeCallback(Environment* env,
1118                            Local<Value> recv,
1119                            const Local<Function> callback,
1120                            int argc,
1121                            Local<Value> argv[]) {
1122   // If you hit this assertion, you forgot to enter the v8::Context first.
1123   CHECK_EQ(env->context(), env->isolate()->GetCurrentContext());
1124
1125   Local<Function> pre_fn = env->async_hooks_pre_function();
1126   Local<Function> post_fn = env->async_hooks_post_function();
1127   Local<Object> object, domain;
1128   bool ran_init_callback = false;
1129   bool has_domain = false;
1130
1131   // TODO(trevnorris): Adding "_asyncQueue" to the "this" in the init callback
1132   // is a horrible way to detect usage. Rethink how detection should happen.
1133   if (recv->IsObject()) {
1134     object = recv.As<Object>();
1135     Local<Value> async_queue_v = object->Get(env->async_queue_string());
1136     if (async_queue_v->IsObject())
1137       ran_init_callback = true;
1138   }
1139
1140   if (env->using_domains()) {
1141     CHECK(recv->IsObject());
1142     Local<Value> domain_v = object->Get(env->domain_string());
1143     has_domain = domain_v->IsObject();
1144     if (has_domain) {
1145       domain = domain_v.As<Object>();
1146       if (domain->Get(env->disposed_string())->IsTrue())
1147         return Undefined(env->isolate());
1148     }
1149   }
1150
1151   TryCatch try_catch;
1152   try_catch.SetVerbose(true);
1153
1154   if (has_domain) {
1155     Local<Value> enter_v = domain->Get(env->enter_string());
1156     if (enter_v->IsFunction()) {
1157         enter_v.As<Function>()->Call(domain, 0, nullptr);
1158       if (try_catch.HasCaught())
1159         return Undefined(env->isolate());
1160     }
1161   }
1162
1163   if (ran_init_callback && !pre_fn.IsEmpty()) {
1164     try_catch.SetVerbose(false);
1165     pre_fn->Call(object, 0, nullptr);
1166     if (try_catch.HasCaught())
1167       FatalError("node::MakeCallback", "pre hook threw");
1168     try_catch.SetVerbose(true);
1169   }
1170
1171   Local<Value> ret = callback->Call(recv, argc, argv);
1172
1173   if (ran_init_callback && !post_fn.IsEmpty()) {
1174     try_catch.SetVerbose(false);
1175     post_fn->Call(object, 0, nullptr);
1176     if (try_catch.HasCaught())
1177       FatalError("node::MakeCallback", "post hook threw");
1178     try_catch.SetVerbose(true);
1179   }
1180
1181   if (has_domain) {
1182     Local<Value> exit_v = domain->Get(env->exit_string());
1183     if (exit_v->IsFunction()) {
1184       exit_v.As<Function>()->Call(domain, 0, nullptr);
1185       if (try_catch.HasCaught())
1186         return Undefined(env->isolate());
1187     }
1188   }
1189
1190   if (try_catch.HasCaught()) {
1191     return Undefined(env->isolate());
1192   }
1193
1194   if (!env->KickNextTick())
1195     return Undefined(env->isolate());
1196
1197   return ret;
1198 }
1199
1200
1201 // Internal only.
1202 Local<Value> MakeCallback(Environment* env,
1203                            Local<Object> recv,
1204                            uint32_t index,
1205                            int argc,
1206                            Local<Value> argv[]) {
1207   Local<Value> cb_v = recv->Get(index);
1208   CHECK(cb_v->IsFunction());
1209   return MakeCallback(env, recv.As<Value>(), cb_v.As<Function>(), argc, argv);
1210 }
1211
1212
1213 Local<Value> MakeCallback(Environment* env,
1214                            Local<Object> recv,
1215                            Local<String> symbol,
1216                            int argc,
1217                            Local<Value> argv[]) {
1218   Local<Value> cb_v = recv->Get(symbol);
1219   CHECK(cb_v->IsFunction());
1220   return MakeCallback(env, recv.As<Value>(), cb_v.As<Function>(), argc, argv);
1221 }
1222
1223
1224 Local<Value> MakeCallback(Environment* env,
1225                            Local<Object> recv,
1226                            const char* method,
1227                            int argc,
1228                            Local<Value> argv[]) {
1229   Local<String> method_string = OneByteString(env->isolate(), method);
1230   return MakeCallback(env, recv, method_string, argc, argv);
1231 }
1232
1233
1234 Local<Value> MakeCallback(Isolate* isolate,
1235                            Local<Object> recv,
1236                            const char* method,
1237                            int argc,
1238                            Local<Value> argv[]) {
1239   EscapableHandleScope handle_scope(isolate);
1240   Local<Context> context = recv->CreationContext();
1241   Environment* env = Environment::GetCurrent(context);
1242   Context::Scope context_scope(context);
1243   return handle_scope.Escape(
1244       Local<Value>::New(isolate, MakeCallback(env, recv, method, argc, argv)));
1245 }
1246
1247
1248 Local<Value> MakeCallback(Isolate* isolate,
1249                            Local<Object> recv,
1250                            Local<String> symbol,
1251                            int argc,
1252                            Local<Value> argv[]) {
1253   EscapableHandleScope handle_scope(isolate);
1254   Local<Context> context = recv->CreationContext();
1255   Environment* env = Environment::GetCurrent(context);
1256   Context::Scope context_scope(context);
1257   return handle_scope.Escape(
1258       Local<Value>::New(isolate, MakeCallback(env, recv, symbol, argc, argv)));
1259 }
1260
1261
1262 Local<Value> MakeCallback(Isolate* isolate,
1263                            Local<Object> recv,
1264                            Local<Function> callback,
1265                            int argc,
1266                            Local<Value> argv[]) {
1267   EscapableHandleScope handle_scope(isolate);
1268   Local<Context> context = recv->CreationContext();
1269   Environment* env = Environment::GetCurrent(context);
1270   Context::Scope context_scope(context);
1271   return handle_scope.Escape(Local<Value>::New(
1272         isolate,
1273         MakeCallback(env, recv.As<Value>(), callback, argc, argv)));
1274 }
1275
1276
1277 enum encoding ParseEncoding(const char* encoding,
1278                             enum encoding default_encoding) {
1279   switch (encoding[0]) {
1280     case 'u':
1281       // utf8, utf16le
1282       if (encoding[1] == 't' && encoding[2] == 'f') {
1283         // Skip `-`
1284         encoding += encoding[3] == '-' ? 4 : 3;
1285         if (encoding[0] == '8' && encoding[1] == '\0')
1286           return UTF8;
1287         if (strncmp(encoding, "16le", 4) == 0)
1288           return UCS2;
1289
1290       // ucs2
1291       } else if (encoding[1] == 'c' && encoding[2] == 's') {
1292         encoding += encoding[3] == '-' ? 4 : 3;
1293         if (encoding[0] == '2' && encoding[1] == '\0')
1294           return UCS2;
1295       }
1296       break;
1297     case 'b':
1298       // binary
1299       if (encoding[1] == 'i') {
1300         if (strncmp(encoding + 2, "nary", 4) == 0)
1301           return BINARY;
1302
1303       // buffer
1304       } else if (encoding[1] == 'u') {
1305         if (strncmp(encoding + 2, "ffer", 4) == 0)
1306           return BUFFER;
1307       }
1308       break;
1309     case '\0':
1310       return default_encoding;
1311     default:
1312       break;
1313   }
1314
1315   if (strcasecmp(encoding, "utf8") == 0) {
1316     return UTF8;
1317   } else if (strcasecmp(encoding, "utf-8") == 0) {
1318     return UTF8;
1319   } else if (strcasecmp(encoding, "ascii") == 0) {
1320     return ASCII;
1321   } else if (strcasecmp(encoding, "base64") == 0) {
1322     return BASE64;
1323   } else if (strcasecmp(encoding, "ucs2") == 0) {
1324     return UCS2;
1325   } else if (strcasecmp(encoding, "ucs-2") == 0) {
1326     return UCS2;
1327   } else if (strcasecmp(encoding, "utf16le") == 0) {
1328     return UCS2;
1329   } else if (strcasecmp(encoding, "utf-16le") == 0) {
1330     return UCS2;
1331   } else if (strcasecmp(encoding, "binary") == 0) {
1332     return BINARY;
1333   } else if (strcasecmp(encoding, "buffer") == 0) {
1334     return BUFFER;
1335   } else if (strcasecmp(encoding, "hex") == 0) {
1336     return HEX;
1337   } else if (strcasecmp(encoding, "raw") == 0) {
1338     if (!no_deprecation) {
1339       fprintf(stderr, "'raw' (array of integers) has been removed. "
1340                       "Use 'binary'.\n");
1341     }
1342     return BINARY;
1343   } else if (strcasecmp(encoding, "raws") == 0) {
1344     if (!no_deprecation) {
1345       fprintf(stderr, "'raws' encoding has been renamed to 'binary'. "
1346                       "Please update your code.\n");
1347     }
1348     return BINARY;
1349   } else {
1350     return default_encoding;
1351   }
1352 }
1353
1354
1355 enum encoding ParseEncoding(Isolate* isolate,
1356                             Local<Value> encoding_v,
1357                             enum encoding default_encoding) {
1358   if (!encoding_v->IsString())
1359     return default_encoding;
1360
1361   node::Utf8Value encoding(isolate, encoding_v);
1362
1363   return ParseEncoding(*encoding, default_encoding);
1364 }
1365
1366 Local<Value> Encode(Isolate* isolate,
1367                     const char* buf,
1368                     size_t len,
1369                     enum encoding encoding) {
1370   CHECK_NE(encoding, UCS2);
1371   return StringBytes::Encode(isolate, buf, len, encoding);
1372 }
1373
1374 Local<Value> Encode(Isolate* isolate, const uint16_t* buf, size_t len) {
1375   return StringBytes::Encode(isolate, buf, len);
1376 }
1377
1378 // Returns -1 if the handle was not valid for decoding
1379 ssize_t DecodeBytes(Isolate* isolate,
1380                     Local<Value> val,
1381                     enum encoding encoding) {
1382   HandleScope scope(isolate);
1383
1384   if (val->IsArray()) {
1385     fprintf(stderr, "'raw' encoding (array of integers) has been removed. "
1386                     "Use 'binary'.\n");
1387     UNREACHABLE();
1388     return -1;
1389   }
1390
1391   return StringBytes::Size(isolate, val, encoding);
1392 }
1393
1394 // Returns number of bytes written.
1395 ssize_t DecodeWrite(Isolate* isolate,
1396                     char* buf,
1397                     size_t buflen,
1398                     Local<Value> val,
1399                     enum encoding encoding) {
1400   return StringBytes::Write(isolate, buf, buflen, val, encoding, nullptr);
1401 }
1402
1403 void AppendExceptionLine(Environment* env,
1404                          Local<Value> er,
1405                          Local<Message> message) {
1406   if (message.IsEmpty())
1407     return;
1408
1409   HandleScope scope(env->isolate());
1410   Local<Object> err_obj;
1411   if (!er.IsEmpty() && er->IsObject()) {
1412     err_obj = er.As<Object>();
1413
1414     // Do it only once per message
1415     if (!err_obj->GetHiddenValue(env->processed_string()).IsEmpty())
1416       return;
1417     err_obj->SetHiddenValue(env->processed_string(), True(env->isolate()));
1418   }
1419
1420   // Print (filename):(line number): (message).
1421   node::Utf8Value filename(env->isolate(), message->GetScriptResourceName());
1422   const char* filename_string = *filename;
1423   int linenum = message->GetLineNumber();
1424   // Print line of source code.
1425   node::Utf8Value sourceline(env->isolate(), message->GetSourceLine());
1426   const char* sourceline_string = *sourceline;
1427
1428   // Because of how node modules work, all scripts are wrapped with a
1429   // "function (module, exports, __filename, ...) {"
1430   // to provide script local variables.
1431   //
1432   // When reporting errors on the first line of a script, this wrapper
1433   // function is leaked to the user. There used to be a hack here to
1434   // truncate off the first 62 characters, but it caused numerous other
1435   // problems when vm.runIn*Context() methods were used for non-module
1436   // code.
1437   //
1438   // If we ever decide to re-instate such a hack, the following steps
1439   // must be taken:
1440   //
1441   // 1. Pass a flag around to say "this code was wrapped"
1442   // 2. Update the stack frame output so that it is also correct.
1443   //
1444   // It would probably be simpler to add a line rather than add some
1445   // number of characters to the first line, since V8 truncates the
1446   // sourceline to 78 characters, and we end up not providing very much
1447   // useful debugging info to the user if we remove 62 characters.
1448
1449   int start = message->GetStartColumn();
1450   int end = message->GetEndColumn();
1451
1452   char arrow[1024];
1453   int max_off = sizeof(arrow) - 2;
1454
1455   int off = snprintf(arrow,
1456                      sizeof(arrow),
1457                      "%s:%i\n%s\n",
1458                      filename_string,
1459                      linenum,
1460                      sourceline_string);
1461   CHECK_GE(off, 0);
1462   if (off > max_off) {
1463     off = max_off;
1464   }
1465
1466   // Print wavy underline (GetUnderline is deprecated).
1467   for (int i = 0; i < start; i++) {
1468     if (sourceline_string[i] == '\0' || off >= max_off) {
1469       break;
1470     }
1471     CHECK_LT(off, max_off);
1472     arrow[off++] = (sourceline_string[i] == '\t') ? '\t' : ' ';
1473   }
1474   for (int i = start; i < end; i++) {
1475     if (sourceline_string[i] == '\0' || off >= max_off) {
1476       break;
1477     }
1478     CHECK_LT(off, max_off);
1479     arrow[off++] = '^';
1480   }
1481   CHECK_LE(off, max_off);
1482   arrow[off] = '\n';
1483   arrow[off + 1] = '\0';
1484
1485   Local<String> arrow_str = String::NewFromUtf8(env->isolate(), arrow);
1486
1487   // Allocation failed, just print it out
1488   if (arrow_str.IsEmpty() || err_obj.IsEmpty() || !err_obj->IsNativeError())
1489     goto print;
1490
1491   err_obj->SetHiddenValue(env->arrow_message_string(), arrow_str);
1492   return;
1493
1494  print:
1495   if (env->printed_error())
1496     return;
1497   env->set_printed_error(true);
1498   uv_tty_reset_mode();
1499   PrintErrorString("\n%s", arrow);
1500 }
1501
1502
1503 static void ReportException(Environment* env,
1504                             Local<Value> er,
1505                             Local<Message> message) {
1506   HandleScope scope(env->isolate());
1507
1508   AppendExceptionLine(env, er, message);
1509
1510   Local<Value> trace_value;
1511   Local<Value> arrow;
1512
1513   if (er->IsUndefined() || er->IsNull()) {
1514     trace_value = Undefined(env->isolate());
1515   } else {
1516     Local<Object> err_obj = er->ToObject(env->isolate());
1517
1518     trace_value = err_obj->Get(env->stack_string());
1519     arrow = err_obj->GetHiddenValue(env->arrow_message_string());
1520   }
1521
1522   node::Utf8Value trace(env->isolate(), trace_value);
1523
1524   // range errors have a trace member set to undefined
1525   if (trace.length() > 0 && !trace_value->IsUndefined()) {
1526     if (arrow.IsEmpty() || !arrow->IsString()) {
1527       PrintErrorString("%s\n", *trace);
1528     } else {
1529       node::Utf8Value arrow_string(env->isolate(), arrow);
1530       PrintErrorString("%s\n%s\n", *arrow_string, *trace);
1531     }
1532   } else {
1533     // this really only happens for RangeErrors, since they're the only
1534     // kind that won't have all this info in the trace, or when non-Error
1535     // objects are thrown manually.
1536     Local<Value> message;
1537     Local<Value> name;
1538
1539     if (er->IsObject()) {
1540       Local<Object> err_obj = er.As<Object>();
1541       message = err_obj->Get(env->message_string());
1542       name = err_obj->Get(FIXED_ONE_BYTE_STRING(env->isolate(), "name"));
1543     }
1544
1545     if (message.IsEmpty() ||
1546         message->IsUndefined() ||
1547         name.IsEmpty() ||
1548         name->IsUndefined()) {
1549       // Not an error object. Just print as-is.
1550       String::Utf8Value message(er);
1551
1552       PrintErrorString("%s\n", *message ? *message :
1553                                           "<toString() threw exception>");
1554     } else {
1555       node::Utf8Value name_string(env->isolate(), name);
1556       node::Utf8Value message_string(env->isolate(), message);
1557
1558       if (arrow.IsEmpty() || !arrow->IsString()) {
1559         PrintErrorString("%s: %s\n", *name_string, *message_string);
1560       } else {
1561         node::Utf8Value arrow_string(env->isolate(), arrow);
1562         PrintErrorString("%s\n%s: %s\n",
1563                          *arrow_string,
1564                          *name_string,
1565                          *message_string);
1566       }
1567     }
1568   }
1569
1570   fflush(stderr);
1571 }
1572
1573
1574 static void ReportException(Environment* env, const TryCatch& try_catch) {
1575   ReportException(env, try_catch.Exception(), try_catch.Message());
1576 }
1577
1578
1579 // Executes a str within the current v8 context.
1580 static Local<Value> ExecuteString(Environment* env,
1581                                   Local<String> source,
1582                                   Local<String> filename) {
1583   EscapableHandleScope scope(env->isolate());
1584   TryCatch try_catch;
1585
1586   // try_catch must be nonverbose to disable FatalException() handler,
1587   // we will handle exceptions ourself.
1588   try_catch.SetVerbose(false);
1589
1590   Local<v8::Script> script = v8::Script::Compile(source, filename);
1591   if (script.IsEmpty()) {
1592     ReportException(env, try_catch);
1593     exit(3);
1594   }
1595
1596   Local<Value> result = script->Run();
1597   if (result.IsEmpty()) {
1598     ReportException(env, try_catch);
1599     exit(4);
1600   }
1601
1602   return scope.Escape(result);
1603 }
1604
1605
1606 static void GetActiveRequests(const FunctionCallbackInfo<Value>& args) {
1607   Environment* env = Environment::GetCurrent(args);
1608
1609   Local<Array> ary = Array::New(args.GetIsolate());
1610   int i = 0;
1611
1612   for (auto w : *env->req_wrap_queue())
1613     if (w->persistent().IsEmpty() == false)
1614       ary->Set(i++, w->object());
1615
1616   args.GetReturnValue().Set(ary);
1617 }
1618
1619
1620 // Non-static, friend of HandleWrap. Could have been a HandleWrap method but
1621 // implemented here for consistency with GetActiveRequests().
1622 void GetActiveHandles(const FunctionCallbackInfo<Value>& args) {
1623   Environment* env = Environment::GetCurrent(args);
1624
1625   Local<Array> ary = Array::New(env->isolate());
1626   int i = 0;
1627
1628   Local<String> owner_sym = env->owner_string();
1629
1630   for (auto w : *env->handle_wrap_queue()) {
1631     if (w->persistent().IsEmpty() || (w->flags_ & HandleWrap::kUnref))
1632       continue;
1633     Local<Object> object = w->object();
1634     Local<Value> owner = object->Get(owner_sym);
1635     if (owner->IsUndefined())
1636       owner = object;
1637     ary->Set(i++, owner);
1638   }
1639
1640   args.GetReturnValue().Set(ary);
1641 }
1642
1643
1644 static void Abort(const FunctionCallbackInfo<Value>& args) {
1645   ABORT();
1646 }
1647
1648
1649 static void Chdir(const FunctionCallbackInfo<Value>& args) {
1650   Environment* env = Environment::GetCurrent(args);
1651
1652   if (args.Length() != 1 || !args[0]->IsString()) {
1653     return env->ThrowTypeError("Bad argument.");
1654   }
1655
1656   node::Utf8Value path(args.GetIsolate(), args[0]);
1657   int err = uv_chdir(*path);
1658   if (err) {
1659     return env->ThrowUVException(err, "uv_chdir");
1660   }
1661 }
1662
1663
1664 static void Cwd(const FunctionCallbackInfo<Value>& args) {
1665   Environment* env = Environment::GetCurrent(args);
1666 #ifdef _WIN32
1667   /* MAX_PATH is in characters, not bytes. Make sure we have enough headroom. */
1668   char buf[MAX_PATH * 4];
1669 #else
1670   char buf[PATH_MAX];
1671 #endif
1672
1673   size_t cwd_len = sizeof(buf);
1674   int err = uv_cwd(buf, &cwd_len);
1675   if (err) {
1676     return env->ThrowUVException(err, "uv_cwd");
1677   }
1678
1679   Local<String> cwd = String::NewFromUtf8(env->isolate(),
1680                                           buf,
1681                                           String::kNormalString,
1682                                           cwd_len);
1683   args.GetReturnValue().Set(cwd);
1684 }
1685
1686
1687 static void Umask(const FunctionCallbackInfo<Value>& args) {
1688   Environment* env = Environment::GetCurrent(args);
1689   uint32_t old;
1690
1691   if (args.Length() < 1 || args[0]->IsUndefined()) {
1692     old = umask(0);
1693     umask(static_cast<mode_t>(old));
1694   } else if (!args[0]->IsInt32() && !args[0]->IsString()) {
1695     return env->ThrowTypeError("argument must be an integer or octal string.");
1696   } else {
1697     int oct;
1698     if (args[0]->IsInt32()) {
1699       oct = args[0]->Uint32Value();
1700     } else {
1701       oct = 0;
1702       node::Utf8Value str(env->isolate(), args[0]);
1703
1704       // Parse the octal string.
1705       for (size_t i = 0; i < str.length(); i++) {
1706         char c = (*str)[i];
1707         if (c > '7' || c < '0') {
1708           return env->ThrowTypeError("invalid octal string");
1709         }
1710         oct *= 8;
1711         oct += c - '0';
1712       }
1713     }
1714     old = umask(static_cast<mode_t>(oct));
1715   }
1716
1717   args.GetReturnValue().Set(old);
1718 }
1719
1720
1721 #if defined(__POSIX__) && !defined(__ANDROID__)
1722
1723 static const uid_t uid_not_found = static_cast<uid_t>(-1);
1724 static const gid_t gid_not_found = static_cast<gid_t>(-1);
1725
1726
1727 static uid_t uid_by_name(const char* name) {
1728   struct passwd pwd;
1729   struct passwd* pp;
1730   char buf[8192];
1731
1732   errno = 0;
1733   pp = nullptr;
1734
1735   if (getpwnam_r(name, &pwd, buf, sizeof(buf), &pp) == 0 && pp != nullptr) {
1736     return pp->pw_uid;
1737   }
1738
1739   return uid_not_found;
1740 }
1741
1742
1743 static char* name_by_uid(uid_t uid) {
1744   struct passwd pwd;
1745   struct passwd* pp;
1746   char buf[8192];
1747   int rc;
1748
1749   errno = 0;
1750   pp = nullptr;
1751
1752   if ((rc = getpwuid_r(uid, &pwd, buf, sizeof(buf), &pp)) == 0 &&
1753       pp != nullptr) {
1754     return strdup(pp->pw_name);
1755   }
1756
1757   if (rc == 0) {
1758     errno = ENOENT;
1759   }
1760
1761   return nullptr;
1762 }
1763
1764
1765 static gid_t gid_by_name(const char* name) {
1766   struct group pwd;
1767   struct group* pp;
1768   char buf[8192];
1769
1770   errno = 0;
1771   pp = nullptr;
1772
1773   if (getgrnam_r(name, &pwd, buf, sizeof(buf), &pp) == 0 && pp != nullptr) {
1774     return pp->gr_gid;
1775   }
1776
1777   return gid_not_found;
1778 }
1779
1780
1781 #if 0  // For future use.
1782 static const char* name_by_gid(gid_t gid) {
1783   struct group pwd;
1784   struct group* pp;
1785   char buf[8192];
1786   int rc;
1787
1788   errno = 0;
1789   pp = nullptr;
1790
1791   if ((rc = getgrgid_r(gid, &pwd, buf, sizeof(buf), &pp)) == 0 &&
1792       pp != nullptr) {
1793     return strdup(pp->gr_name);
1794   }
1795
1796   if (rc == 0) {
1797     errno = ENOENT;
1798   }
1799
1800   return nullptr;
1801 }
1802 #endif
1803
1804
1805 static uid_t uid_by_name(Isolate* isolate, Local<Value> value) {
1806   if (value->IsUint32()) {
1807     return static_cast<uid_t>(value->Uint32Value());
1808   } else {
1809     node::Utf8Value name(isolate, value);
1810     return uid_by_name(*name);
1811   }
1812 }
1813
1814
1815 static gid_t gid_by_name(Isolate* isolate, Local<Value> value) {
1816   if (value->IsUint32()) {
1817     return static_cast<gid_t>(value->Uint32Value());
1818   } else {
1819     node::Utf8Value name(isolate, value);
1820     return gid_by_name(*name);
1821   }
1822 }
1823
1824
1825 static void GetUid(const FunctionCallbackInfo<Value>& args) {
1826   // uid_t is an uint32_t on all supported platforms.
1827   args.GetReturnValue().Set(static_cast<uint32_t>(getuid()));
1828 }
1829
1830
1831 static void GetGid(const FunctionCallbackInfo<Value>& args) {
1832   // gid_t is an uint32_t on all supported platforms.
1833   args.GetReturnValue().Set(static_cast<uint32_t>(getgid()));
1834 }
1835
1836
1837 static void GetEUid(const FunctionCallbackInfo<Value>& args) {
1838   // uid_t is an uint32_t on all supported platforms.
1839   args.GetReturnValue().Set(static_cast<uint32_t>(geteuid()));
1840 }
1841
1842
1843 static void GetEGid(const FunctionCallbackInfo<Value>& args) {
1844   // gid_t is an uint32_t on all supported platforms.
1845   args.GetReturnValue().Set(static_cast<uint32_t>(getegid()));
1846 }
1847
1848
1849 static void SetGid(const FunctionCallbackInfo<Value>& args) {
1850   Environment* env = Environment::GetCurrent(args);
1851
1852   if (!args[0]->IsUint32() && !args[0]->IsString()) {
1853     return env->ThrowTypeError("setgid argument must be a number or a string");
1854   }
1855
1856   gid_t gid = gid_by_name(env->isolate(), args[0]);
1857
1858   if (gid == gid_not_found) {
1859     return env->ThrowError("setgid group id does not exist");
1860   }
1861
1862   if (setgid(gid)) {
1863     return env->ThrowErrnoException(errno, "setgid");
1864   }
1865 }
1866
1867
1868 static void SetEGid(const FunctionCallbackInfo<Value>& args) {
1869   Environment* env = Environment::GetCurrent(args);
1870
1871   if (!args[0]->IsUint32() && !args[0]->IsString()) {
1872     return env->ThrowTypeError("setegid argument must be a number or string");
1873   }
1874
1875   gid_t gid = gid_by_name(env->isolate(), args[0]);
1876
1877   if (gid == gid_not_found) {
1878     return env->ThrowError("setegid group id does not exist");
1879   }
1880
1881   if (setegid(gid)) {
1882     return env->ThrowErrnoException(errno, "setegid");
1883   }
1884 }
1885
1886
1887 static void SetUid(const FunctionCallbackInfo<Value>& args) {
1888   Environment* env = Environment::GetCurrent(args);
1889
1890   if (!args[0]->IsUint32() && !args[0]->IsString()) {
1891     return env->ThrowTypeError("setuid argument must be a number or a string");
1892   }
1893
1894   uid_t uid = uid_by_name(env->isolate(), args[0]);
1895
1896   if (uid == uid_not_found) {
1897     return env->ThrowError("setuid user id does not exist");
1898   }
1899
1900   if (setuid(uid)) {
1901     return env->ThrowErrnoException(errno, "setuid");
1902   }
1903 }
1904
1905
1906 static void SetEUid(const FunctionCallbackInfo<Value>& args) {
1907   Environment* env = Environment::GetCurrent(args);
1908
1909   if (!args[0]->IsUint32() && !args[0]->IsString()) {
1910     return env->ThrowTypeError("seteuid argument must be a number or string");
1911   }
1912
1913   uid_t uid = uid_by_name(env->isolate(), args[0]);
1914
1915   if (uid == uid_not_found) {
1916     return env->ThrowError("seteuid user id does not exist");
1917   }
1918
1919   if (seteuid(uid)) {
1920     return env->ThrowErrnoException(errno, "seteuid");
1921   }
1922 }
1923
1924
1925 static void GetGroups(const FunctionCallbackInfo<Value>& args) {
1926   Environment* env = Environment::GetCurrent(args);
1927
1928   int ngroups = getgroups(0, nullptr);
1929
1930   if (ngroups == -1) {
1931     return env->ThrowErrnoException(errno, "getgroups");
1932   }
1933
1934   gid_t* groups = new gid_t[ngroups];
1935
1936   ngroups = getgroups(ngroups, groups);
1937
1938   if (ngroups == -1) {
1939     delete[] groups;
1940     return env->ThrowErrnoException(errno, "getgroups");
1941   }
1942
1943   Local<Array> groups_list = Array::New(env->isolate(), ngroups);
1944   bool seen_egid = false;
1945   gid_t egid = getegid();
1946
1947   for (int i = 0; i < ngroups; i++) {
1948     groups_list->Set(i, Integer::New(env->isolate(), groups[i]));
1949     if (groups[i] == egid)
1950       seen_egid = true;
1951   }
1952
1953   delete[] groups;
1954
1955   if (seen_egid == false) {
1956     groups_list->Set(ngroups, Integer::New(env->isolate(), egid));
1957   }
1958
1959   args.GetReturnValue().Set(groups_list);
1960 }
1961
1962
1963 static void SetGroups(const FunctionCallbackInfo<Value>& args) {
1964   Environment* env = Environment::GetCurrent(args);
1965
1966   if (!args[0]->IsArray()) {
1967     return env->ThrowTypeError("argument 1 must be an array");
1968   }
1969
1970   Local<Array> groups_list = args[0].As<Array>();
1971   size_t size = groups_list->Length();
1972   gid_t* groups = new gid_t[size];
1973
1974   for (size_t i = 0; i < size; i++) {
1975     gid_t gid = gid_by_name(env->isolate(), groups_list->Get(i));
1976
1977     if (gid == gid_not_found) {
1978       delete[] groups;
1979       return env->ThrowError("group name not found");
1980     }
1981
1982     groups[i] = gid;
1983   }
1984
1985   int rc = setgroups(size, groups);
1986   delete[] groups;
1987
1988   if (rc == -1) {
1989     return env->ThrowErrnoException(errno, "setgroups");
1990   }
1991 }
1992
1993
1994 static void InitGroups(const FunctionCallbackInfo<Value>& args) {
1995   Environment* env = Environment::GetCurrent(args);
1996
1997   if (!args[0]->IsUint32() && !args[0]->IsString()) {
1998     return env->ThrowTypeError("argument 1 must be a number or a string");
1999   }
2000
2001   if (!args[1]->IsUint32() && !args[1]->IsString()) {
2002     return env->ThrowTypeError("argument 2 must be a number or a string");
2003   }
2004
2005   node::Utf8Value arg0(env->isolate(), args[0]);
2006   gid_t extra_group;
2007   bool must_free;
2008   char* user;
2009
2010   if (args[0]->IsUint32()) {
2011     user = name_by_uid(args[0]->Uint32Value());
2012     must_free = true;
2013   } else {
2014     user = *arg0;
2015     must_free = false;
2016   }
2017
2018   if (user == nullptr) {
2019     return env->ThrowError("initgroups user not found");
2020   }
2021
2022   extra_group = gid_by_name(env->isolate(), args[1]);
2023
2024   if (extra_group == gid_not_found) {
2025     if (must_free)
2026       free(user);
2027     return env->ThrowError("initgroups extra group not found");
2028   }
2029
2030   int rc = initgroups(user, extra_group);
2031
2032   if (must_free) {
2033     free(user);
2034   }
2035
2036   if (rc) {
2037     return env->ThrowErrnoException(errno, "initgroups");
2038   }
2039 }
2040
2041 #endif  // __POSIX__ && !defined(__ANDROID__)
2042
2043
2044 void Exit(const FunctionCallbackInfo<Value>& args) {
2045   exit(args[0]->Int32Value());
2046 }
2047
2048
2049 static void Uptime(const FunctionCallbackInfo<Value>& args) {
2050   Environment* env = Environment::GetCurrent(args);
2051   double uptime;
2052
2053   uv_update_time(env->event_loop());
2054   uptime = uv_now(env->event_loop()) - prog_start_time;
2055
2056   args.GetReturnValue().Set(Number::New(env->isolate(), uptime / 1000));
2057 }
2058
2059
2060 void MemoryUsage(const FunctionCallbackInfo<Value>& args) {
2061   Environment* env = Environment::GetCurrent(args);
2062
2063   size_t rss;
2064   int err = uv_resident_set_memory(&rss);
2065   if (err) {
2066     return env->ThrowUVException(err, "uv_resident_set_memory");
2067   }
2068
2069   // V8 memory usage
2070   HeapStatistics v8_heap_stats;
2071   env->isolate()->GetHeapStatistics(&v8_heap_stats);
2072
2073   Local<Number> heap_total =
2074       Number::New(env->isolate(), v8_heap_stats.total_heap_size());
2075   Local<Number> heap_used =
2076       Number::New(env->isolate(), v8_heap_stats.used_heap_size());
2077
2078   Local<Object> info = Object::New(env->isolate());
2079   info->Set(env->rss_string(), Number::New(env->isolate(), rss));
2080   info->Set(env->heap_total_string(), heap_total);
2081   info->Set(env->heap_used_string(), heap_used);
2082
2083   args.GetReturnValue().Set(info);
2084 }
2085
2086
2087 void Kill(const FunctionCallbackInfo<Value>& args) {
2088   Environment* env = Environment::GetCurrent(args);
2089
2090   if (args.Length() != 2) {
2091     return env->ThrowError("Bad argument.");
2092   }
2093
2094   int pid = args[0]->Int32Value();
2095   int sig = args[1]->Int32Value();
2096   int err = uv_kill(pid, sig);
2097   args.GetReturnValue().Set(err);
2098 }
2099
2100 // used in Hrtime() below
2101 #define NANOS_PER_SEC 1000000000
2102
2103 // Hrtime exposes libuv's uv_hrtime() high-resolution timer.
2104 // The value returned by uv_hrtime() is a 64-bit int representing nanoseconds,
2105 // so this function instead returns an Array with 2 entries representing seconds
2106 // and nanoseconds, to avoid any integer overflow possibility.
2107 // Pass in an Array from a previous hrtime() call to instead get a time diff.
2108 void Hrtime(const FunctionCallbackInfo<Value>& args) {
2109   Environment* env = Environment::GetCurrent(args);
2110
2111   uint64_t t = uv_hrtime();
2112
2113   if (args.Length() > 0) {
2114     // return a time diff tuple
2115     if (!args[0]->IsArray()) {
2116       return env->ThrowTypeError(
2117           "process.hrtime() only accepts an Array tuple.");
2118     }
2119     Local<Array> inArray = Local<Array>::Cast(args[0]);
2120     uint64_t seconds = inArray->Get(0)->Uint32Value();
2121     uint64_t nanos = inArray->Get(1)->Uint32Value();
2122     t -= (seconds * NANOS_PER_SEC) + nanos;
2123   }
2124
2125   Local<Array> tuple = Array::New(env->isolate(), 2);
2126   tuple->Set(0, Integer::NewFromUnsigned(env->isolate(), t / NANOS_PER_SEC));
2127   tuple->Set(1, Integer::NewFromUnsigned(env->isolate(), t % NANOS_PER_SEC));
2128   args.GetReturnValue().Set(tuple);
2129 }
2130
2131 extern "C" void node_module_register(void* m) {
2132   struct node_module* mp = reinterpret_cast<struct node_module*>(m);
2133
2134   if (mp->nm_flags & NM_F_BUILTIN) {
2135     mp->nm_link = modlist_builtin;
2136     modlist_builtin = mp;
2137   } else if (!node_is_initialized) {
2138     // "Linked" modules are included as part of the node project.
2139     // Like builtins they are registered *before* node::Init runs.
2140     mp->nm_flags = NM_F_LINKED;
2141     mp->nm_link = modlist_linked;
2142     modlist_linked = mp;
2143   } else {
2144     modpending = mp;
2145   }
2146 }
2147
2148 struct node_module* get_builtin_module(const char* name) {
2149   struct node_module* mp;
2150
2151   for (mp = modlist_builtin; mp != nullptr; mp = mp->nm_link) {
2152     if (strcmp(mp->nm_modname, name) == 0)
2153       break;
2154   }
2155
2156   CHECK(mp == nullptr || (mp->nm_flags & NM_F_BUILTIN) != 0);
2157   return (mp);
2158 }
2159
2160 struct node_module* get_linked_module(const char* name) {
2161   struct node_module* mp;
2162
2163   for (mp = modlist_linked; mp != nullptr; mp = mp->nm_link) {
2164     if (strcmp(mp->nm_modname, name) == 0)
2165       break;
2166   }
2167
2168   CHECK(mp == nullptr || (mp->nm_flags & NM_F_LINKED) != 0);
2169   return mp;
2170 }
2171
2172 typedef void (UV_DYNAMIC* extInit)(Local<Object> exports);
2173
2174 // DLOpen is process.dlopen(module, filename).
2175 // Used to load 'module.node' dynamically shared objects.
2176 //
2177 // FIXME(bnoordhuis) Not multi-context ready. TBD how to resolve the conflict
2178 // when two contexts try to load the same shared object. Maybe have a shadow
2179 // cache that's a plain C list or hash table that's shared across contexts?
2180 void DLOpen(const FunctionCallbackInfo<Value>& args) {
2181   Environment* env = Environment::GetCurrent(args);
2182   uv_lib_t lib;
2183
2184   CHECK_EQ(modpending, nullptr);
2185
2186   if (args.Length() != 2) {
2187     env->ThrowError("process.dlopen takes exactly 2 arguments.");
2188     return;
2189   }
2190
2191   Local<Object> module = args[0]->ToObject(env->isolate());  // Cast
2192   node::Utf8Value filename(env->isolate(), args[1]);  // Cast
2193   const bool is_dlopen_error = uv_dlopen(*filename, &lib);
2194
2195   // Objects containing v14 or later modules will have registered themselves
2196   // on the pending list.  Activate all of them now.  At present, only one
2197   // module per object is supported.
2198   node_module* const mp = modpending;
2199   modpending = nullptr;
2200
2201   if (is_dlopen_error) {
2202     Local<String> errmsg = OneByteString(env->isolate(), uv_dlerror(&lib));
2203     uv_dlclose(&lib);
2204 #ifdef _WIN32
2205     // Windows needs to add the filename into the error message
2206     errmsg = String::Concat(errmsg, args[1]->ToString(env->isolate()));
2207 #endif  // _WIN32
2208     env->isolate()->ThrowException(Exception::Error(errmsg));
2209     return;
2210   }
2211
2212   if (mp == nullptr) {
2213     uv_dlclose(&lib);
2214     env->ThrowError("Module did not self-register.");
2215     return;
2216   }
2217   if (mp->nm_version != NODE_MODULE_VERSION) {
2218     char errmsg[1024];
2219     snprintf(errmsg,
2220              sizeof(errmsg),
2221              "Module version mismatch. Expected %d, got %d.",
2222              NODE_MODULE_VERSION, mp->nm_version);
2223
2224     // NOTE: `mp` is allocated inside of the shared library's memory, calling
2225     // `uv_dlclose` will deallocate it
2226     uv_dlclose(&lib);
2227     env->ThrowError(errmsg);
2228     return;
2229   }
2230   if (mp->nm_flags & NM_F_BUILTIN) {
2231     uv_dlclose(&lib);
2232     env->ThrowError("Built-in module self-registered.");
2233     return;
2234   }
2235
2236   mp->nm_dso_handle = lib.handle;
2237   mp->nm_link = modlist_addon;
2238   modlist_addon = mp;
2239
2240   Local<String> exports_string = env->exports_string();
2241   Local<Object> exports = module->Get(exports_string)->ToObject(env->isolate());
2242
2243   if (mp->nm_context_register_func != nullptr) {
2244     mp->nm_context_register_func(exports, module, env->context(), mp->nm_priv);
2245   } else if (mp->nm_register_func != nullptr) {
2246     mp->nm_register_func(exports, module, mp->nm_priv);
2247   } else {
2248     uv_dlclose(&lib);
2249     env->ThrowError("Module has no declared entry point.");
2250     return;
2251   }
2252
2253   // Tell coverity that 'handle' should not be freed when we return.
2254   // coverity[leaked_storage]
2255 }
2256
2257
2258 static void OnFatalError(const char* location, const char* message) {
2259   if (location) {
2260     PrintErrorString("FATAL ERROR: %s %s\n", location, message);
2261   } else {
2262     PrintErrorString("FATAL ERROR: %s\n", message);
2263   }
2264   fflush(stderr);
2265   ABORT();
2266 }
2267
2268
2269 NO_RETURN void FatalError(const char* location, const char* message) {
2270   OnFatalError(location, message);
2271   // to suppress compiler warning
2272   ABORT();
2273 }
2274
2275
2276 void FatalException(Isolate* isolate,
2277                     Local<Value> error,
2278                     Local<Message> message) {
2279   HandleScope scope(isolate);
2280
2281   Environment* env = Environment::GetCurrent(isolate);
2282   Local<Object> process_object = env->process_object();
2283   Local<String> fatal_exception_string = env->fatal_exception_string();
2284   Local<Function> fatal_exception_function =
2285       process_object->Get(fatal_exception_string).As<Function>();
2286
2287   if (!fatal_exception_function->IsFunction()) {
2288     // failed before the process._fatalException function was added!
2289     // this is probably pretty bad.  Nothing to do but report and exit.
2290     ReportException(env, error, message);
2291     exit(6);
2292   }
2293
2294   TryCatch fatal_try_catch;
2295
2296   // Do not call FatalException when _fatalException handler throws
2297   fatal_try_catch.SetVerbose(false);
2298
2299   // this will return true if the JS layer handled it, false otherwise
2300   Local<Value> caught =
2301       fatal_exception_function->Call(process_object, 1, &error);
2302
2303   if (fatal_try_catch.HasCaught()) {
2304     // the fatal exception function threw, so we must exit
2305     ReportException(env, fatal_try_catch);
2306     exit(7);
2307   }
2308
2309   if (false == caught->BooleanValue()) {
2310     ReportException(env, error, message);
2311     exit(1);
2312   }
2313 }
2314
2315
2316 void FatalException(Isolate* isolate, const TryCatch& try_catch) {
2317   HandleScope scope(isolate);
2318   // TODO(bajtos) do not call FatalException if try_catch is verbose
2319   // (requires V8 API to expose getter for try_catch.is_verbose_)
2320   FatalException(isolate, try_catch.Exception(), try_catch.Message());
2321 }
2322
2323
2324 void OnMessage(Local<Message> message, Local<Value> error) {
2325   // The current version of V8 sends messages for errors only
2326   // (thus `error` is always set).
2327   FatalException(Isolate::GetCurrent(), error, message);
2328 }
2329
2330
2331 static void Binding(const FunctionCallbackInfo<Value>& args) {
2332   Environment* env = Environment::GetCurrent(args);
2333
2334   Local<String> module = args[0]->ToString(env->isolate());
2335   node::Utf8Value module_v(env->isolate(), module);
2336
2337   Local<Object> cache = env->binding_cache_object();
2338   Local<Object> exports;
2339
2340   if (cache->Has(module)) {
2341     exports = cache->Get(module)->ToObject(env->isolate());
2342     args.GetReturnValue().Set(exports);
2343     return;
2344   }
2345
2346   // Append a string to process.moduleLoadList
2347   char buf[1024];
2348   snprintf(buf, sizeof(buf), "Binding %s", *module_v);
2349
2350   Local<Array> modules = env->module_load_list_array();
2351   uint32_t l = modules->Length();
2352   modules->Set(l, OneByteString(env->isolate(), buf));
2353
2354   node_module* mod = get_builtin_module(*module_v);
2355   if (mod != nullptr) {
2356     exports = Object::New(env->isolate());
2357     // Internal bindings don't have a "module" object, only exports.
2358     CHECK_EQ(mod->nm_register_func, nullptr);
2359     CHECK_NE(mod->nm_context_register_func, nullptr);
2360     Local<Value> unused = Undefined(env->isolate());
2361     mod->nm_context_register_func(exports, unused,
2362       env->context(), mod->nm_priv);
2363     cache->Set(module, exports);
2364   } else if (!strcmp(*module_v, "constants")) {
2365     exports = Object::New(env->isolate());
2366     DefineConstants(exports);
2367     cache->Set(module, exports);
2368   } else if (!strcmp(*module_v, "natives")) {
2369     exports = Object::New(env->isolate());
2370     DefineJavaScript(env, exports);
2371     cache->Set(module, exports);
2372   } else {
2373     char errmsg[1024];
2374     snprintf(errmsg,
2375              sizeof(errmsg),
2376              "No such module: %s",
2377              *module_v);
2378     return env->ThrowError(errmsg);
2379   }
2380
2381   args.GetReturnValue().Set(exports);
2382 }
2383
2384 static void LinkedBinding(const FunctionCallbackInfo<Value>& args) {
2385   Environment* env = Environment::GetCurrent(args.GetIsolate());
2386
2387   Local<String> module = args[0]->ToString(env->isolate());
2388
2389   Local<Object> cache = env->binding_cache_object();
2390   Local<Value> exports_v = cache->Get(module);
2391
2392   if (exports_v->IsObject())
2393     return args.GetReturnValue().Set(exports_v.As<Object>());
2394
2395   node::Utf8Value module_v(env->isolate(), module);
2396   node_module* mod = get_linked_module(*module_v);
2397
2398   if (mod == nullptr) {
2399     char errmsg[1024];
2400     snprintf(errmsg,
2401              sizeof(errmsg),
2402              "No such module was linked: %s",
2403              *module_v);
2404     return env->ThrowError(errmsg);
2405   }
2406
2407   Local<Object> exports = Object::New(env->isolate());
2408
2409   if (mod->nm_context_register_func != nullptr) {
2410     mod->nm_context_register_func(exports,
2411                                   module,
2412                                   env->context(),
2413                                   mod->nm_priv);
2414   } else if (mod->nm_register_func != nullptr) {
2415     mod->nm_register_func(exports, module, mod->nm_priv);
2416   } else {
2417     return env->ThrowError("Linked module has no declared entry point.");
2418   }
2419
2420   cache->Set(module, exports);
2421
2422   args.GetReturnValue().Set(exports);
2423 }
2424
2425 static void ProcessTitleGetter(Local<String> property,
2426                                const PropertyCallbackInfo<Value>& info) {
2427   char buffer[512];
2428   uv_get_process_title(buffer, sizeof(buffer));
2429   info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), buffer));
2430 }
2431
2432
2433 static void ProcessTitleSetter(Local<String> property,
2434                                Local<Value> value,
2435                                const PropertyCallbackInfo<void>& info) {
2436   node::Utf8Value title(info.GetIsolate(), value);
2437   // TODO(piscisaureus): protect with a lock
2438   uv_set_process_title(*title);
2439 }
2440
2441
2442 static void EnvGetter(Local<String> property,
2443                       const PropertyCallbackInfo<Value>& info) {
2444   Isolate* isolate = info.GetIsolate();
2445 #ifdef __POSIX__
2446   node::Utf8Value key(isolate, property);
2447   const char* val = getenv(*key);
2448   if (val) {
2449     return info.GetReturnValue().Set(String::NewFromUtf8(isolate, val));
2450   }
2451 #else  // _WIN32
2452   String::Value key(property);
2453   WCHAR buffer[32767];  // The maximum size allowed for environment variables.
2454   DWORD result = GetEnvironmentVariableW(reinterpret_cast<WCHAR*>(*key),
2455                                          buffer,
2456                                          ARRAY_SIZE(buffer));
2457   // If result >= sizeof buffer the buffer was too small. That should never
2458   // happen. If result == 0 and result != ERROR_SUCCESS the variable was not
2459   // not found.
2460   if ((result > 0 || GetLastError() == ERROR_SUCCESS) &&
2461       result < ARRAY_SIZE(buffer)) {
2462     const uint16_t* two_byte_buffer = reinterpret_cast<const uint16_t*>(buffer);
2463     Local<String> rc = String::NewFromTwoByte(isolate, two_byte_buffer);
2464     return info.GetReturnValue().Set(rc);
2465   }
2466 #endif
2467 }
2468
2469
2470 static void EnvSetter(Local<String> property,
2471                       Local<Value> value,
2472                       const PropertyCallbackInfo<Value>& info) {
2473 #ifdef __POSIX__
2474   node::Utf8Value key(info.GetIsolate(), property);
2475   node::Utf8Value val(info.GetIsolate(), value);
2476   setenv(*key, *val, 1);
2477 #else  // _WIN32
2478   String::Value key(property);
2479   String::Value val(value);
2480   WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key);
2481   // Environment variables that start with '=' are read-only.
2482   if (key_ptr[0] != L'=') {
2483     SetEnvironmentVariableW(key_ptr, reinterpret_cast<WCHAR*>(*val));
2484   }
2485 #endif
2486   // Whether it worked or not, always return rval.
2487   info.GetReturnValue().Set(value);
2488 }
2489
2490
2491 static void EnvQuery(Local<String> property,
2492                      const PropertyCallbackInfo<Integer>& info) {
2493   int32_t rc = -1;  // Not found unless proven otherwise.
2494 #ifdef __POSIX__
2495   node::Utf8Value key(info.GetIsolate(), property);
2496   if (getenv(*key))
2497     rc = 0;
2498 #else  // _WIN32
2499   String::Value key(property);
2500   WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key);
2501   if (GetEnvironmentVariableW(key_ptr, nullptr, 0) > 0 ||
2502       GetLastError() == ERROR_SUCCESS) {
2503     rc = 0;
2504     if (key_ptr[0] == L'=') {
2505       // Environment variables that start with '=' are hidden and read-only.
2506       rc = static_cast<int32_t>(v8::ReadOnly) |
2507            static_cast<int32_t>(v8::DontDelete) |
2508            static_cast<int32_t>(v8::DontEnum);
2509     }
2510   }
2511 #endif
2512   if (rc != -1)
2513     info.GetReturnValue().Set(rc);
2514 }
2515
2516
2517 static void EnvDeleter(Local<String> property,
2518                        const PropertyCallbackInfo<Boolean>& info) {
2519   bool rc = true;
2520 #ifdef __POSIX__
2521   node::Utf8Value key(info.GetIsolate(), property);
2522   rc = getenv(*key) != nullptr;
2523   if (rc)
2524     unsetenv(*key);
2525 #else
2526   String::Value key(property);
2527   WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key);
2528   if (key_ptr[0] == L'=' || !SetEnvironmentVariableW(key_ptr, nullptr)) {
2529     // Deletion failed. Return true if the key wasn't there in the first place,
2530     // false if it is still there.
2531     rc = GetEnvironmentVariableW(key_ptr, nullptr, 0) == 0 &&
2532          GetLastError() != ERROR_SUCCESS;
2533   }
2534 #endif
2535   info.GetReturnValue().Set(rc);
2536 }
2537
2538
2539 static void EnvEnumerator(const PropertyCallbackInfo<Array>& info) {
2540   Isolate* isolate = info.GetIsolate();
2541 #ifdef __POSIX__
2542   int size = 0;
2543   while (environ[size])
2544     size++;
2545
2546   Local<Array> envarr = Array::New(isolate, size);
2547
2548   for (int i = 0; i < size; ++i) {
2549     const char* var = environ[i];
2550     const char* s = strchr(var, '=');
2551     const int length = s ? s - var : strlen(var);
2552     Local<String> name = String::NewFromUtf8(isolate,
2553                                              var,
2554                                              String::kNormalString,
2555                                              length);
2556     envarr->Set(i, name);
2557   }
2558 #else  // _WIN32
2559   WCHAR* environment = GetEnvironmentStringsW();
2560   if (environment == nullptr)
2561     return;  // This should not happen.
2562   Local<Array> envarr = Array::New(isolate);
2563   WCHAR* p = environment;
2564   int i = 0;
2565   while (*p) {
2566     WCHAR *s;
2567     if (*p == L'=') {
2568       // If the key starts with '=' it is a hidden environment variable.
2569       p += wcslen(p) + 1;
2570       continue;
2571     } else {
2572       s = wcschr(p, L'=');
2573     }
2574     if (!s) {
2575       s = p + wcslen(p);
2576     }
2577     const uint16_t* two_byte_buffer = reinterpret_cast<const uint16_t*>(p);
2578     const size_t two_byte_buffer_len = s - p;
2579     Local<String> value = String::NewFromTwoByte(isolate,
2580                                                  two_byte_buffer,
2581                                                  String::kNormalString,
2582                                                  two_byte_buffer_len);
2583     envarr->Set(i++, value);
2584     p = s + wcslen(s) + 1;
2585   }
2586   FreeEnvironmentStringsW(environment);
2587 #endif
2588
2589   info.GetReturnValue().Set(envarr);
2590 }
2591
2592
2593 static Local<Object> GetFeatures(Environment* env) {
2594   EscapableHandleScope scope(env->isolate());
2595
2596   Local<Object> obj = Object::New(env->isolate());
2597 #if defined(DEBUG) && DEBUG
2598   Local<Value> debug = True(env->isolate());
2599 #else
2600   Local<Value> debug = False(env->isolate());
2601 #endif  // defined(DEBUG) && DEBUG
2602
2603   obj->Set(env->debug_string(), debug);
2604
2605   obj->Set(env->uv_string(), True(env->isolate()));
2606   // TODO(bnoordhuis) ping libuv
2607   obj->Set(env->ipv6_lc_string(), True(env->isolate()));
2608
2609 #ifdef OPENSSL_NPN_NEGOTIATED
2610   Local<Boolean> tls_npn = True(env->isolate());
2611 #else
2612   Local<Boolean> tls_npn = False(env->isolate());
2613 #endif
2614   obj->Set(env->tls_npn_string(), tls_npn);
2615
2616 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
2617   Local<Boolean> tls_sni = True(env->isolate());
2618 #else
2619   Local<Boolean> tls_sni = False(env->isolate());
2620 #endif
2621   obj->Set(env->tls_sni_string(), tls_sni);
2622
2623 #if !defined(OPENSSL_NO_TLSEXT) && defined(SSL_CTX_set_tlsext_status_cb)
2624   Local<Boolean> tls_ocsp = True(env->isolate());
2625 #else
2626   Local<Boolean> tls_ocsp = False(env->isolate());
2627 #endif  // !defined(OPENSSL_NO_TLSEXT) && defined(SSL_CTX_set_tlsext_status_cb)
2628   obj->Set(env->tls_ocsp_string(), tls_ocsp);
2629
2630   obj->Set(env->tls_string(),
2631            Boolean::New(env->isolate(),
2632                         get_builtin_module("crypto") != nullptr));
2633
2634   return scope.Escape(obj);
2635 }
2636
2637
2638 static void DebugPortGetter(Local<String> property,
2639                             const PropertyCallbackInfo<Value>& info) {
2640   info.GetReturnValue().Set(debug_port);
2641 }
2642
2643
2644 static void DebugPortSetter(Local<String> property,
2645                             Local<Value> value,
2646                             const PropertyCallbackInfo<void>& info) {
2647   debug_port = value->Int32Value();
2648 }
2649
2650
2651 static void DebugProcess(const FunctionCallbackInfo<Value>& args);
2652 static void DebugPause(const FunctionCallbackInfo<Value>& args);
2653 static void DebugEnd(const FunctionCallbackInfo<Value>& args);
2654
2655
2656 void NeedImmediateCallbackGetter(Local<String> property,
2657                                  const PropertyCallbackInfo<Value>& info) {
2658   Environment* env = Environment::GetCurrent(info);
2659   const uv_check_t* immediate_check_handle = env->immediate_check_handle();
2660   bool active = uv_is_active(
2661       reinterpret_cast<const uv_handle_t*>(immediate_check_handle));
2662   info.GetReturnValue().Set(active);
2663 }
2664
2665
2666 static void NeedImmediateCallbackSetter(
2667     Local<String> property,
2668     Local<Value> value,
2669     const PropertyCallbackInfo<void>& info) {
2670   Environment* env = Environment::GetCurrent(info);
2671
2672   uv_check_t* immediate_check_handle = env->immediate_check_handle();
2673   bool active = uv_is_active(
2674       reinterpret_cast<const uv_handle_t*>(immediate_check_handle));
2675
2676   if (active == value->BooleanValue())
2677     return;
2678
2679   uv_idle_t* immediate_idle_handle = env->immediate_idle_handle();
2680
2681   if (active) {
2682     uv_check_stop(immediate_check_handle);
2683     uv_idle_stop(immediate_idle_handle);
2684   } else {
2685     uv_check_start(immediate_check_handle, CheckImmediate);
2686     // Idle handle is needed only to stop the event loop from blocking in poll.
2687     uv_idle_start(immediate_idle_handle, IdleImmediateDummy);
2688   }
2689 }
2690
2691
2692 void SetIdle(uv_prepare_t* handle) {
2693   Environment* env = Environment::from_idle_prepare_handle(handle);
2694   env->isolate()->GetCpuProfiler()->SetIdle(true);
2695 }
2696
2697
2698 void ClearIdle(uv_check_t* handle) {
2699   Environment* env = Environment::from_idle_check_handle(handle);
2700   env->isolate()->GetCpuProfiler()->SetIdle(false);
2701 }
2702
2703
2704 void StartProfilerIdleNotifier(Environment* env) {
2705   uv_prepare_start(env->idle_prepare_handle(), SetIdle);
2706   uv_check_start(env->idle_check_handle(), ClearIdle);
2707 }
2708
2709
2710 void StopProfilerIdleNotifier(Environment* env) {
2711   uv_prepare_stop(env->idle_prepare_handle());
2712   uv_check_stop(env->idle_check_handle());
2713 }
2714
2715
2716 void StartProfilerIdleNotifier(const FunctionCallbackInfo<Value>& args) {
2717   Environment* env = Environment::GetCurrent(args);
2718   StartProfilerIdleNotifier(env);
2719 }
2720
2721
2722 void StopProfilerIdleNotifier(const FunctionCallbackInfo<Value>& args) {
2723   Environment* env = Environment::GetCurrent(args);
2724   StopProfilerIdleNotifier(env);
2725 }
2726
2727
2728 #define READONLY_PROPERTY(obj, str, var)                                      \
2729   do {                                                                        \
2730     obj->ForceSet(OneByteString(env->isolate(), str), var, v8::ReadOnly);     \
2731   } while (0)
2732
2733 #define READONLY_DONT_ENUM_PROPERTY(obj, str, var)                            \
2734   do {                                                                        \
2735     obj->ForceSet(OneByteString(env->isolate(), str),                         \
2736                   var,                                                        \
2737                   static_cast<v8::PropertyAttribute>(v8::ReadOnly |           \
2738                                                      v8::DontEnum));          \
2739   } while (0)
2740
2741
2742 void SetupProcessObject(Environment* env,
2743                         int argc,
2744                         const char* const* argv,
2745                         int exec_argc,
2746                         const char* const* exec_argv) {
2747   HandleScope scope(env->isolate());
2748
2749   Local<Object> process = env->process_object();
2750
2751   process->SetAccessor(env->title_string(),
2752                        ProcessTitleGetter,
2753                        ProcessTitleSetter,
2754                        env->as_external());
2755
2756   // process.version
2757   READONLY_PROPERTY(process,
2758                     "version",
2759                     FIXED_ONE_BYTE_STRING(env->isolate(), NODE_VERSION));
2760
2761   // process.moduleLoadList
2762   READONLY_PROPERTY(process,
2763                     "moduleLoadList",
2764                     env->module_load_list_array());
2765
2766   // process.versions
2767   Local<Object> versions = Object::New(env->isolate());
2768   READONLY_PROPERTY(process, "versions", versions);
2769
2770   const char http_parser_version[] = NODE_STRINGIFY(HTTP_PARSER_VERSION_MAJOR)
2771                                      "."
2772                                      NODE_STRINGIFY(HTTP_PARSER_VERSION_MINOR)
2773                                      "."
2774                                      NODE_STRINGIFY(HTTP_PARSER_VERSION_PATCH);
2775   READONLY_PROPERTY(versions,
2776                     "http_parser",
2777                     FIXED_ONE_BYTE_STRING(env->isolate(), http_parser_version));
2778
2779   // +1 to get rid of the leading 'v'
2780   READONLY_PROPERTY(versions,
2781                     "node",
2782                     OneByteString(env->isolate(), NODE_VERSION + 1));
2783   READONLY_PROPERTY(versions,
2784                     "v8",
2785                     OneByteString(env->isolate(), V8::GetVersion()));
2786   READONLY_PROPERTY(versions,
2787                     "uv",
2788                     OneByteString(env->isolate(), uv_version_string()));
2789   READONLY_PROPERTY(versions,
2790                     "zlib",
2791                     FIXED_ONE_BYTE_STRING(env->isolate(), ZLIB_VERSION));
2792   READONLY_PROPERTY(versions,
2793                     "ares",
2794                     FIXED_ONE_BYTE_STRING(env->isolate(), ARES_VERSION_STR));
2795
2796 #if defined(NODE_HAVE_I18N_SUPPORT) && defined(U_ICU_VERSION)
2797   READONLY_PROPERTY(versions,
2798                     "icu",
2799                     OneByteString(env->isolate(), U_ICU_VERSION));
2800 #endif
2801
2802   const char node_modules_version[] = NODE_STRINGIFY(NODE_MODULE_VERSION);
2803   READONLY_PROPERTY(
2804       versions,
2805       "modules",
2806       FIXED_ONE_BYTE_STRING(env->isolate(), node_modules_version));
2807
2808   // process._promiseRejectEvent
2809   Local<Object> promiseRejectEvent = Object::New(env->isolate());
2810   READONLY_DONT_ENUM_PROPERTY(process,
2811                               "_promiseRejectEvent",
2812                               promiseRejectEvent);
2813   READONLY_PROPERTY(promiseRejectEvent,
2814                     "unhandled",
2815                     Integer::New(env->isolate(),
2816                                  v8::kPromiseRejectWithNoHandler));
2817   READONLY_PROPERTY(promiseRejectEvent,
2818                     "handled",
2819                     Integer::New(env->isolate(),
2820                                  v8::kPromiseHandlerAddedAfterReject));
2821
2822 #if HAVE_OPENSSL
2823   // Stupid code to slice out the version string.
2824   {  // NOLINT(whitespace/braces)
2825     size_t i, j, k;
2826     int c;
2827     for (i = j = 0, k = sizeof(OPENSSL_VERSION_TEXT) - 1; i < k; ++i) {
2828       c = OPENSSL_VERSION_TEXT[i];
2829       if ('0' <= c && c <= '9') {
2830         for (j = i + 1; j < k; ++j) {
2831           c = OPENSSL_VERSION_TEXT[j];
2832           if (c == ' ')
2833             break;
2834         }
2835         break;
2836       }
2837     }
2838     READONLY_PROPERTY(
2839         versions,
2840         "openssl",
2841         OneByteString(env->isolate(), &OPENSSL_VERSION_TEXT[i], j - i));
2842   }
2843 #endif
2844
2845   // process.arch
2846   READONLY_PROPERTY(process, "arch", OneByteString(env->isolate(), NODE_ARCH));
2847
2848   // process.platform
2849   READONLY_PROPERTY(process,
2850                     "platform",
2851                     OneByteString(env->isolate(), NODE_PLATFORM));
2852
2853   // process.release
2854   Local<Object> release = Object::New(env->isolate());
2855   READONLY_PROPERTY(process, "release", release);
2856   READONLY_PROPERTY(release, "name", OneByteString(env->isolate(), "node"));
2857
2858 #if NODE_VERSION_IS_LTS
2859   READONLY_PROPERTY(release, "lts",
2860                     OneByteString(env->isolate(), NODE_VERSION_LTS_CODENAME));
2861 #endif
2862
2863 // if this is a release build and no explicit base has been set
2864 // substitute the standard release download URL
2865 #ifndef NODE_RELEASE_URLBASE
2866 # if NODE_VERSION_IS_RELEASE
2867 #  define NODE_RELEASE_URLBASE "https://nodejs.org/download/release/"
2868 # endif
2869 #endif
2870
2871 #if defined(NODE_RELEASE_URLBASE)
2872 #  define NODE_RELEASE_URLPFX NODE_RELEASE_URLBASE "v" NODE_VERSION_STRING "/"
2873 #  define NODE_RELEASE_URLFPFX NODE_RELEASE_URLPFX "node-v" NODE_VERSION_STRING
2874
2875   READONLY_PROPERTY(release,
2876                     "sourceUrl",
2877                     OneByteString(env->isolate(),
2878                     NODE_RELEASE_URLFPFX ".tar.gz"));
2879   READONLY_PROPERTY(release,
2880                     "headersUrl",
2881                     OneByteString(env->isolate(),
2882                     NODE_RELEASE_URLFPFX "-headers.tar.gz"));
2883 #  ifdef _WIN32
2884   READONLY_PROPERTY(release,
2885                     "libUrl",
2886                     OneByteString(env->isolate(),
2887                     strcmp(NODE_ARCH, "ia32") ? NODE_RELEASE_URLPFX "win-"
2888                                                 NODE_ARCH "/node.lib"
2889                                               : NODE_RELEASE_URLPFX
2890                                                 "win-x86/node.lib"));
2891 #  endif
2892 #endif
2893
2894   // process.argv
2895   Local<Array> arguments = Array::New(env->isolate(), argc);
2896   for (int i = 0; i < argc; ++i) {
2897     arguments->Set(i, String::NewFromUtf8(env->isolate(), argv[i]));
2898   }
2899   process->Set(env->argv_string(), arguments);
2900
2901   // process.execArgv
2902   Local<Array> exec_arguments = Array::New(env->isolate(), exec_argc);
2903   for (int i = 0; i < exec_argc; ++i) {
2904     exec_arguments->Set(i, String::NewFromUtf8(env->isolate(), exec_argv[i]));
2905   }
2906   process->Set(env->exec_argv_string(), exec_arguments);
2907
2908   // create process.env
2909   Local<ObjectTemplate> process_env_template =
2910       ObjectTemplate::New(env->isolate());
2911   process_env_template->SetNamedPropertyHandler(EnvGetter,
2912                                                 EnvSetter,
2913                                                 EnvQuery,
2914                                                 EnvDeleter,
2915                                                 EnvEnumerator,
2916                                                 env->as_external());
2917   Local<Object> process_env = process_env_template->NewInstance();
2918   process->Set(env->env_string(), process_env);
2919
2920   READONLY_PROPERTY(process, "pid", Integer::New(env->isolate(), getpid()));
2921   READONLY_PROPERTY(process, "features", GetFeatures(env));
2922   process->SetAccessor(env->need_imm_cb_string(),
2923                        NeedImmediateCallbackGetter,
2924                        NeedImmediateCallbackSetter,
2925                        env->as_external());
2926
2927   // -e, --eval
2928   if (eval_string) {
2929     READONLY_PROPERTY(process,
2930                       "_eval",
2931                       String::NewFromUtf8(env->isolate(), eval_string));
2932   }
2933
2934   // -p, --print
2935   if (print_eval) {
2936     READONLY_PROPERTY(process, "_print_eval", True(env->isolate()));
2937   }
2938
2939   // -c, --check
2940   if (syntax_check_only) {
2941     READONLY_PROPERTY(process, "_syntax_check_only", True(env->isolate()));
2942   }
2943
2944   // -i, --interactive
2945   if (force_repl) {
2946     READONLY_PROPERTY(process, "_forceRepl", True(env->isolate()));
2947   }
2948
2949   if (preload_module_count) {
2950     CHECK(preload_modules);
2951     Local<Array> array = Array::New(env->isolate());
2952     for (unsigned int i = 0; i < preload_module_count; ++i) {
2953       Local<String> module = String::NewFromUtf8(env->isolate(),
2954                                                  preload_modules[i]);
2955       array->Set(i, module);
2956     }
2957     READONLY_PROPERTY(process,
2958                       "_preload_modules",
2959                       array);
2960
2961     delete[] preload_modules;
2962     preload_modules = nullptr;
2963     preload_module_count = 0;
2964   }
2965
2966   // --no-deprecation
2967   if (no_deprecation) {
2968     READONLY_PROPERTY(process, "noDeprecation", True(env->isolate()));
2969   }
2970
2971   // --throw-deprecation
2972   if (throw_deprecation) {
2973     READONLY_PROPERTY(process, "throwDeprecation", True(env->isolate()));
2974   }
2975
2976   // --prof-process
2977   if (prof_process) {
2978     READONLY_PROPERTY(process, "profProcess", True(env->isolate()));
2979   }
2980
2981   // --trace-deprecation
2982   if (trace_deprecation) {
2983     READONLY_PROPERTY(process, "traceDeprecation", True(env->isolate()));
2984   }
2985
2986   // --security-revert flags
2987 #define V(code, _, __)                                                        \
2988   do {                                                                        \
2989     if (IsReverted(REVERT_ ## code)) {                                        \
2990       READONLY_PROPERTY(process, "REVERT_" #code, True(env->isolate()));      \
2991     }                                                                         \
2992   } while (0);
2993   REVERSIONS(V)
2994 #undef V
2995
2996   size_t exec_path_len = 2 * PATH_MAX;
2997   char* exec_path = new char[exec_path_len];
2998   Local<String> exec_path_value;
2999   if (uv_exepath(exec_path, &exec_path_len) == 0) {
3000     exec_path_value = String::NewFromUtf8(env->isolate(),
3001                                           exec_path,
3002                                           String::kNormalString,
3003                                           exec_path_len);
3004   } else {
3005     exec_path_value = String::NewFromUtf8(env->isolate(), argv[0]);
3006   }
3007   process->Set(env->exec_path_string(), exec_path_value);
3008   delete[] exec_path;
3009
3010   process->SetAccessor(env->debug_port_string(),
3011                        DebugPortGetter,
3012                        DebugPortSetter,
3013                        env->as_external());
3014
3015   // define various internal methods
3016   env->SetMethod(process,
3017                  "_startProfilerIdleNotifier",
3018                  StartProfilerIdleNotifier);
3019   env->SetMethod(process,
3020                  "_stopProfilerIdleNotifier",
3021                  StopProfilerIdleNotifier);
3022   env->SetMethod(process, "_getActiveRequests", GetActiveRequests);
3023   env->SetMethod(process, "_getActiveHandles", GetActiveHandles);
3024   env->SetMethod(process, "reallyExit", Exit);
3025   env->SetMethod(process, "abort", Abort);
3026   env->SetMethod(process, "chdir", Chdir);
3027   env->SetMethod(process, "cwd", Cwd);
3028
3029   env->SetMethod(process, "umask", Umask);
3030
3031 #if defined(__POSIX__) && !defined(__ANDROID__)
3032   env->SetMethod(process, "getuid", GetUid);
3033   env->SetMethod(process, "geteuid", GetEUid);
3034   env->SetMethod(process, "setuid", SetUid);
3035   env->SetMethod(process, "seteuid", SetEUid);
3036
3037   env->SetMethod(process, "setgid", SetGid);
3038   env->SetMethod(process, "setegid", SetEGid);
3039   env->SetMethod(process, "getgid", GetGid);
3040   env->SetMethod(process, "getegid", GetEGid);
3041
3042   env->SetMethod(process, "getgroups", GetGroups);
3043   env->SetMethod(process, "setgroups", SetGroups);
3044   env->SetMethod(process, "initgroups", InitGroups);
3045 #endif  // __POSIX__ && !defined(__ANDROID__)
3046
3047   env->SetMethod(process, "_kill", Kill);
3048
3049   env->SetMethod(process, "_debugProcess", DebugProcess);
3050   env->SetMethod(process, "_debugPause", DebugPause);
3051   env->SetMethod(process, "_debugEnd", DebugEnd);
3052
3053   env->SetMethod(process, "hrtime", Hrtime);
3054
3055   env->SetMethod(process, "dlopen", DLOpen);
3056
3057   env->SetMethod(process, "uptime", Uptime);
3058   env->SetMethod(process, "memoryUsage", MemoryUsage);
3059
3060   env->SetMethod(process, "binding", Binding);
3061   env->SetMethod(process, "_linkedBinding", LinkedBinding);
3062
3063   env->SetMethod(process, "_setupNextTick", SetupNextTick);
3064   env->SetMethod(process, "_setupPromises", SetupPromises);
3065   env->SetMethod(process, "_setupDomainUse", SetupDomainUse);
3066
3067   // pre-set _events object for faster emit checks
3068   process->Set(env->events_string(), Object::New(env->isolate()));
3069 }
3070
3071
3072 #undef READONLY_PROPERTY
3073
3074
3075 static void AtExit() {
3076   uv_tty_reset_mode();
3077 }
3078
3079
3080 static void SignalExit(int signo) {
3081   uv_tty_reset_mode();
3082 #ifdef __FreeBSD__
3083   // FreeBSD has a nasty bug, see RegisterSignalHandler for details
3084   struct sigaction sa;
3085   memset(&sa, 0, sizeof(sa));
3086   sa.sa_handler = SIG_DFL;
3087   CHECK_EQ(sigaction(signo, &sa, nullptr), 0);
3088 #endif
3089   raise(signo);
3090 }
3091
3092
3093 // Most of the time, it's best to use `console.error` to write
3094 // to the process.stderr stream.  However, in some cases, such as
3095 // when debugging the stream.Writable class or the process.nextTick
3096 // function, it is useful to bypass JavaScript entirely.
3097 static void RawDebug(const FunctionCallbackInfo<Value>& args) {
3098   CHECK(args.Length() == 1 && args[0]->IsString() &&
3099         "must be called with a single string");
3100   node::Utf8Value message(args.GetIsolate(), args[0]);
3101   PrintErrorString("%s\n", *message);
3102   fflush(stderr);
3103 }
3104
3105
3106 void LoadEnvironment(Environment* env) {
3107   HandleScope handle_scope(env->isolate());
3108
3109   env->isolate()->SetFatalErrorHandler(node::OnFatalError);
3110   env->isolate()->AddMessageListener(OnMessage);
3111
3112   // Compile, execute the src/node.js file. (Which was included as static C
3113   // string in node_natives.h. 'native_node' is the string containing that
3114   // source code.)
3115
3116   // The node.js file returns a function 'f'
3117   atexit(AtExit);
3118
3119   TryCatch try_catch;
3120
3121   // Disable verbose mode to stop FatalException() handler from trying
3122   // to handle the exception. Errors this early in the start-up phase
3123   // are not safe to ignore.
3124   try_catch.SetVerbose(false);
3125
3126   Local<String> script_name = FIXED_ONE_BYTE_STRING(env->isolate(), "node.js");
3127   Local<Value> f_value = ExecuteString(env, MainSource(env), script_name);
3128   if (try_catch.HasCaught())  {
3129     ReportException(env, try_catch);
3130     exit(10);
3131   }
3132   CHECK(f_value->IsFunction());
3133   Local<Function> f = Local<Function>::Cast(f_value);
3134
3135   // Now we call 'f' with the 'process' variable that we've built up with
3136   // all our bindings. Inside node.js we'll take care of assigning things to
3137   // their places.
3138
3139   // We start the process this way in order to be more modular. Developers
3140   // who do not like how 'src/node.js' setups the module system but do like
3141   // Node's I/O bindings may want to replace 'f' with their own function.
3142
3143   // Add a reference to the global object
3144   Local<Object> global = env->context()->Global();
3145
3146 #if defined HAVE_DTRACE || defined HAVE_ETW
3147   InitDTrace(env, global);
3148 #endif
3149
3150 #if defined HAVE_LTTNG
3151   InitLTTNG(env, global);
3152 #endif
3153
3154 #if defined HAVE_PERFCTR
3155   InitPerfCounters(env, global);
3156 #endif
3157
3158   // Enable handling of uncaught exceptions
3159   // (FatalException(), break on uncaught exception in debugger)
3160   //
3161   // This is not strictly necessary since it's almost impossible
3162   // to attach the debugger fast enought to break on exception
3163   // thrown during process startup.
3164   try_catch.SetVerbose(true);
3165
3166   env->SetMethod(env->process_object(), "_rawDebug", RawDebug);
3167
3168   Local<Value> arg = env->process_object();
3169   f->Call(global, 1, &arg);
3170 }
3171
3172 static void PrintHelp();
3173
3174 static bool ParseDebugOpt(const char* arg) {
3175   const char* port = nullptr;
3176
3177   if (!strcmp(arg, "--debug")) {
3178     use_debug_agent = true;
3179   } else if (!strncmp(arg, "--debug=", sizeof("--debug=") - 1)) {
3180     use_debug_agent = true;
3181     port = arg + sizeof("--debug=") - 1;
3182   } else if (!strcmp(arg, "--debug-brk")) {
3183     use_debug_agent = true;
3184     debug_wait_connect = true;
3185   } else if (!strncmp(arg, "--debug-brk=", sizeof("--debug-brk=") - 1)) {
3186     use_debug_agent = true;
3187     debug_wait_connect = true;
3188     port = arg + sizeof("--debug-brk=") - 1;
3189   } else if (!strncmp(arg, "--debug-port=", sizeof("--debug-port=") - 1)) {
3190     port = arg + sizeof("--debug-port=") - 1;
3191   } else {
3192     return false;
3193   }
3194
3195   if (port != nullptr) {
3196     debug_port = atoi(port);
3197     if (debug_port < 1024 || debug_port > 65535) {
3198       fprintf(stderr, "Debug port must be in range 1024 to 65535.\n");
3199       PrintHelp();
3200       exit(12);
3201     }
3202   }
3203
3204   return true;
3205 }
3206
3207 static void PrintHelp() {
3208   // XXX: If you add an option here, please also add it to doc/node.1 and
3209   // doc/api/cli.markdown
3210   printf("Usage: node [options] [ -e script | script.js ] [arguments] \n"
3211          "       node debug script.js [arguments] \n"
3212          "\n"
3213          "Options:\n"
3214          "  -v, --version         print Node.js version\n"
3215          "  -e, --eval script     evaluate script\n"
3216          "  -p, --print           evaluate script and print result\n"
3217          "  -c, --check           syntax check script without executing\n"
3218          "  -i, --interactive     always enter the REPL even if stdin\n"
3219          "                        does not appear to be a terminal\n"
3220          "  -r, --require         module to preload (option can be repeated)\n"
3221          "  --no-deprecation      silence deprecation warnings\n"
3222          "  --trace-deprecation   show stack traces on deprecations\n"
3223          "  --throw-deprecation   throw an exception anytime a deprecated "
3224          "function is used\n"
3225          "  --trace-sync-io       show stack trace when use of sync IO\n"
3226          "                        is detected after the first tick\n"
3227          "  --track-heap-objects  track heap object allocations for heap "
3228          "snapshots\n"
3229          "  --prof-process        process v8 profiler output generated\n"
3230          "                        using --prof\n"
3231          "  --v8-options          print v8 command line options\n"
3232 #if HAVE_OPENSSL
3233          "  --tls-cipher-list=val use an alternative default TLS cipher list\n"
3234 #endif
3235 #if defined(NODE_HAVE_I18N_SUPPORT)
3236          "  --icu-data-dir=dir    set ICU data load path to dir\n"
3237          "                        (overrides NODE_ICU_DATA)\n"
3238 #if !defined(NODE_HAVE_SMALL_ICU)
3239          "                        note: linked-in ICU data is\n"
3240          "                        present.\n"
3241 #endif
3242 #endif
3243          "\n"
3244          "Environment variables:\n"
3245 #ifdef _WIN32
3246          "NODE_PATH               ';'-separated list of directories\n"
3247 #else
3248          "NODE_PATH               ':'-separated list of directories\n"
3249 #endif
3250          "                        prefixed to the module search path.\n"
3251          "NODE_DISABLE_COLORS     set to 1 to disable colors in the REPL\n"
3252 #if defined(NODE_HAVE_I18N_SUPPORT)
3253          "NODE_ICU_DATA           data path for ICU (Intl object) data\n"
3254 #if !defined(NODE_HAVE_SMALL_ICU)
3255          "                        (will extend linked-in data)\n"
3256 #endif
3257 #endif
3258          "NODE_REPL_HISTORY       path to the persistent REPL history file\n"
3259          "\n"
3260          "Documentation can be found at https://nodejs.org/\n");
3261 }
3262
3263
3264 // Parse command line arguments.
3265 //
3266 // argv is modified in place. exec_argv and v8_argv are out arguments that
3267 // ParseArgs() allocates memory for and stores a pointer to the output
3268 // vector in.  The caller should free them with delete[].
3269 //
3270 // On exit:
3271 //
3272 //  * argv contains the arguments with node and V8 options filtered out.
3273 //  * exec_argv contains both node and V8 options and nothing else.
3274 //  * v8_argv contains argv[0] plus any V8 options
3275 static void ParseArgs(int* argc,
3276                       const char** argv,
3277                       int* exec_argc,
3278                       const char*** exec_argv,
3279                       int* v8_argc,
3280                       const char*** v8_argv) {
3281   const unsigned int nargs = static_cast<unsigned int>(*argc);
3282   const char** new_exec_argv = new const char*[nargs];
3283   const char** new_v8_argv = new const char*[nargs];
3284   const char** new_argv = new const char*[nargs];
3285   const char** local_preload_modules = new const char*[nargs];
3286
3287   for (unsigned int i = 0; i < nargs; ++i) {
3288     new_exec_argv[i] = nullptr;
3289     new_v8_argv[i] = nullptr;
3290     new_argv[i] = nullptr;
3291     local_preload_modules[i] = nullptr;
3292   }
3293
3294   // exec_argv starts with the first option, the other two start with argv[0].
3295   unsigned int new_exec_argc = 0;
3296   unsigned int new_v8_argc = 1;
3297   unsigned int new_argc = 1;
3298   new_v8_argv[0] = argv[0];
3299   new_argv[0] = argv[0];
3300
3301   unsigned int index = 1;
3302   bool short_circuit = false;
3303   while (index < nargs && argv[index][0] == '-' && !short_circuit) {
3304     const char* const arg = argv[index];
3305     unsigned int args_consumed = 1;
3306
3307     if (ParseDebugOpt(arg)) {
3308       // Done, consumed by ParseDebugOpt().
3309     } else if (strcmp(arg, "--version") == 0 || strcmp(arg, "-v") == 0) {
3310       printf("%s\n", NODE_VERSION);
3311       exit(0);
3312     } else if (strcmp(arg, "--help") == 0 || strcmp(arg, "-h") == 0) {
3313       PrintHelp();
3314       exit(0);
3315     } else if (strcmp(arg, "--eval") == 0 ||
3316                strcmp(arg, "-e") == 0 ||
3317                strcmp(arg, "--print") == 0 ||
3318                strcmp(arg, "-pe") == 0 ||
3319                strcmp(arg, "-p") == 0) {
3320       bool is_eval = strchr(arg, 'e') != nullptr;
3321       bool is_print = strchr(arg, 'p') != nullptr;
3322       print_eval = print_eval || is_print;
3323       // --eval, -e and -pe always require an argument.
3324       if (is_eval == true) {
3325         args_consumed += 1;
3326         eval_string = argv[index + 1];
3327         if (eval_string == nullptr) {
3328           fprintf(stderr, "%s: %s requires an argument\n", argv[0], arg);
3329           exit(9);
3330         }
3331       } else if ((index + 1 < nargs) &&
3332                  argv[index + 1] != nullptr &&
3333                  argv[index + 1][0] != '-') {
3334         args_consumed += 1;
3335         eval_string = argv[index + 1];
3336         if (strncmp(eval_string, "\\-", 2) == 0) {
3337           // Starts with "\\-": escaped expression, drop the backslash.
3338           eval_string += 1;
3339         }
3340       }
3341     } else if (strcmp(arg, "--require") == 0 ||
3342                strcmp(arg, "-r") == 0) {
3343       const char* module = argv[index + 1];
3344       if (module == nullptr) {
3345         fprintf(stderr, "%s: %s requires an argument\n", argv[0], arg);
3346         exit(9);
3347       }
3348       args_consumed += 1;
3349       local_preload_modules[preload_module_count++] = module;
3350     } else if (strcmp(arg, "--check") == 0 || strcmp(arg, "-c") == 0) {
3351       syntax_check_only = true;
3352     } else if (strcmp(arg, "--interactive") == 0 || strcmp(arg, "-i") == 0) {
3353       force_repl = true;
3354     } else if (strcmp(arg, "--no-deprecation") == 0) {
3355       no_deprecation = true;
3356     } else if (strcmp(arg, "--trace-deprecation") == 0) {
3357       trace_deprecation = true;
3358     } else if (strcmp(arg, "--trace-sync-io") == 0) {
3359       trace_sync_io = true;
3360     } else if (strcmp(arg, "--track-heap-objects") == 0) {
3361       track_heap_objects = true;
3362     } else if (strcmp(arg, "--throw-deprecation") == 0) {
3363       throw_deprecation = true;
3364     } else if (strncmp(arg, "--security-revert=", 18) == 0) {
3365       const char* cve = arg + 18;
3366       Revert(cve);
3367     } else if (strcmp(arg, "--prof-process") == 0) {
3368       prof_process = true;
3369       short_circuit = true;
3370     } else if (strcmp(arg, "--v8-options") == 0) {
3371       new_v8_argv[new_v8_argc] = "--help";
3372       new_v8_argc += 1;
3373 #if HAVE_OPENSSL
3374     } else if (strncmp(arg, "--tls-cipher-list=", 18) == 0) {
3375       default_cipher_list = arg + 18;
3376 #endif
3377 #if defined(NODE_HAVE_I18N_SUPPORT)
3378     } else if (strncmp(arg, "--icu-data-dir=", 15) == 0) {
3379       icu_data_dir = arg + 15;
3380 #endif
3381     } else if (strcmp(arg, "--expose-internals") == 0 ||
3382                strcmp(arg, "--expose_internals") == 0) {
3383       // consumed in js
3384     } else {
3385       // V8 option.  Pass through as-is.
3386       new_v8_argv[new_v8_argc] = arg;
3387       new_v8_argc += 1;
3388     }
3389
3390     memcpy(new_exec_argv + new_exec_argc,
3391            argv + index,
3392            args_consumed * sizeof(*argv));
3393
3394     new_exec_argc += args_consumed;
3395     index += args_consumed;
3396   }
3397
3398   // Copy remaining arguments.
3399   const unsigned int args_left = nargs - index;
3400   memcpy(new_argv + new_argc, argv + index, args_left * sizeof(*argv));
3401   new_argc += args_left;
3402
3403   *exec_argc = new_exec_argc;
3404   *exec_argv = new_exec_argv;
3405   *v8_argc = new_v8_argc;
3406   *v8_argv = new_v8_argv;
3407
3408   // Copy new_argv over argv and update argc.
3409   memcpy(argv, new_argv, new_argc * sizeof(*argv));
3410   delete[] new_argv;
3411   *argc = static_cast<int>(new_argc);
3412
3413   // Copy the preload_modules from the local array to an appropriately sized
3414   // global array.
3415   if (preload_module_count > 0) {
3416     CHECK(!preload_modules);
3417     preload_modules = new const char*[preload_module_count];
3418     memcpy(preload_modules, local_preload_modules,
3419            preload_module_count * sizeof(*preload_modules));
3420   }
3421   delete[] local_preload_modules;
3422 }
3423
3424
3425 // Called from V8 Debug Agent TCP thread.
3426 static void DispatchMessagesDebugAgentCallback(Environment* env) {
3427   // TODO(indutny): move async handle to environment
3428   uv_async_send(&dispatch_debug_messages_async);
3429 }
3430
3431
3432 static void StartDebug(Environment* env, bool wait) {
3433   CHECK(!debugger_running);
3434
3435   env->debugger_agent()->set_dispatch_handler(
3436         DispatchMessagesDebugAgentCallback);
3437   debugger_running = env->debugger_agent()->Start(debug_port, wait);
3438   if (debugger_running == false) {
3439     fprintf(stderr, "Starting debugger on port %d failed\n", debug_port);
3440     fflush(stderr);
3441     return;
3442   }
3443 }
3444
3445
3446 // Called from the main thread.
3447 static void EnableDebug(Environment* env) {
3448   CHECK(debugger_running);
3449
3450   // Send message to enable debug in workers
3451   HandleScope handle_scope(env->isolate());
3452
3453   Local<Object> message = Object::New(env->isolate());
3454   message->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "cmd"),
3455                FIXED_ONE_BYTE_STRING(env->isolate(), "NODE_DEBUG_ENABLED"));
3456   Local<Value> argv[] = {
3457     FIXED_ONE_BYTE_STRING(env->isolate(), "internalMessage"),
3458     message
3459   };
3460   MakeCallback(env, env->process_object(), "emit", ARRAY_SIZE(argv), argv);
3461
3462   // Enabled debugger, possibly making it wait on a semaphore
3463   env->debugger_agent()->Enable();
3464 }
3465
3466
3467 // Called from an arbitrary thread.
3468 static void TryStartDebugger() {
3469   // Call only async signal-safe functions here!  Don't retry the exchange,
3470   // it will deadlock when the thread is interrupted inside a critical section.
3471   if (auto isolate = node_isolate.exchange(nullptr)) {
3472     v8::Debug::DebugBreak(isolate);
3473     uv_async_send(&dispatch_debug_messages_async);
3474     CHECK_EQ(nullptr, node_isolate.exchange(isolate));
3475   }
3476 }
3477
3478
3479 // Called from the main thread.
3480 static void DispatchDebugMessagesAsyncCallback(uv_async_t* handle) {
3481   // Synchronize with signal handler, see TryStartDebugger.
3482   Isolate* isolate;
3483   do {
3484     isolate = node_isolate.exchange(nullptr);
3485   } while (isolate == nullptr);
3486
3487   if (debugger_running == false) {
3488     fprintf(stderr, "Starting debugger agent.\n");
3489
3490     HandleScope scope(isolate);
3491     Environment* env = Environment::GetCurrent(isolate);
3492     Context::Scope context_scope(env->context());
3493
3494     StartDebug(env, false);
3495     EnableDebug(env);
3496   }
3497
3498   Isolate::Scope isolate_scope(isolate);
3499   v8::Debug::ProcessDebugMessages();
3500   CHECK_EQ(nullptr, node_isolate.exchange(isolate));
3501 }
3502
3503
3504 #ifdef __POSIX__
3505 static void EnableDebugSignalHandler(int signo) {
3506   TryStartDebugger();
3507 }
3508
3509
3510 static void RegisterSignalHandler(int signal,
3511                                   void (*handler)(int signal),
3512                                   bool reset_handler = false) {
3513   struct sigaction sa;
3514   memset(&sa, 0, sizeof(sa));
3515   sa.sa_handler = handler;
3516 #ifndef __FreeBSD__
3517   // FreeBSD has a nasty bug with SA_RESETHAND reseting the SA_SIGINFO, that is
3518   // in turn set for a libthr wrapper. This leads to a crash.
3519   // Work around the issue by manually setting SIG_DFL in the signal handler
3520   sa.sa_flags = reset_handler ? SA_RESETHAND : 0;
3521 #endif
3522   sigfillset(&sa.sa_mask);
3523   CHECK_EQ(sigaction(signal, &sa, nullptr), 0);
3524 }
3525
3526
3527 void DebugProcess(const FunctionCallbackInfo<Value>& args) {
3528   Environment* env = Environment::GetCurrent(args);
3529
3530   if (args.Length() != 1) {
3531     return env->ThrowError("Invalid number of arguments.");
3532   }
3533
3534   pid_t pid;
3535   int r;
3536
3537   pid = args[0]->IntegerValue();
3538   r = kill(pid, SIGUSR1);
3539   if (r != 0) {
3540     return env->ThrowErrnoException(errno, "kill");
3541   }
3542 }
3543
3544
3545 static int RegisterDebugSignalHandler() {
3546   // FIXME(bnoordhuis) Should be per-isolate or per-context, not global.
3547   RegisterSignalHandler(SIGUSR1, EnableDebugSignalHandler);
3548   // Unblock SIGUSR1.  A pending SIGUSR1 signal will now be delivered.
3549   sigset_t sigmask;
3550   sigemptyset(&sigmask);
3551   sigaddset(&sigmask, SIGUSR1);
3552   CHECK_EQ(0, pthread_sigmask(SIG_UNBLOCK, &sigmask, nullptr));
3553   return 0;
3554 }
3555 #endif  // __POSIX__
3556
3557
3558 #ifdef _WIN32
3559 DWORD WINAPI EnableDebugThreadProc(void* arg) {
3560   TryStartDebugger();
3561   return 0;
3562 }
3563
3564
3565 static int GetDebugSignalHandlerMappingName(DWORD pid, wchar_t* buf,
3566     size_t buf_len) {
3567   return _snwprintf(buf, buf_len, L"node-debug-handler-%u", pid);
3568 }
3569
3570
3571 static int RegisterDebugSignalHandler() {
3572   wchar_t mapping_name[32];
3573   HANDLE mapping_handle;
3574   DWORD pid;
3575   LPTHREAD_START_ROUTINE* handler;
3576
3577   pid = GetCurrentProcessId();
3578
3579   if (GetDebugSignalHandlerMappingName(pid,
3580                                        mapping_name,
3581                                        ARRAY_SIZE(mapping_name)) < 0) {
3582     return -1;
3583   }
3584
3585   mapping_handle = CreateFileMappingW(INVALID_HANDLE_VALUE,
3586                                       nullptr,
3587                                       PAGE_READWRITE,
3588                                       0,
3589                                       sizeof *handler,
3590                                       mapping_name);
3591   if (mapping_handle == nullptr) {
3592     return -1;
3593   }
3594
3595   handler = reinterpret_cast<LPTHREAD_START_ROUTINE*>(
3596       MapViewOfFile(mapping_handle,
3597                     FILE_MAP_ALL_ACCESS,
3598                     0,
3599                     0,
3600                     sizeof *handler));
3601   if (handler == nullptr) {
3602     CloseHandle(mapping_handle);
3603     return -1;
3604   }
3605
3606   *handler = EnableDebugThreadProc;
3607
3608   UnmapViewOfFile(static_cast<void*>(handler));
3609
3610   return 0;
3611 }
3612
3613
3614 static void DebugProcess(const FunctionCallbackInfo<Value>& args) {
3615   Environment* env = Environment::GetCurrent(args);
3616   Isolate* isolate = args.GetIsolate();
3617   DWORD pid;
3618   HANDLE process = nullptr;
3619   HANDLE thread = nullptr;
3620   HANDLE mapping = nullptr;
3621   wchar_t mapping_name[32];
3622   LPTHREAD_START_ROUTINE* handler = nullptr;
3623
3624   if (args.Length() != 1) {
3625     env->ThrowError("Invalid number of arguments.");
3626     goto out;
3627   }
3628
3629   pid = (DWORD) args[0]->IntegerValue();
3630
3631   process = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION |
3632                             PROCESS_VM_OPERATION | PROCESS_VM_WRITE |
3633                             PROCESS_VM_READ,
3634                         FALSE,
3635                         pid);
3636   if (process == nullptr) {
3637     isolate->ThrowException(
3638         WinapiErrnoException(isolate, GetLastError(), "OpenProcess"));
3639     goto out;
3640   }
3641
3642   if (GetDebugSignalHandlerMappingName(pid,
3643                                        mapping_name,
3644                                        ARRAY_SIZE(mapping_name)) < 0) {
3645     env->ThrowErrnoException(errno, "sprintf");
3646     goto out;
3647   }
3648
3649   mapping = OpenFileMappingW(FILE_MAP_READ, FALSE, mapping_name);
3650   if (mapping == nullptr) {
3651     isolate->ThrowException(WinapiErrnoException(isolate,
3652                                              GetLastError(),
3653                                              "OpenFileMappingW"));
3654     goto out;
3655   }
3656
3657   handler = reinterpret_cast<LPTHREAD_START_ROUTINE*>(
3658       MapViewOfFile(mapping,
3659                     FILE_MAP_READ,
3660                     0,
3661                     0,
3662                     sizeof *handler));
3663   if (handler == nullptr || *handler == nullptr) {
3664     isolate->ThrowException(
3665         WinapiErrnoException(isolate, GetLastError(), "MapViewOfFile"));
3666     goto out;
3667   }
3668
3669   thread = CreateRemoteThread(process,
3670                               nullptr,
3671                               0,
3672                               *handler,
3673                               nullptr,
3674                               0,
3675                               nullptr);
3676   if (thread == nullptr) {
3677     isolate->ThrowException(WinapiErrnoException(isolate,
3678                                                  GetLastError(),
3679                                                  "CreateRemoteThread"));
3680     goto out;
3681   }
3682
3683   // Wait for the thread to terminate
3684   if (WaitForSingleObject(thread, INFINITE) != WAIT_OBJECT_0) {
3685     isolate->ThrowException(WinapiErrnoException(isolate,
3686                                                  GetLastError(),
3687                                                  "WaitForSingleObject"));
3688     goto out;
3689   }
3690
3691  out:
3692   if (process != nullptr)
3693     CloseHandle(process);
3694   if (thread != nullptr)
3695     CloseHandle(thread);
3696   if (handler != nullptr)
3697     UnmapViewOfFile(handler);
3698   if (mapping != nullptr)
3699     CloseHandle(mapping);
3700 }
3701 #endif  // _WIN32
3702
3703
3704 static void DebugPause(const FunctionCallbackInfo<Value>& args) {
3705   v8::Debug::DebugBreak(args.GetIsolate());
3706 }
3707
3708
3709 static void DebugEnd(const FunctionCallbackInfo<Value>& args) {
3710   if (debugger_running) {
3711     Environment* env = Environment::GetCurrent(args);
3712     env->debugger_agent()->Stop();
3713     debugger_running = false;
3714   }
3715 }
3716
3717
3718 inline void PlatformInit() {
3719 #ifdef __POSIX__
3720   sigset_t sigmask;
3721   sigemptyset(&sigmask);
3722   sigaddset(&sigmask, SIGUSR1);
3723   const int err = pthread_sigmask(SIG_SETMASK, &sigmask, nullptr);
3724
3725   // Make sure file descriptors 0-2 are valid before we start logging anything.
3726   for (int fd = STDIN_FILENO; fd <= STDERR_FILENO; fd += 1) {
3727     struct stat ignored;
3728     if (fstat(fd, &ignored) == 0)
3729       continue;
3730     // Anything but EBADF means something is seriously wrong.  We don't
3731     // have to special-case EINTR, fstat() is not interruptible.
3732     if (errno != EBADF)
3733       ABORT();
3734     if (fd != open("/dev/null", O_RDWR))
3735       ABORT();
3736   }
3737
3738   CHECK_EQ(err, 0);
3739
3740   // Restore signal dispositions, the parent process may have changed them.
3741   struct sigaction act;
3742   memset(&act, 0, sizeof(act));
3743
3744   // The hard-coded upper limit is because NSIG is not very reliable; on Linux,
3745   // it evaluates to 32, 34 or 64, depending on whether RT signals are enabled.
3746   // Counting up to SIGRTMIN doesn't work for the same reason.
3747   for (unsigned nr = 1; nr < 32; nr += 1) {
3748     if (nr == SIGKILL || nr == SIGSTOP)
3749       continue;
3750     act.sa_handler = (nr == SIGPIPE) ? SIG_IGN : SIG_DFL;
3751     CHECK_EQ(0, sigaction(nr, &act, nullptr));
3752   }
3753
3754   RegisterSignalHandler(SIGINT, SignalExit, true);
3755   RegisterSignalHandler(SIGTERM, SignalExit, true);
3756
3757   // Raise the open file descriptor limit.
3758   struct rlimit lim;
3759   if (getrlimit(RLIMIT_NOFILE, &lim) == 0 && lim.rlim_cur != lim.rlim_max) {
3760     // Do a binary search for the limit.
3761     rlim_t min = lim.rlim_cur;
3762     rlim_t max = 1 << 20;
3763     // But if there's a defined upper bound, don't search, just set it.
3764     if (lim.rlim_max != RLIM_INFINITY) {
3765       min = lim.rlim_max;
3766       max = lim.rlim_max;
3767     }
3768     do {
3769       lim.rlim_cur = min + (max - min) / 2;
3770       if (setrlimit(RLIMIT_NOFILE, &lim)) {
3771         max = lim.rlim_cur;
3772       } else {
3773         min = lim.rlim_cur;
3774       }
3775     } while (min + 1 < max);
3776   }
3777 #endif  // __POSIX__
3778 }
3779
3780
3781 void Init(int* argc,
3782           const char** argv,
3783           int* exec_argc,
3784           const char*** exec_argv) {
3785   // Initialize prog_start_time to get relative uptime.
3786   prog_start_time = static_cast<double>(uv_now(uv_default_loop()));
3787
3788   // Make inherited handles noninheritable.
3789   uv_disable_stdio_inheritance();
3790
3791   // init async debug messages dispatching
3792   // Main thread uses uv_default_loop
3793   uv_async_init(uv_default_loop(),
3794                 &dispatch_debug_messages_async,
3795                 DispatchDebugMessagesAsyncCallback);
3796   uv_unref(reinterpret_cast<uv_handle_t*>(&dispatch_debug_messages_async));
3797
3798 #if defined(NODE_V8_OPTIONS)
3799   // Should come before the call to V8::SetFlagsFromCommandLine()
3800   // so the user can disable a flag --foo at run-time by passing
3801   // --no_foo from the command line.
3802   V8::SetFlagsFromString(NODE_V8_OPTIONS, sizeof(NODE_V8_OPTIONS) - 1);
3803 #endif
3804
3805   // Parse a few arguments which are specific to Node.
3806   int v8_argc;
3807   const char** v8_argv;
3808   ParseArgs(argc, argv, exec_argc, exec_argv, &v8_argc, &v8_argv);
3809
3810   // TODO(bnoordhuis) Intercept --prof arguments and start the CPU profiler
3811   // manually?  That would give us a little more control over its runtime
3812   // behavior but it could also interfere with the user's intentions in ways
3813   // we fail to anticipate.  Dillema.
3814   for (int i = 1; i < v8_argc; ++i) {
3815     if (strncmp(v8_argv[i], "--prof", sizeof("--prof") - 1) == 0) {
3816       v8_is_profiling = true;
3817       break;
3818     }
3819   }
3820
3821 #ifdef __POSIX__
3822   // Block SIGPROF signals when sleeping in epoll_wait/kevent/etc.  Avoids the
3823   // performance penalty of frequent EINTR wakeups when the profiler is running.
3824   // Only do this for v8.log profiling, as it breaks v8::CpuProfiler users.
3825   if (v8_is_profiling) {
3826     uv_loop_configure(uv_default_loop(), UV_LOOP_BLOCK_SIGNAL, SIGPROF);
3827   }
3828 #endif
3829
3830 #if defined(NODE_HAVE_I18N_SUPPORT)
3831   if (icu_data_dir == nullptr) {
3832     // if the parameter isn't given, use the env variable.
3833     icu_data_dir = secure_getenv("NODE_ICU_DATA");
3834   }
3835   // Initialize ICU.
3836   // If icu_data_dir is nullptr here, it will load the 'minimal' data.
3837   if (!i18n::InitializeICUDirectory(icu_data_dir)) {
3838     FatalError(nullptr, "Could not initialize ICU "
3839                      "(check NODE_ICU_DATA or --icu-data-dir parameters)");
3840   }
3841 #endif
3842   // The const_cast doesn't violate conceptual const-ness.  V8 doesn't modify
3843   // the argv array or the elements it points to.
3844   if (v8_argc > 1)
3845     V8::SetFlagsFromCommandLine(&v8_argc, const_cast<char**>(v8_argv), true);
3846
3847   // Anything that's still in v8_argv is not a V8 or a node option.
3848   for (int i = 1; i < v8_argc; i++) {
3849     fprintf(stderr, "%s: bad option: %s\n", argv[0], v8_argv[i]);
3850   }
3851   delete[] v8_argv;
3852   v8_argv = nullptr;
3853
3854   if (v8_argc > 1) {
3855     exit(9);
3856   }
3857
3858   if (debug_wait_connect) {
3859     const char expose_debug_as[] = "--expose_debug_as=v8debug";
3860     V8::SetFlagsFromString(expose_debug_as, sizeof(expose_debug_as) - 1);
3861   }
3862
3863   // Unconditionally force typed arrays to allocate outside the v8 heap. This
3864   // is to prevent memory pointers from being moved around that are returned by
3865   // Buffer::Data().
3866   const char no_typed_array_heap[] = "--typed_array_max_size_in_heap=0";
3867   V8::SetFlagsFromString(no_typed_array_heap, sizeof(no_typed_array_heap) - 1);
3868
3869   if (!use_debug_agent) {
3870     RegisterDebugSignalHandler();
3871   }
3872
3873   // We should set node_is_initialized here instead of in node::Start,
3874   // otherwise embedders using node::Init to initialize everything will not be
3875   // able to set it and native modules will not load for them.
3876   node_is_initialized = true;
3877 }
3878
3879
3880 struct AtExitCallback {
3881   AtExitCallback* next_;
3882   void (*cb_)(void* arg);
3883   void* arg_;
3884 };
3885
3886 static AtExitCallback* at_exit_functions_;
3887
3888
3889 // TODO(bnoordhuis) Turn into per-context event.
3890 void RunAtExit(Environment* env) {
3891   AtExitCallback* p = at_exit_functions_;
3892   at_exit_functions_ = nullptr;
3893
3894   while (p) {
3895     AtExitCallback* q = p->next_;
3896     p->cb_(p->arg_);
3897     delete p;
3898     p = q;
3899   }
3900 }
3901
3902
3903 void AtExit(void (*cb)(void* arg), void* arg) {
3904   AtExitCallback* p = new AtExitCallback;
3905   p->cb_ = cb;
3906   p->arg_ = arg;
3907   p->next_ = at_exit_functions_;
3908   at_exit_functions_ = p;
3909 }
3910
3911
3912 void EmitBeforeExit(Environment* env) {
3913   HandleScope handle_scope(env->isolate());
3914   Context::Scope context_scope(env->context());
3915   Local<Object> process_object = env->process_object();
3916   Local<String> exit_code = FIXED_ONE_BYTE_STRING(env->isolate(), "exitCode");
3917   Local<Value> args[] = {
3918     FIXED_ONE_BYTE_STRING(env->isolate(), "beforeExit"),
3919     process_object->Get(exit_code)->ToInteger(env->isolate())
3920   };
3921   MakeCallback(env, process_object, "emit", ARRAY_SIZE(args), args);
3922 }
3923
3924
3925 int EmitExit(Environment* env) {
3926   // process.emit('exit')
3927   HandleScope handle_scope(env->isolate());
3928   Context::Scope context_scope(env->context());
3929   Local<Object> process_object = env->process_object();
3930   process_object->Set(env->exiting_string(), True(env->isolate()));
3931
3932   Local<String> exitCode = env->exit_code_string();
3933   int code = process_object->Get(exitCode)->Int32Value();
3934
3935   Local<Value> args[] = {
3936     env->exit_string(),
3937     Integer::New(env->isolate(), code)
3938   };
3939
3940   MakeCallback(env, process_object, "emit", ARRAY_SIZE(args), args);
3941
3942   // Reload exit code, it may be changed by `emit('exit')`
3943   return process_object->Get(exitCode)->Int32Value();
3944 }
3945
3946
3947 // Just a convenience method
3948 Environment* CreateEnvironment(Isolate* isolate,
3949                                Local<Context> context,
3950                                int argc,
3951                                const char* const* argv,
3952                                int exec_argc,
3953                                const char* const* exec_argv) {
3954   Environment* env;
3955   Context::Scope context_scope(context);
3956
3957   env = CreateEnvironment(isolate,
3958                           uv_default_loop(),
3959                           context,
3960                           argc,
3961                           argv,
3962                           exec_argc,
3963                           exec_argv);
3964
3965   LoadEnvironment(env);
3966
3967   return env;
3968 }
3969
3970 static Environment* CreateEnvironment(Isolate* isolate,
3971                                       Local<Context> context,
3972                                       NodeInstanceData* instance_data) {
3973   return CreateEnvironment(isolate,
3974                            instance_data->event_loop(),
3975                            context,
3976                            instance_data->argc(),
3977                            instance_data->argv(),
3978                            instance_data->exec_argc(),
3979                            instance_data->exec_argv());
3980 }
3981
3982
3983 static void HandleCloseCb(uv_handle_t* handle) {
3984   Environment* env = reinterpret_cast<Environment*>(handle->data);
3985   env->FinishHandleCleanup(handle);
3986 }
3987
3988
3989 static void HandleCleanup(Environment* env,
3990                           uv_handle_t* handle,
3991                           void* arg) {
3992   handle->data = env;
3993   uv_close(handle, HandleCloseCb);
3994 }
3995
3996
3997 Environment* CreateEnvironment(Isolate* isolate,
3998                                uv_loop_t* loop,
3999                                Local<Context> context,
4000                                int argc,
4001                                const char* const* argv,
4002                                int exec_argc,
4003                                const char* const* exec_argv) {
4004   HandleScope handle_scope(isolate);
4005
4006   Context::Scope context_scope(context);
4007   Environment* env = Environment::New(context, loop);
4008
4009   isolate->SetAutorunMicrotasks(false);
4010
4011   uv_check_init(env->event_loop(), env->immediate_check_handle());
4012   uv_unref(
4013       reinterpret_cast<uv_handle_t*>(env->immediate_check_handle()));
4014
4015   uv_idle_init(env->event_loop(), env->immediate_idle_handle());
4016
4017   // Inform V8's CPU profiler when we're idle.  The profiler is sampling-based
4018   // but not all samples are created equal; mark the wall clock time spent in
4019   // epoll_wait() and friends so profiling tools can filter it out.  The samples
4020   // still end up in v8.log but with state=IDLE rather than state=EXTERNAL.
4021   // TODO(bnoordhuis) Depends on a libuv implementation detail that we should
4022   // probably fortify in the API contract, namely that the last started prepare
4023   // or check watcher runs first.  It's not 100% foolproof; if an add-on starts
4024   // a prepare or check watcher after us, any samples attributed to its callback
4025   // will be recorded with state=IDLE.
4026   uv_prepare_init(env->event_loop(), env->idle_prepare_handle());
4027   uv_check_init(env->event_loop(), env->idle_check_handle());
4028   uv_unref(reinterpret_cast<uv_handle_t*>(env->idle_prepare_handle()));
4029   uv_unref(reinterpret_cast<uv_handle_t*>(env->idle_check_handle()));
4030
4031   // Register handle cleanups
4032   env->RegisterHandleCleanup(
4033       reinterpret_cast<uv_handle_t*>(env->immediate_check_handle()),
4034       HandleCleanup,
4035       nullptr);
4036   env->RegisterHandleCleanup(
4037       reinterpret_cast<uv_handle_t*>(env->immediate_idle_handle()),
4038       HandleCleanup,
4039       nullptr);
4040   env->RegisterHandleCleanup(
4041       reinterpret_cast<uv_handle_t*>(env->idle_prepare_handle()),
4042       HandleCleanup,
4043       nullptr);
4044   env->RegisterHandleCleanup(
4045       reinterpret_cast<uv_handle_t*>(env->idle_check_handle()),
4046       HandleCleanup,
4047       nullptr);
4048
4049   if (v8_is_profiling) {
4050     StartProfilerIdleNotifier(env);
4051   }
4052
4053   Local<FunctionTemplate> process_template = FunctionTemplate::New(isolate);
4054   process_template->SetClassName(FIXED_ONE_BYTE_STRING(isolate, "process"));
4055
4056   Local<Object> process_object = process_template->GetFunction()->NewInstance();
4057   env->set_process_object(process_object);
4058
4059   SetupProcessObject(env, argc, argv, exec_argc, exec_argv);
4060   LoadAsyncWrapperInfo(env);
4061
4062   return env;
4063 }
4064
4065
4066 // Entry point for new node instances, also called directly for the main
4067 // node instance.
4068 static void StartNodeInstance(void* arg) {
4069   NodeInstanceData* instance_data = static_cast<NodeInstanceData*>(arg);
4070   Isolate::CreateParams params;
4071   ArrayBufferAllocator* array_buffer_allocator = new ArrayBufferAllocator();
4072   params.array_buffer_allocator = array_buffer_allocator;
4073   Isolate* isolate = Isolate::New(params);
4074   if (track_heap_objects) {
4075     isolate->GetHeapProfiler()->StartTrackingHeapObjects(true);
4076   }
4077
4078   // Fetch a reference to the main isolate, so we have a reference to it
4079   // even when we need it to access it from another (debugger) thread.
4080   if (instance_data->is_main())
4081     CHECK_EQ(nullptr, node_isolate.exchange(isolate));
4082
4083   {
4084     Locker locker(isolate);
4085     Isolate::Scope isolate_scope(isolate);
4086     HandleScope handle_scope(isolate);
4087     Local<Context> context = Context::New(isolate);
4088     Environment* env = CreateEnvironment(isolate, context, instance_data);
4089     array_buffer_allocator->set_env(env);
4090     Context::Scope context_scope(context);
4091
4092     isolate->SetAbortOnUncaughtExceptionCallback(
4093         ShouldAbortOnUncaughtException);
4094
4095     // Start debug agent when argv has --debug
4096     if (instance_data->use_debug_agent())
4097       StartDebug(env, debug_wait_connect);
4098
4099     LoadEnvironment(env);
4100
4101     env->set_trace_sync_io(trace_sync_io);
4102
4103     // Enable debugger
4104     if (instance_data->use_debug_agent())
4105       EnableDebug(env);
4106
4107     {
4108       SealHandleScope seal(isolate);
4109       bool more;
4110       do {
4111         v8::platform::PumpMessageLoop(default_platform, isolate);
4112         more = uv_run(env->event_loop(), UV_RUN_ONCE);
4113
4114         if (more == false) {
4115           v8::platform::PumpMessageLoop(default_platform, isolate);
4116           EmitBeforeExit(env);
4117
4118           // Emit `beforeExit` if the loop became alive either after emitting
4119           // event, or after running some callbacks.
4120           more = uv_loop_alive(env->event_loop());
4121           if (uv_run(env->event_loop(), UV_RUN_NOWAIT) != 0)
4122             more = true;
4123         }
4124       } while (more == true);
4125     }
4126
4127     env->set_trace_sync_io(false);
4128
4129     int exit_code = EmitExit(env);
4130     if (instance_data->is_main())
4131       instance_data->set_exit_code(exit_code);
4132     RunAtExit(env);
4133
4134 #if defined(LEAK_SANITIZER)
4135     __lsan_do_leak_check();
4136 #endif
4137
4138     array_buffer_allocator->set_env(nullptr);
4139     env->Dispose();
4140     env = nullptr;
4141   }
4142
4143   if (instance_data->is_main()) {
4144     // Synchronize with signal handler, see TryStartDebugger.
4145     while (isolate != node_isolate.exchange(nullptr));  // NOLINT
4146   }
4147
4148   CHECK_NE(isolate, nullptr);
4149   isolate->Dispose();
4150   isolate = nullptr;
4151   delete array_buffer_allocator;
4152 }
4153
4154 int Start(int argc, char** argv) {
4155   PlatformInit();
4156
4157   CHECK_GT(argc, 0);
4158
4159   // Hack around with the argv pointer. Used for process.title = "blah".
4160   argv = uv_setup_args(argc, argv);
4161
4162   // This needs to run *before* V8::Initialize().  The const_cast is not
4163   // optional, in case you're wondering.
4164   int exec_argc;
4165   const char** exec_argv;
4166   Init(&argc, const_cast<const char**>(argv), &exec_argc, &exec_argv);
4167
4168 #if HAVE_OPENSSL
4169   // V8 on Windows doesn't have a good source of entropy. Seed it from
4170   // OpenSSL's pool.
4171   V8::SetEntropySource(crypto::EntropySource);
4172 #endif
4173
4174   const int thread_pool_size = 4;
4175   default_platform = v8::platform::CreateDefaultPlatform(thread_pool_size);
4176   V8::InitializePlatform(default_platform);
4177   V8::Initialize();
4178
4179   int exit_code = 1;
4180   {
4181     NodeInstanceData instance_data(NodeInstanceType::MAIN,
4182                                    uv_default_loop(),
4183                                    argc,
4184                                    const_cast<const char**>(argv),
4185                                    exec_argc,
4186                                    exec_argv,
4187                                    use_debug_agent);
4188     StartNodeInstance(&instance_data);
4189     exit_code = instance_data.exit_code();
4190   }
4191   V8::Dispose();
4192
4193   delete default_platform;
4194   default_platform = nullptr;
4195
4196   delete[] exec_argv;
4197   exec_argv = nullptr;
4198
4199   return exit_code;
4200 }
4201
4202
4203 }  // namespace node