GCC Code Coverage Report
Directory: ../ Exec Total Coverage
File: /home/iojs/build/workspace/node-test-commit-linux-coverage/nodes/benchmark/out/../src/node.cc Lines: 1562 1909 81.8 %
Date: 2017-10-21 Branches: 845 1282 65.9 %

Line Branch Exec Source
1
// Copyright Joyent, Inc. and other Node contributors.
2
//
3
// Permission is hereby granted, free of charge, to any person obtaining a
4
// copy of this software and associated documentation files (the
5
// "Software"), to deal in the Software without restriction, including
6
// without limitation the rights to use, copy, modify, merge, publish,
7
// distribute, sublicense, and/or sell copies of the Software, and to permit
8
// persons to whom the Software is furnished to do so, subject to the
9
// following conditions:
10
//
11
// The above copyright notice and this permission notice shall be included
12
// in all copies or substantial portions of the Software.
13
//
14
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20
// USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22
#include "node_buffer.h"
23
#include "node_constants.h"
24
#include "node_javascript.h"
25
#include "node_platform.h"
26
#include "node_version.h"
27
#include "node_internals.h"
28
#include "node_revert.h"
29
#include "node_debug_options.h"
30
#include "node_perf.h"
31
32
#if defined HAVE_PERFCTR
33
#include "node_counters.h"
34
#endif
35
36
#if HAVE_OPENSSL
37
#include "node_crypto.h"
38
#endif
39
40
#if defined(NODE_HAVE_I18N_SUPPORT)
41
#include "node_i18n.h"
42
#endif
43
44
#if HAVE_INSPECTOR
45
#include "inspector_io.h"
46
#endif
47
48
#if defined HAVE_DTRACE || defined HAVE_ETW
49
#include "node_dtrace.h"
50
#endif
51
52
#if defined HAVE_LTTNG
53
#include "node_lttng.h"
54
#endif
55
56
#include "ares.h"
57
#include "async-wrap.h"
58
#include "async-wrap-inl.h"
59
#include "env.h"
60
#include "env-inl.h"
61
#include "handle_wrap.h"
62
#include "http_parser.h"
63
#include "nghttp2/nghttp2ver.h"
64
#include "req-wrap.h"
65
#include "req-wrap-inl.h"
66
#include "string_bytes.h"
67
#include "tracing/agent.h"
68
#include "util.h"
69
#include "uv.h"
70
#if NODE_USE_V8_PLATFORM
71
#include "libplatform/libplatform.h"
72
#endif  // NODE_USE_V8_PLATFORM
73
#include "v8-debug.h"
74
#include "v8-profiler.h"
75
#include "zlib.h"
76
77
#ifdef NODE_ENABLE_VTUNE_PROFILING
78
#include "../deps/v8/src/third_party/vtune/v8-vtune.h"
79
#endif
80
81
#include <errno.h>
82
#include <fcntl.h>  // _O_RDWR
83
#include <limits.h>  // PATH_MAX
84
#include <locale.h>
85
#include <signal.h>
86
#include <stdio.h>
87
#include <stdlib.h>
88
#include <string.h>
89
#include <sys/types.h>
90
91
#include <string>
92
#include <vector>
93
94
#if defined(NODE_HAVE_I18N_SUPPORT)
95
#include <unicode/uvernum.h>
96
#endif
97
98
#if defined(LEAK_SANITIZER)
99
#include <sanitizer/lsan_interface.h>
100
#endif
101
102
#if defined(_MSC_VER)
103
#include <direct.h>
104
#include <io.h>
105
#define getpid GetCurrentProcessId
106
#define umask _umask
107
typedef int mode_t;
108
#else
109
#include <pthread.h>
110
#include <sys/resource.h>  // getrlimit, setrlimit
111
#include <unistd.h>  // setuid, getuid
112
#endif
113
114
#if defined(__POSIX__) && !defined(__ANDROID__)
115
#include <pwd.h>  // getpwnam()
116
#include <grp.h>  // getgrnam()
117
#endif
118
119
#if defined(__POSIX__)
120
#include <dlfcn.h>
121
#endif
122
123
#ifdef __APPLE__
124
#include <crt_externs.h>
125
#define environ (*_NSGetEnviron())
126
#elif !defined(_MSC_VER)
127
extern char **environ;
128
#endif
129
130
namespace node {
131
132
using v8::Array;
133
using v8::ArrayBuffer;
134
using v8::Boolean;
135
using v8::Context;
136
using v8::EscapableHandleScope;
137
using v8::Exception;
138
using v8::Float64Array;
139
using v8::Function;
140
using v8::FunctionCallbackInfo;
141
using v8::HandleScope;
142
using v8::HeapStatistics;
143
using v8::Integer;
144
using v8::Isolate;
145
using v8::Local;
146
using v8::Locker;
147
using v8::MaybeLocal;
148
using v8::Message;
149
using v8::Name;
150
using v8::NamedPropertyHandlerConfiguration;
151
using v8::Null;
152
using v8::Number;
153
using v8::Object;
154
using v8::ObjectTemplate;
155
using v8::Promise;
156
using v8::PromiseHookType;
157
using v8::PromiseRejectMessage;
158
using v8::PropertyCallbackInfo;
159
using v8::ScriptOrigin;
160
using v8::SealHandleScope;
161
using v8::String;
162
using v8::TryCatch;
163
using v8::Uint32Array;
164
using v8::Undefined;
165
using v8::V8;
166
using v8::Value;
167
168
using AsyncHooks = node::Environment::AsyncHooks;
169
170
static bool print_eval = false;
171
static bool force_repl = false;
172
static bool syntax_check_only = false;
173
static bool trace_deprecation = false;
174
static bool throw_deprecation = false;
175
static bool trace_sync_io = false;
176
static bool force_async_hooks_checks = false;
177
static bool track_heap_objects = false;
178
static const char* eval_string = nullptr;
179
3246
static std::vector<std::string> preload_modules;
180
static const int v8_default_thread_pool_size = 4;
181
static int v8_thread_pool_size = v8_default_thread_pool_size;
182
static bool prof_process = false;
183
static bool v8_is_profiling = false;
184
static bool node_is_initialized = false;
185
static node_module* modpending;
186
static node_module* modlist_builtin;
187
static node_module* modlist_internal;
188
static node_module* modlist_linked;
189
static node_module* modlist_addon;
190
static bool trace_enabled = false;
191
3246
static std::string trace_enabled_categories;  // NOLINT(runtime/string)
192
static bool abort_on_uncaught_exception = false;
193
194
// Bit flag used to track security reverts (see node_revert.h)
195
unsigned int reverted = 0;
196
197
#if defined(NODE_HAVE_I18N_SUPPORT)
198
// Path to ICU data (for i18n / Intl)
199
3246
std::string icu_data_dir;  // NOLINT(runtime/string)
200
#endif
201
202
// used by C++ modules as well
203
bool no_deprecation = false;
204
205
#if HAVE_OPENSSL
206
// use OpenSSL's cert store instead of bundled certs
207
bool ssl_openssl_cert_store =
208
#if defined(NODE_OPENSSL_CERT_STORE)
209
        true;
210
#else
211
        false;
212
#endif
213
214
# if NODE_FIPS_MODE
215
// used by crypto module
216
bool enable_fips_crypto = false;
217
bool force_fips_crypto = false;
218
# endif  // NODE_FIPS_MODE
219
3246
std::string openssl_config;  // NOLINT(runtime/string)
220
#endif  // HAVE_OPENSSL
221
222
// true if process warnings should be suppressed
223
bool no_process_warnings = false;
224
bool trace_warnings = false;
225
226
// Set in node.cc by ParseArgs when --preserve-symlinks is used.
227
// Used in node_config.cc to set a constant on process.binding('config')
228
// that is used by lib/module.js
229
bool config_preserve_symlinks = false;
230
231
// Set in node.cc by ParseArgs when --experimental-modules is used.
232
// Used in node_config.cc to set a constant on process.binding('config')
233
// that is used by lib/module.js
234
bool config_experimental_modules = false;
235
236
// Set in node.cc by ParseArgs when --loader is used.
237
// Used in node_config.cc to set a constant on process.binding('config')
238
// that is used by lib/internal/bootstrap_node.js
239
3246
std::string config_userland_loader;  // NOLINT(runtime/string)
240
241
// Set by ParseArgs when --pending-deprecation or NODE_PENDING_DEPRECATION
242
// is used.
243
bool config_pending_deprecation = false;
244
245
// Set in node.cc by ParseArgs when --redirect-warnings= is used.
246
3246
std::string config_warning_file;  // NOLINT(runtime/string)
247
248
// Set in node.cc by ParseArgs when --expose-internals or --expose_internals is
249
// used.
250
// Used in node_config.cc to set a constant on process.binding('config')
251
// that is used by lib/internal/bootstrap_node.js
252
bool config_expose_internals = false;
253
254
bool v8_initialized = false;
255
256
bool linux_at_secure = false;
257
258
// process-relative uptime base, initialized at start-up
259
static double prog_start_time;
260
261
3246
static Mutex node_isolate_mutex;
262
static v8::Isolate* node_isolate;
263
264
3246
node::DebugOptions debug_options;
265
266
static struct {
267
#if NODE_USE_V8_PLATFORM
268
3202
  void Initialize(int thread_pool_size, uv_loop_t* loop) {
269
    tracing_agent_ =
270
3202
        trace_enabled ? new tracing::Agent() : nullptr;
271
    platform_ = new NodePlatform(thread_pool_size, loop,
272
3202
        trace_enabled ? tracing_agent_->GetTracingController() : nullptr);
273
3202
    V8::InitializePlatform(platform_);
274
    tracing::TraceEventHelper::SetTracingController(
275
3202
        trace_enabled ? tracing_agent_->GetTracingController() : nullptr);
276
3202
  }
277
278
2842
  void Dispose() {
279
2842
    platform_->Shutdown();
280
2842
    delete platform_;
281
2842
    platform_ = nullptr;
282
2842
    delete tracing_agent_;
283
2842
    tracing_agent_ = nullptr;
284
2842
  }
285
286
5740
  void DrainVMTasks() {
287
5740
    platform_->DrainBackgroundTasks();
288
5740
  }
289
290
#if HAVE_INSPECTOR
291
3202
  bool StartInspector(Environment *env, const char* script_path,
292
                      const node::DebugOptions& options) {
293
    // Inspector agent can't fail to start, but if it was configured to listen
294
    // right away on the websocket port and fails to bind/etc, this will return
295
    // false.
296
3202
    return env->inspector_agent()->Start(platform_, script_path, options);
297
  }
298
299
65
  bool InspectorStarted(Environment *env) {
300
65
    return env->inspector_agent()->IsStarted();
301
  }
302
#endif  // HAVE_INSPECTOR
303
304
3
  void StartTracingAgent() {
305
3
    tracing_agent_->Start(trace_enabled_categories);
306
3
  }
307
308
3
  void StopTracingAgent() {
309
3
    tracing_agent_->Stop();
310
3
  }
311
312
  tracing::Agent* tracing_agent_;
313
  NodePlatform* platform_;
314
#else  // !NODE_USE_V8_PLATFORM
315
  void Initialize(int thread_pool_size, uv_loop_t* loop) {}
316
  void Dispose() {}
317
  void DrainVMTasks() {}
318
  bool StartInspector(Environment *env, const char* script_path,
319
                      const node::DebugOptions& options) {
320
    env->ThrowError("Node compiled with NODE_USE_V8_PLATFORM=0");
321
    return true;
322
  }
323
324
  void StartTracingAgent() {
325
    fprintf(stderr, "Node compiled with NODE_USE_V8_PLATFORM=0, "
326
                    "so event tracing is not available.\n");
327
  }
328
  void StopTracingAgent() {}
329
#endif  // !NODE_USE_V8_PLATFORM
330
331
#if !NODE_USE_V8_PLATFORM || !HAVE_INSPECTOR
332
  bool InspectorStarted(Environment *env) {
333
    return false;
334
  }
335
#endif  //  !NODE_USE_V8_PLATFORM || !HAVE_INSPECTOR
336
} v8_platform;
337
338
#ifdef __POSIX__
339
static const unsigned kMaxSignal = 32;
340
#endif
341
342
154
static void PrintErrorString(const char* format, ...) {
343
  va_list ap;
344
154
  va_start(ap, format);
345
#ifdef _WIN32
346
  HANDLE stderr_handle = GetStdHandle(STD_ERROR_HANDLE);
347
348
  // Check if stderr is something other than a tty/console
349
  if (stderr_handle == INVALID_HANDLE_VALUE ||
350
      stderr_handle == nullptr ||
351
      uv_guess_handle(_fileno(stderr)) != UV_TTY) {
352
    vfprintf(stderr, format, ap);
353
    va_end(ap);
354
    return;
355
  }
356
357
  // Fill in any placeholders
358
  int n = _vscprintf(format, ap);
359
  std::vector<char> out(n + 1);
360
  vsprintf(out.data(), format, ap);
361
362
  // Get required wide buffer size
363
  n = MultiByteToWideChar(CP_UTF8, 0, out.data(), -1, nullptr, 0);
364
365
  std::vector<wchar_t> wbuf(n);
366
  MultiByteToWideChar(CP_UTF8, 0, out.data(), -1, wbuf.data(), n);
367
368
  // Don't include the null character in the output
369
  CHECK_GT(n, 0);
370
  WriteConsoleW(stderr_handle, wbuf.data(), n - 1, nullptr, nullptr);
371
#else
372
154
  vfprintf(stderr, format, ap);
373
#endif
374
154
  va_end(ap);
375
154
}
376
377
378
66772
static void CheckImmediate(uv_check_t* handle) {
379
66772
  Environment* env = Environment::from_immediate_check_handle(handle);
380
66772
  HandleScope scope(env->isolate());
381
66772
  Context::Scope context_scope(env->context());
382
  MakeCallback(env->isolate(),
383
               env->process_object(),
384
               env->immediate_callback_string(),
385
               0,
386
               nullptr,
387
200308
               {0, 0}).ToLocalChecked();
388
66768
}
389
390
391
63765
static void IdleImmediateDummy(uv_idle_t* handle) {
392
  // Do nothing. Only for maintaining event loop.
393
  // TODO(bnoordhuis) Maybe make libuv accept nullptr idle callbacks.
394
63765
}
395
396
397
4
static inline const char *errno_string(int errorno) {
398
#define ERRNO_CASE(e)  case e: return #e;
399



















4
  switch (errorno) {
400
#ifdef EACCES
401
  ERRNO_CASE(EACCES);
402
#endif
403
404
#ifdef EADDRINUSE
405
  ERRNO_CASE(EADDRINUSE);
406
#endif
407
408
#ifdef EADDRNOTAVAIL
409
  ERRNO_CASE(EADDRNOTAVAIL);
410
#endif
411
412
#ifdef EAFNOSUPPORT
413
  ERRNO_CASE(EAFNOSUPPORT);
414
#endif
415
416
#ifdef EAGAIN
417
  ERRNO_CASE(EAGAIN);
418
#endif
419
420
#ifdef EWOULDBLOCK
421
# if EAGAIN != EWOULDBLOCK
422
  ERRNO_CASE(EWOULDBLOCK);
423
# endif
424
#endif
425
426
#ifdef EALREADY
427
  ERRNO_CASE(EALREADY);
428
#endif
429
430
#ifdef EBADF
431
  ERRNO_CASE(EBADF);
432
#endif
433
434
#ifdef EBADMSG
435
  ERRNO_CASE(EBADMSG);
436
#endif
437
438
#ifdef EBUSY
439
  ERRNO_CASE(EBUSY);
440
#endif
441
442
#ifdef ECANCELED
443
  ERRNO_CASE(ECANCELED);
444
#endif
445
446
#ifdef ECHILD
447
1
  ERRNO_CASE(ECHILD);
448
#endif
449
450
#ifdef ECONNABORTED
451
  ERRNO_CASE(ECONNABORTED);
452
#endif
453
454
#ifdef ECONNREFUSED
455
  ERRNO_CASE(ECONNREFUSED);
456
#endif
457
458
#ifdef ECONNRESET
459
  ERRNO_CASE(ECONNRESET);
460
#endif
461
462
#ifdef EDEADLK
463
  ERRNO_CASE(EDEADLK);
464
#endif
465
466
#ifdef EDESTADDRREQ
467
  ERRNO_CASE(EDESTADDRREQ);
468
#endif
469
470
#ifdef EDOM
471
  ERRNO_CASE(EDOM);
472
#endif
473
474
#ifdef EDQUOT
475
  ERRNO_CASE(EDQUOT);
476
#endif
477
478
#ifdef EEXIST
479
  ERRNO_CASE(EEXIST);
480
#endif
481
482
#ifdef EFAULT
483
  ERRNO_CASE(EFAULT);
484
#endif
485
486
#ifdef EFBIG
487
  ERRNO_CASE(EFBIG);
488
#endif
489
490
#ifdef EHOSTUNREACH
491
  ERRNO_CASE(EHOSTUNREACH);
492
#endif
493
494
#ifdef EIDRM
495
  ERRNO_CASE(EIDRM);
496
#endif
497
498
#ifdef EILSEQ
499
  ERRNO_CASE(EILSEQ);
500
#endif
501
502
#ifdef EINPROGRESS
503
  ERRNO_CASE(EINPROGRESS);
504
#endif
505
506
#ifdef EINTR
507
  ERRNO_CASE(EINTR);
508
#endif
509
510
#ifdef EINVAL
511
  ERRNO_CASE(EINVAL);
512
#endif
513
514
#ifdef EIO
515
  ERRNO_CASE(EIO);
516
#endif
517
518
#ifdef EISCONN
519
  ERRNO_CASE(EISCONN);
520
#endif
521
522
#ifdef EISDIR
523
  ERRNO_CASE(EISDIR);
524
#endif
525
526
#ifdef ELOOP
527
  ERRNO_CASE(ELOOP);
528
#endif
529
530
#ifdef EMFILE
531
  ERRNO_CASE(EMFILE);
532
#endif
533
534
#ifdef EMLINK
535
  ERRNO_CASE(EMLINK);
536
#endif
537
538
#ifdef EMSGSIZE
539
  ERRNO_CASE(EMSGSIZE);
540
#endif
541
542
#ifdef EMULTIHOP
543
  ERRNO_CASE(EMULTIHOP);
544
#endif
545
546
#ifdef ENAMETOOLONG
547
  ERRNO_CASE(ENAMETOOLONG);
548
#endif
549
550
#ifdef ENETDOWN
551
  ERRNO_CASE(ENETDOWN);
552
#endif
553
554
#ifdef ENETRESET
555
  ERRNO_CASE(ENETRESET);
556
#endif
557
558
#ifdef ENETUNREACH
559
  ERRNO_CASE(ENETUNREACH);
560
#endif
561
562
#ifdef ENFILE
563
  ERRNO_CASE(ENFILE);
564
#endif
565
566
#ifdef ENOBUFS
567
  ERRNO_CASE(ENOBUFS);
568
#endif
569
570
#ifdef ENODATA
571
  ERRNO_CASE(ENODATA);
572
#endif
573
574
#ifdef ENODEV
575
  ERRNO_CASE(ENODEV);
576
#endif
577
578
#ifdef ENOENT
579
  ERRNO_CASE(ENOENT);
580
#endif
581
582
#ifdef ENOEXEC
583
  ERRNO_CASE(ENOEXEC);
584
#endif
585
586
#ifdef ENOLINK
587
  ERRNO_CASE(ENOLINK);
588
#endif
589
590
#ifdef ENOLCK
591
# if ENOLINK != ENOLCK
592
  ERRNO_CASE(ENOLCK);
593
# endif
594
#endif
595
596
#ifdef ENOMEM
597
  ERRNO_CASE(ENOMEM);
598
#endif
599
600
#ifdef ENOMSG
601
  ERRNO_CASE(ENOMSG);
602
#endif
603
604
#ifdef ENOPROTOOPT
605
  ERRNO_CASE(ENOPROTOOPT);
606
#endif
607
608
#ifdef ENOSPC
609
  ERRNO_CASE(ENOSPC);
610
#endif
611
612
#ifdef ENOSR
613
  ERRNO_CASE(ENOSR);
614
#endif
615
616
#ifdef ENOSTR
617
  ERRNO_CASE(ENOSTR);
618
#endif
619
620
#ifdef ENOSYS
621
  ERRNO_CASE(ENOSYS);
622
#endif
623
624
#ifdef ENOTCONN
625
  ERRNO_CASE(ENOTCONN);
626
#endif
627
628
#ifdef ENOTDIR
629
  ERRNO_CASE(ENOTDIR);
630
#endif
631
632
#ifdef ENOTEMPTY
633
# if ENOTEMPTY != EEXIST
634
  ERRNO_CASE(ENOTEMPTY);
635
# endif
636
#endif
637
638
#ifdef ENOTSOCK
639
  ERRNO_CASE(ENOTSOCK);
640
#endif
641
642
#ifdef ENOTSUP
643
  ERRNO_CASE(ENOTSUP);
644
#else
645
# ifdef EOPNOTSUPP
646
  ERRNO_CASE(EOPNOTSUPP);
647
# endif
648
#endif
649
650
#ifdef ENOTTY
651
  ERRNO_CASE(ENOTTY);
652
#endif
653
654
#ifdef ENXIO
655
  ERRNO_CASE(ENXIO);
656
#endif
657
658
659
#ifdef EOVERFLOW
660
  ERRNO_CASE(EOVERFLOW);
661
#endif
662
663
#ifdef EPERM
664
2
  ERRNO_CASE(EPERM);
665
#endif
666
667
#ifdef EPIPE
668
  ERRNO_CASE(EPIPE);
669
#endif
670
671
#ifdef EPROTO
672
  ERRNO_CASE(EPROTO);
673
#endif
674
675
#ifdef EPROTONOSUPPORT
676
  ERRNO_CASE(EPROTONOSUPPORT);
677
#endif
678
679
#ifdef EPROTOTYPE
680
  ERRNO_CASE(EPROTOTYPE);
681
#endif
682
683
#ifdef ERANGE
684
  ERRNO_CASE(ERANGE);
685
#endif
686
687
#ifdef EROFS
688
  ERRNO_CASE(EROFS);
689
#endif
690
691
#ifdef ESPIPE
692
  ERRNO_CASE(ESPIPE);
693
#endif
694
695
#ifdef ESRCH
696
1
  ERRNO_CASE(ESRCH);
697
#endif
698
699
#ifdef ESTALE
700
  ERRNO_CASE(ESTALE);
701
#endif
702
703
#ifdef ETIME
704
  ERRNO_CASE(ETIME);
705
#endif
706
707
#ifdef ETIMEDOUT
708
  ERRNO_CASE(ETIMEDOUT);
709
#endif
710
711
#ifdef ETXTBSY
712
  ERRNO_CASE(ETXTBSY);
713
#endif
714
715
#ifdef EXDEV
716
  ERRNO_CASE(EXDEV);
717
#endif
718
719
  default: return "";
720
  }
721
}
722
723
1390
const char *signo_string(int signo) {
724
#define SIGNO_CASE(e)  case e: return #e;
725








1390
  switch (signo) {
726
#ifdef SIGHUP
727
  SIGNO_CASE(SIGHUP);
728
#endif
729
730
#ifdef SIGINT
731
4
  SIGNO_CASE(SIGINT);
732
#endif
733
734
#ifdef SIGQUIT
735
  SIGNO_CASE(SIGQUIT);
736
#endif
737
738
#ifdef SIGILL
739
1
  SIGNO_CASE(SIGILL);
740
#endif
741
742
#ifdef SIGTRAP
743
  SIGNO_CASE(SIGTRAP);
744
#endif
745
746
#ifdef SIGABRT
747
7
  SIGNO_CASE(SIGABRT);
748
#endif
749
750
#ifdef SIGIOT
751
# if SIGABRT != SIGIOT
752
  SIGNO_CASE(SIGIOT);
753
# endif
754
#endif
755
756
#ifdef SIGBUS
757
  SIGNO_CASE(SIGBUS);
758
#endif
759
760
#ifdef SIGFPE
761
  SIGNO_CASE(SIGFPE);
762
#endif
763
764
#ifdef SIGKILL
765
5
  SIGNO_CASE(SIGKILL);
766
#endif
767
768
#ifdef SIGUSR1
769
  SIGNO_CASE(SIGUSR1);
770
#endif
771
772
#ifdef SIGSEGV
773
  SIGNO_CASE(SIGSEGV);
774
#endif
775
776
#ifdef SIGUSR2
777
  SIGNO_CASE(SIGUSR2);
778
#endif
779
780
#ifdef SIGPIPE
781
  SIGNO_CASE(SIGPIPE);
782
#endif
783
784
#ifdef SIGALRM
785
  SIGNO_CASE(SIGALRM);
786
#endif
787
788
157
  SIGNO_CASE(SIGTERM);
789
790
#ifdef SIGCHLD
791
  SIGNO_CASE(SIGCHLD);
792
#endif
793
794
#ifdef SIGSTKFLT
795
  SIGNO_CASE(SIGSTKFLT);
796
#endif
797
798
799
#ifdef SIGCONT
800
  SIGNO_CASE(SIGCONT);
801
#endif
802
803
#ifdef SIGSTOP
804
  SIGNO_CASE(SIGSTOP);
805
#endif
806
807
#ifdef SIGTSTP
808
  SIGNO_CASE(SIGTSTP);
809
#endif
810
811
#ifdef SIGBREAK
812
  SIGNO_CASE(SIGBREAK);
813
#endif
814
815
#ifdef SIGTTIN
816
  SIGNO_CASE(SIGTTIN);
817
#endif
818
819
#ifdef SIGTTOU
820
  SIGNO_CASE(SIGTTOU);
821
#endif
822
823
#ifdef SIGURG
824
  SIGNO_CASE(SIGURG);
825
#endif
826
827
#ifdef SIGXCPU
828
  SIGNO_CASE(SIGXCPU);
829
#endif
830
831
#ifdef SIGXFSZ
832
  SIGNO_CASE(SIGXFSZ);
833
#endif
834
835
#ifdef SIGVTALRM
836
  SIGNO_CASE(SIGVTALRM);
837
#endif
838
839
#ifdef SIGPROF
840
  SIGNO_CASE(SIGPROF);
841
#endif
842
843
#ifdef SIGWINCH
844
  SIGNO_CASE(SIGWINCH);
845
#endif
846
847
#ifdef SIGIO
848
  SIGNO_CASE(SIGIO);
849
#endif
850
851
#ifdef SIGPOLL
852
# if SIGPOLL != SIGIO
853
  SIGNO_CASE(SIGPOLL);
854
# endif
855
#endif
856
857
#ifdef SIGLOST
858
# if SIGLOST != SIGABRT
859
  SIGNO_CASE(SIGLOST);
860
# endif
861
#endif
862
863
#ifdef SIGPWR
864
# if SIGPWR != SIGLOST
865
  SIGNO_CASE(SIGPWR);
866
# endif
867
#endif
868
869
#ifdef SIGINFO
870
# if !defined(SIGPWR) || SIGINFO != SIGPWR
871
  SIGNO_CASE(SIGINFO);
872
# endif
873
#endif
874
875
#ifdef SIGSYS
876
  SIGNO_CASE(SIGSYS);
877
#endif
878
879
1216
  default: return "";
880
  }
881
}
882
883
884
4
Local<Value> ErrnoException(Isolate* isolate,
885
                            int errorno,
886
                            const char *syscall,
887
                            const char *msg,
888
                            const char *path) {
889
4
  Environment* env = Environment::GetCurrent(isolate);
890
891
  Local<Value> e;
892
4
  Local<String> estring = OneByteString(env->isolate(), errno_string(errorno));
893

4
  if (msg == nullptr || msg[0] == '\0') {
894
3
    msg = strerror(errorno);
895
  }
896
4
  Local<String> message = OneByteString(env->isolate(), msg);
897
898
  Local<String> cons =
899
4
      String::Concat(estring, FIXED_ONE_BYTE_STRING(env->isolate(), ", "));
900
4
  cons = String::Concat(cons, message);
901
902
  Local<String> path_string;
903
4
  if (path != nullptr) {
904
    // FIXME(bnoordhuis) It's questionable to interpret the file path as UTF-8.
905
1
    path_string = String::NewFromUtf8(env->isolate(), path);
906
  }
907
908
4
  if (path_string.IsEmpty() == false) {
909
1
    cons = String::Concat(cons, FIXED_ONE_BYTE_STRING(env->isolate(), " '"));
910
1
    cons = String::Concat(cons, path_string);
911
1
    cons = String::Concat(cons, FIXED_ONE_BYTE_STRING(env->isolate(), "'"));
912
  }
913
4
  e = Exception::Error(cons);
914
915
8
  Local<Object> obj = e->ToObject(env->isolate());
916
12
  obj->Set(env->errno_string(), Integer::New(env->isolate(), errorno));
917
8
  obj->Set(env->code_string(), estring);
918
919
4
  if (path_string.IsEmpty() == false) {
920
2
    obj->Set(env->path_string(), path_string);
921
  }
922
923
4
  if (syscall != nullptr) {
924
12
    obj->Set(env->syscall_string(), OneByteString(env->isolate(), syscall));
925
  }
926
927
4
  return e;
928
}
929
930
931
17049
static Local<String> StringFromPath(Isolate* isolate, const char* path) {
932
#ifdef _WIN32
933
  if (strncmp(path, "\\\\?\\UNC\\", 8) == 0) {
934
    return String::Concat(FIXED_ONE_BYTE_STRING(isolate, "\\\\"),
935
                          String::NewFromUtf8(isolate, path + 8));
936
  } else if (strncmp(path, "\\\\?\\", 4) == 0) {
937
    return String::NewFromUtf8(isolate, path + 4);
938
  }
939
#endif
940
941
17049
  return String::NewFromUtf8(isolate, path);
942
}
943
944
945
Local<Value> UVException(Isolate* isolate,
946
                         int errorno,
947
                         const char* syscall,
948
                         const char* msg,
949
                         const char* path) {
950
  return UVException(isolate, errorno, syscall, msg, path, nullptr);
951
}
952
953
954
17014
Local<Value> UVException(Isolate* isolate,
955
                         int errorno,
956
                         const char* syscall,
957
                         const char* msg,
958
                         const char* path,
959
                         const char* dest) {
960
17014
  Environment* env = Environment::GetCurrent(isolate);
961
962

17014
  if (!msg || !msg[0])
963
17014
    msg = uv_strerror(errorno);
964
965
17014
  Local<String> js_code = OneByteString(isolate, uv_err_name(errorno));
966
17014
  Local<String> js_syscall = OneByteString(isolate, syscall);
967
  Local<String> js_path;
968
  Local<String> js_dest;
969
970
17014
  Local<String> js_msg = js_code;
971
17014
  js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate, ": "));
972
17014
  js_msg = String::Concat(js_msg, OneByteString(isolate, msg));
973
17014
  js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate, ", "));
974
17014
  js_msg = String::Concat(js_msg, js_syscall);
975
976
17014
  if (path != nullptr) {
977
16972
    js_path = StringFromPath(isolate, path);
978
979
16972
    js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate, " '"));
980
16972
    js_msg = String::Concat(js_msg, js_path);
981
16972
    js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate, "'"));
982
  }
983
984
17014
  if (dest != nullptr) {
985
77
    js_dest = StringFromPath(isolate, dest);
986
987
77
    js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate, " -> '"));
988
77
    js_msg = String::Concat(js_msg, js_dest);
989
77
    js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate, "'"));
990
  }
991
992
34028
  Local<Object> e = Exception::Error(js_msg)->ToObject(isolate);
993
994
51042
  e->Set(env->errno_string(), Integer::New(isolate, errorno));
995
34028
  e->Set(env->code_string(), js_code);
996
34028
  e->Set(env->syscall_string(), js_syscall);
997
17014
  if (!js_path.IsEmpty())
998
33944
    e->Set(env->path_string(), js_path);
999
17014
  if (!js_dest.IsEmpty())
1000
154
    e->Set(env->dest_string(), js_dest);
1001
1002
17014
  return e;
1003
}
1004
1005
1006
// Look up environment variable unless running as setuid root.
1007
22630
bool SafeGetenv(const char* key, std::string* text) {
1008
#ifndef _WIN32
1009


22630
  if (linux_at_secure || getuid() != geteuid() || getgid() != getegid())
1010
    goto fail;
1011
#endif
1012
1013
22630
  if (const char* value = getenv(key)) {
1014
45
    *text = value;
1015
45
    return true;
1016
  }
1017
1018
fail:
1019
22585
  text->clear();
1020
22585
  return false;
1021
}
1022
1023
1024
#ifdef _WIN32
1025
// Does about the same as strerror(),
1026
// but supports all windows error messages
1027
static const char *winapi_strerror(const int errorno, bool* must_free) {
1028
  char *errmsg = nullptr;
1029
1030
  FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
1031
      FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, errorno,
1032
      MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&errmsg, 0, nullptr);
1033
1034
  if (errmsg) {
1035
    *must_free = true;
1036
1037
    // Remove trailing newlines
1038
    for (int i = strlen(errmsg) - 1;
1039
        i >= 0 && (errmsg[i] == '\n' || errmsg[i] == '\r'); i--) {
1040
      errmsg[i] = '\0';
1041
    }
1042
1043
    return errmsg;
1044
  } else {
1045
    // FormatMessage failed
1046
    *must_free = false;
1047
    return "Unknown error";
1048
  }
1049
}
1050
1051
1052
Local<Value> WinapiErrnoException(Isolate* isolate,
1053
                                  int errorno,
1054
                                  const char* syscall,
1055
                                  const char* msg,
1056
                                  const char* path) {
1057
  Environment* env = Environment::GetCurrent(isolate);
1058
  Local<Value> e;
1059
  bool must_free = false;
1060
  if (!msg || !msg[0]) {
1061
    msg = winapi_strerror(errorno, &must_free);
1062
  }
1063
  Local<String> message = OneByteString(env->isolate(), msg);
1064
1065
  if (path) {
1066
    Local<String> cons1 =
1067
        String::Concat(message, FIXED_ONE_BYTE_STRING(isolate, " '"));
1068
    Local<String> cons2 =
1069
        String::Concat(cons1, String::NewFromUtf8(isolate, path));
1070
    Local<String> cons3 =
1071
        String::Concat(cons2, FIXED_ONE_BYTE_STRING(isolate, "'"));
1072
    e = Exception::Error(cons3);
1073
  } else {
1074
    e = Exception::Error(message);
1075
  }
1076
1077
  Local<Object> obj = e->ToObject(env->isolate());
1078
  obj->Set(env->errno_string(), Integer::New(isolate, errorno));
1079
1080
  if (path != nullptr) {
1081
    obj->Set(env->path_string(), String::NewFromUtf8(isolate, path));
1082
  }
1083
1084
  if (syscall != nullptr) {
1085
    obj->Set(env->syscall_string(), OneByteString(isolate, syscall));
1086
  }
1087
1088
  if (must_free)
1089
    LocalFree((HLOCAL)msg);
1090
1091
  return e;
1092
}
1093
#endif
1094
1095
1096
47098
void* ArrayBufferAllocator::Allocate(size_t size) {
1097

47098
  if (zero_fill_field_ || zero_fill_all_buffers)
1098
3438
    return node::UncheckedCalloc(size);
1099
  else
1100
43660
    return node::UncheckedMalloc(size);
1101
}
1102
1103
namespace {
1104
1105
28
bool DomainHasErrorHandler(const Environment* env,
1106
                           const Local<Object>& domain) {
1107
28
  HandleScope scope(env->isolate());
1108
1109
56
  Local<Value> domain_event_listeners_v = domain->Get(env->events_string());
1110
28
  if (!domain_event_listeners_v->IsObject())
1111
    return false;
1112
1113
  Local<Object> domain_event_listeners_o =
1114
28
      domain_event_listeners_v.As<Object>();
1115
1116
  Local<Value> domain_error_listeners_v =
1117
56
      domain_event_listeners_o->Get(env->error_string());
1118
1119

140
  if (domain_error_listeners_v->IsFunction() ||
1120
1
      (domain_error_listeners_v->IsArray() &&
1121
28
      domain_error_listeners_v.As<Array>()->Length() > 0))
1122
27
    return true;
1123
1124
1
  return false;
1125
}
1126
1127
27
bool DomainsStackHasErrorHandler(const Environment* env) {
1128
27
  HandleScope scope(env->isolate());
1129
1130
27
  if (!env->using_domains())
1131
    return false;
1132
1133
54
  Local<Array> domains_stack_array = env->domains_stack_array().As<Array>();
1134
27
  if (domains_stack_array->Length() == 0)
1135
    return false;
1136
1137
27
  uint32_t domains_stack_length = domains_stack_array->Length();
1138
56
  for (uint32_t i = domains_stack_length; i > 0; --i) {
1139
56
    Local<Value> domain_v = domains_stack_array->Get(i - 1);
1140
28
    if (!domain_v->IsObject())
1141
27
      return false;
1142
1143
28
    Local<Object> domain = domain_v.As<Object>();
1144
28
    if (DomainHasErrorHandler(env, domain))
1145
27
      return true;
1146
  }
1147
1148
  return false;
1149
}
1150
1151
1152
27
bool ShouldAbortOnUncaughtException(Isolate* isolate) {
1153
27
  HandleScope scope(isolate);
1154
1155
27
  Environment* env = Environment::GetCurrent(isolate);
1156
27
  Local<Object> process_object = env->process_object();
1157
  Local<String> emitting_top_level_domain_error_key =
1158
27
    env->emitting_top_level_domain_error_string();
1159
  bool isEmittingTopLevelDomainError =
1160
54
      process_object->Get(emitting_top_level_domain_error_key)->BooleanValue();
1161
1162

27
  return isEmittingTopLevelDomainError || !DomainsStackHasErrorHandler(env);
1163
}
1164
1165
1166
4148
Local<Value> GetDomainProperty(Environment* env, Local<Object> object) {
1167
  Local<Value> domain_v =
1168
8296
      object->GetPrivate(env->context(), env->domain_private_symbol())
1169
8296
          .ToLocalChecked();
1170
4148
  if (domain_v->IsObject()) {
1171
2
    return domain_v;
1172
  }
1173
16584
  return object->Get(env->context(), env->domain_string()).ToLocalChecked();
1174
}
1175
1176
1177
2611
void DomainEnter(Environment* env, Local<Object> object) {
1178
2611
  Local<Value> domain_v = GetDomainProperty(env, object);
1179
2611
  if (domain_v->IsObject()) {
1180
88
    Local<Object> domain = domain_v.As<Object>();
1181
176
    Local<Value> enter_v = domain->Get(env->enter_string());
1182
88
    if (enter_v->IsFunction()) {
1183
264
      if (enter_v.As<Function>()->Call(domain, 0, nullptr).IsEmpty()) {
1184
        FatalError("node::AsyncWrap::MakeCallback",
1185
                   "domain enter callback threw, please report this");
1186
      }
1187
    }
1188
  }
1189
2611
}
1190
1191
1192
1537
void DomainExit(Environment* env, v8::Local<v8::Object> object) {
1193
1537
  Local<Value> domain_v = GetDomainProperty(env, object);
1194
1537
  if (domain_v->IsObject()) {
1195
67
    Local<Object> domain = domain_v.As<Object>();
1196
134
    Local<Value> exit_v = domain->Get(env->exit_string());
1197
67
    if (exit_v->IsFunction()) {
1198
201
      if (exit_v.As<Function>()->Call(domain, 0, nullptr).IsEmpty()) {
1199
        FatalError("node::AsyncWrap::MakeCallback",
1200
                  "domain exit callback threw, please report this");
1201
      }
1202
    }
1203
  }
1204
1537
}
1205
1206
1207
970
void DomainPromiseHook(PromiseHookType type,
1208
                       Local<Promise> promise,
1209
                       Local<Value> parent,
1210
                       void* arg) {
1211
970
  Environment* env = static_cast<Environment*>(arg);
1212
970
  Local<Context> context = env->context();
1213
1214

970
  if (type == PromiseHookType::kInit && env->in_domain()) {
1215
    Local<Value> domain_obj =
1216
174
        env->domain_array()->Get(context, 0).ToLocalChecked();
1217
116
    if (promise->CreationContext() == context) {
1218
168
      promise->Set(context, env->domain_string(), domain_obj).FromJust();
1219
    } else {
1220
      // Do not expose object from another context publicly in promises created
1221
      // in non-main contexts.
1222
4
      promise->SetPrivate(context, env->domain_private_symbol(), domain_obj)
1223
4
          .FromJust();
1224
    }
1225
1028
    return;
1226
  }
1227
1228
912
  if (type == PromiseHookType::kBefore) {
1229
158
    DomainEnter(env, promise);
1230
754
  } else if (type == PromiseHookType::kAfter) {
1231
158
    DomainExit(env, promise);
1232
  }
1233
}
1234
1235
1236
137
void SetupDomainUse(const FunctionCallbackInfo<Value>& args) {
1237
137
  Environment* env = Environment::GetCurrent(args);
1238
1239
137
  if (env->using_domains())
1240
137
    return;
1241
137
  env->set_using_domains(true);
1242
1243
137
  HandleScope scope(env->isolate());
1244
137
  Local<Object> process_object = env->process_object();
1245
1246
137
  Local<String> tick_callback_function_key = env->tick_domain_cb_string();
1247
  Local<Function> tick_callback_function =
1248
274
      process_object->Get(tick_callback_function_key).As<Function>();
1249
1250
137
  if (!tick_callback_function->IsFunction()) {
1251
    fprintf(stderr, "process._tickDomainCallback assigned to non-function\n");
1252
    ABORT();
1253
  }
1254
1255
274
  process_object->Set(env->tick_callback_string(), tick_callback_function);
1256
137
  env->set_tick_callback_function(tick_callback_function);
1257
1258
274
  CHECK(args[0]->IsArray());
1259
274
  env->set_domain_array(args[0].As<Array>());
1260
1261
274
  CHECK(args[1]->IsArray());
1262
274
  env->set_domains_stack_array(args[1].As<Array>());
1263
1264
  // Do a little housekeeping.
1265
  env->process_object()->Delete(
1266
      env->context(),
1267
685
      FIXED_ONE_BYTE_STRING(args.GetIsolate(), "_setupDomainUse")).FromJust();
1268
1269
137
  uint32_t* const fields = env->domain_flag()->fields();
1270
137
  uint32_t const fields_count = env->domain_flag()->fields_count();
1271
1272
  Local<ArrayBuffer> array_buffer =
1273
137
      ArrayBuffer::New(env->isolate(), fields, sizeof(*fields) * fields_count);
1274
1275
137
  env->AddPromiseHook(DomainPromiseHook, static_cast<void*>(env));
1276
1277
411
  args.GetReturnValue().Set(Uint32Array::New(array_buffer, 0, fields_count));
1278
}
1279
1280
1281
73086
void RunMicrotasks(const FunctionCallbackInfo<Value>& args) {
1282
73086
  args.GetIsolate()->RunMicrotasks();
1283
73080
}
1284
1285
1286
3200
void SetupProcessObject(const FunctionCallbackInfo<Value>& args) {
1287
3200
  Environment* env = Environment::GetCurrent(args);
1288
1289
6400
  CHECK(args[0]->IsFunction());
1290
1291
6400
  env->set_push_values_to_array_function(args[0].As<Function>());
1292
  env->process_object()->Delete(
1293
      env->context(),
1294
12800
      FIXED_ONE_BYTE_STRING(env->isolate(), "_setupProcessObject")).FromJust();
1295
3200
}
1296
1297
1298
3200
void SetupNextTick(const FunctionCallbackInfo<Value>& args) {
1299
3200
  Environment* env = Environment::GetCurrent(args);
1300
1301
6400
  CHECK(args[0]->IsFunction());
1302
6400
  CHECK(args[1]->IsObject());
1303
1304
6400
  env->set_tick_callback_function(args[0].As<Function>());
1305
1306
6400
  env->SetMethod(args[1].As<Object>(), "runMicrotasks", RunMicrotasks);
1307
1308
  // Do a little housekeeping.
1309
  env->process_object()->Delete(
1310
      env->context(),
1311
16000
      FIXED_ONE_BYTE_STRING(args.GetIsolate(), "_setupNextTick")).FromJust();
1312
1313
  // Values use to cross communicate with processNextTick.
1314
3200
  uint32_t* const fields = env->tick_info()->fields();
1315
3200
  uint32_t const fields_count = env->tick_info()->fields_count();
1316
1317
  Local<ArrayBuffer> array_buffer =
1318
3200
      ArrayBuffer::New(env->isolate(), fields, sizeof(*fields) * fields_count);
1319
1320
9600
  args.GetReturnValue().Set(Uint32Array::New(array_buffer, 0, fields_count));
1321
3200
}
1322
1323
7166
void PromiseRejectCallback(PromiseRejectMessage message) {
1324
7166
  Local<Promise> promise = message.GetPromise();
1325
7166
  Isolate* isolate = promise->GetIsolate();
1326
7166
  Local<Value> value = message.GetValue();
1327
7166
  Local<Integer> event = Integer::New(isolate, message.GetEvent());
1328
1329
7166
  Environment* env = Environment::GetCurrent(isolate);
1330
7166
  Local<Function> callback = env->promise_reject_function();
1331
1332
7166
  if (value.IsEmpty())
1333
91
    value = Undefined(isolate);
1334
1335
21498
  Local<Value> args[] = { event, promise, value };
1336
7166
  Local<Object> process = env->process_object();
1337
1338
14332
  callback->Call(process, arraysize(args), args);
1339
7166
}
1340
1341
3200
void SetupPromises(const FunctionCallbackInfo<Value>& args) {
1342
3200
  Environment* env = Environment::GetCurrent(args);
1343
3200
  Isolate* isolate = env->isolate();
1344
1345
6400
  CHECK(args[0]->IsFunction());
1346
1347
3200
  isolate->SetPromiseRejectCallback(PromiseRejectCallback);
1348
6400
  env->set_promise_reject_function(args[0].As<Function>());
1349
1350
  env->process_object()->Delete(
1351
      env->context(),
1352
12800
      FIXED_ONE_BYTE_STRING(isolate, "_setupPromises")).FromJust();
1353
3200
}
1354
1355
}  // anonymous namespace
1356
1357
1358
void AddPromiseHook(v8::Isolate* isolate, promise_hook_func fn, void* arg) {
1359
  Environment* env = Environment::GetCurrent(isolate);
1360
  env->AddPromiseHook(fn, arg);
1361
}
1362
1363
13
CallbackScope::CallbackScope(Isolate* isolate,
1364
                             Local<Object> object,
1365
                             async_context asyncContext)
1366
  : private_(new InternalCallbackScope(Environment::GetCurrent(isolate),
1367
                                       object,
1368
13
                                       asyncContext)),
1369
26
    try_catch_(isolate) {
1370
13
  try_catch_.SetVerbose(true);
1371
13
}
1372
1373
24
CallbackScope::~CallbackScope() {
1374
12
  if (try_catch_.HasCaught())
1375
1
    private_->MarkAsFailed();
1376
12
  delete private_;
1377
12
}
1378
1379
403141
InternalCallbackScope::InternalCallbackScope(Environment* env,
1380
                                             Local<Object> object,
1381
                                             const async_context& asyncContext,
1382
                                             ResourceExpectation expect)
1383
  : env_(env),
1384
    async_context_(asyncContext),
1385
    object_(object),
1386
403141
    callback_scope_(env) {
1387
403141
  if (expect == kRequireResource) {
1388
402417
    CHECK(!object.IsEmpty());
1389
  }
1390
1391
403141
  HandleScope handle_scope(env->isolate());
1392
  // If you hit this assertion, you forgot to enter the v8::Context first.
1393
403141
  CHECK_EQ(Environment::GetCurrent(env->isolate()), env);
1394
1395

405594
  if (env->using_domains() && !object_.IsEmpty()) {
1396
2453
    DomainEnter(env, object_);
1397
  }
1398
1399
403141
  if (asyncContext.async_id != 0) {
1400
    // No need to check a return value because the application will exit if
1401
    // an exception occurs.
1402
329847
    AsyncWrap::EmitBefore(env, asyncContext.async_id);
1403
  }
1404
1405
  env->async_hooks()->push_async_ids(async_context_.async_id,
1406
403141
                               async_context_.trigger_async_id);
1407
403141
  pushed_ids_ = true;
1408
403141
}
1409
1410
806010
InternalCallbackScope::~InternalCallbackScope() {
1411
403005
  Close();
1412
403005
}
1413
1414
804258
void InternalCallbackScope::Close() {
1415
1538603
  if (closed_) return;
1416
403084
  closed_ = true;
1417
403084
  HandleScope handle_scope(env_->isolate());
1418
1419
403084
  if (pushed_ids_)
1420
403084
    env_->async_hooks()->pop_async_id(async_context_.async_id);
1421
1422
403084
  if (failed_) return;
1423
1424
401988
  if (async_context_.async_id != 0) {
1425
329752
    AsyncWrap::EmitAfter(env_, async_context_.async_id);
1426
  }
1427
1428

403367
  if (env_->using_domains() && !object_.IsEmpty()) {
1429
1379
    DomainExit(env_, object_);
1430
  }
1431
1432
401988
  if (IsInnerMakeCallback()) {
1433
33334
    return;
1434
  }
1435
1436
368654
  Environment::TickInfo* tick_info = env_->tick_info();
1437
1438
368654
  if (tick_info->length() == 0) {
1439
298821
    env_->isolate()->RunMicrotasks();
1440
  }
1441
1442
  // Make sure the stack unwound properly. If there are nested MakeCallback's
1443
  // then it should return early and not reach this code.
1444
368653
  if (env_->async_hooks()->fields()[AsyncHooks::kTotals]) {
1445
60773
    CHECK_EQ(env_->execution_async_id(), 0);
1446
60773
    CHECK_EQ(env_->trigger_async_id(), 0);
1447
  }
1448
1449
368653
  Local<Object> process = env_->process_object();
1450
1451
368653
  if (tick_info->length() == 0) {
1452
298741
    tick_info->set_index(0);
1453
298741
    return;
1454
  }
1455
1456
69912
  if (env_->async_hooks()->fields()[AsyncHooks::kTotals]) {
1457
189
    CHECK_EQ(env_->execution_async_id(), 0);
1458
189
    CHECK_EQ(env_->trigger_async_id(), 0);
1459
  }
1460
1461
209658
  if (env_->tick_callback_function()->Call(process, 0, nullptr).IsEmpty()) {
1462
22
    failed_ = true;
1463
69834
  }
1464
}
1465
1466
402404
MaybeLocal<Value> InternalMakeCallback(Environment* env,
1467
                                       Local<Object> recv,
1468
                                       const Local<Function> callback,
1469
                                       int argc,
1470
                                       Local<Value> argv[],
1471
                                       async_context asyncContext) {
1472
402404
  CHECK(!recv.IsEmpty());
1473
402404
  InternalCallbackScope scope(env, recv, asyncContext);
1474
402404
  if (scope.Failed()) {
1475
    return Undefined(env->isolate());
1476
  }
1477
1478
  MaybeLocal<Value> ret;
1479
1480
  {
1481
804808
    ret = callback->Call(env->context(), recv, argc, argv);
1482
1483
402348
    if (ret.IsEmpty()) {
1484
      // NOTE: For backwards compatibility with public API we return Undefined()
1485
      // if the top level call threw.
1486
1095
      scope.MarkAsFailed();
1487
2190
      return scope.IsInnerMakeCallback() ? ret : Undefined(env->isolate());
1488
    }
1489
  }
1490
1491
401253
  scope.Close();
1492
401174
  if (scope.Failed()) {
1493
44
    return Undefined(env->isolate());
1494
  }
1495
1496
401152
  return ret;
1497
}
1498
1499
1500
// Public MakeCallback()s
1501
1502
1503
5745
MaybeLocal<Value> MakeCallback(Isolate* isolate,
1504
                               Local<Object> recv,
1505
                               const char* method,
1506
                               int argc,
1507
                               Local<Value> argv[],
1508
                               async_context asyncContext) {
1509
  Local<String> method_string =
1510
      String::NewFromUtf8(isolate, method, v8::NewStringType::kNormal)
1511
11490
          .ToLocalChecked();
1512
5745
  return MakeCallback(isolate, recv, method_string, argc, argv, asyncContext);
1513
}
1514
1515
1516
72527
MaybeLocal<Value> MakeCallback(Isolate* isolate,
1517
                               Local<Object> recv,
1518
                               Local<String> symbol,
1519
                               int argc,
1520
                               Local<Value> argv[],
1521
                               async_context asyncContext) {
1522
72527
  Local<Value> callback_v = recv->Get(symbol);
1523
72527
  if (callback_v.IsEmpty()) return Local<Value>();
1524
72527
  if (!callback_v->IsFunction()) return Local<Value>();
1525
72527
  Local<Function> callback = callback_v.As<Function>();
1526
72527
  return MakeCallback(isolate, recv, callback, argc, argv, asyncContext);
1527
}
1528
1529
1530
72579
MaybeLocal<Value> MakeCallback(Isolate* isolate,
1531
                               Local<Object> recv,
1532
                               Local<Function> callback,
1533
                               int argc,
1534
                               Local<Value> argv[],
1535
                               async_context asyncContext) {
1536
  // Observe the following two subtleties:
1537
  //
1538
  // 1. The environment is retrieved from the callback function's context.
1539
  // 2. The context to enter is retrieved from the environment.
1540
  //
1541
  // Because of the AssignToContext() call in src/node_contextify.cc,
1542
  // the two contexts need not be the same.
1543
72579
  Environment* env = Environment::GetCurrent(callback->CreationContext());
1544
72579
  Context::Scope context_scope(env->context());
1545
  return InternalMakeCallback(env, recv, callback,
1546
145148
                              argc, argv, asyncContext);
1547
}
1548
1549
1550
// Legacy MakeCallback()s
1551
1552
Local<Value> MakeCallback(Isolate* isolate,
1553
                          Local<Object> recv,
1554
                          const char* method,
1555
                          int argc,
1556
                          Local<Value>* argv) {
1557
  EscapableHandleScope handle_scope(isolate);
1558
  return handle_scope.Escape(
1559
      MakeCallback(isolate, recv, method, argc, argv, {0, 0})
1560
          .FromMaybe(Local<Value>()));
1561
}
1562
1563
1564
5
Local<Value> MakeCallback(Isolate* isolate,
1565
    Local<Object> recv,
1566
    Local<String> symbol,
1567
    int argc,
1568
    Local<Value>* argv) {
1569
5
  EscapableHandleScope handle_scope(isolate);
1570
  return handle_scope.Escape(
1571
5
      MakeCallback(isolate, recv, symbol, argc, argv, {0, 0})
1572
15
          .FromMaybe(Local<Value>()));
1573
}
1574
1575
1576
24
Local<Value> MakeCallback(Isolate* isolate,
1577
    Local<Object> recv,
1578
    Local<Function> callback,
1579
    int argc,
1580
    Local<Value>* argv) {
1581
24
  EscapableHandleScope handle_scope(isolate);
1582
  return handle_scope.Escape(
1583
24
      MakeCallback(isolate, recv, callback, argc, argv, {0, 0})
1584
72
          .FromMaybe(Local<Value>()));
1585
}
1586
1587
1588
205425
enum encoding ParseEncoding(const char* encoding,
1589
                            enum encoding default_encoding) {
1590

205425
  switch (encoding[0]) {
1591
    case 'u':
1592
      // utf8, utf16le
1593

109668
      if (encoding[1] == 't' && encoding[2] == 'f') {
1594
        // Skip `-`
1595
109477
        encoding += encoding[3] == '-' ? 4 : 3;
1596

109477
        if (encoding[0] == '8' && encoding[1] == '\0')
1597
109460
          return UTF8;
1598
17
        if (strncmp(encoding, "16le", 4) == 0)
1599
17
          return UCS2;
1600
1601
      // ucs2
1602

191
      } else if (encoding[1] == 'c' && encoding[2] == 's') {
1603
190
        encoding += encoding[3] == '-' ? 4 : 3;
1604

190
        if (encoding[0] == '2' && encoding[1] == '\0')
1605
190
          return UCS2;
1606
      }
1607
1
      break;
1608
    case 'l':
1609
      // latin1
1610
52333
      if (encoding[1] == 'a') {
1611
52331
        if (strncmp(encoding + 2, "tin1", 4) == 0)
1612
52331
          return LATIN1;
1613
      }
1614
2
      break;
1615
    case 'b':
1616
      // binary
1617
20920
      if (encoding[1] == 'i') {
1618
30
        if (strncmp(encoding + 2, "nary", 4) == 0)
1619
30
          return LATIN1;
1620
1621
      // buffer
1622
20890
      } else if (encoding[1] == 'u') {
1623
20609
        if (strncmp(encoding + 2, "ffer", 4) == 0)
1624
20609
          return BUFFER;
1625
      }
1626
281
      break;
1627
    case '\0':
1628
1
      return default_encoding;
1629
    default:
1630
22503
      break;
1631
  }
1632
1633
22787
  if (StringEqualNoCase(encoding, "utf8")) {
1634
    return UTF8;
1635
22787
  } else if (StringEqualNoCase(encoding, "utf-8")) {
1636
3
    return UTF8;
1637
22784
  } else if (StringEqualNoCase(encoding, "ascii")) {
1638
49
    return ASCII;
1639
22735
  } else if (StringEqualNoCase(encoding, "base64")) {
1640
279
    return BASE64;
1641
22456
  } else if (StringEqualNoCase(encoding, "ucs2")) {
1642
    return UCS2;
1643
22456
  } else if (StringEqualNoCase(encoding, "ucs-2")) {
1644
    return UCS2;
1645
22456
  } else if (StringEqualNoCase(encoding, "utf16le")) {
1646
    return UCS2;
1647
22456
  } else if (StringEqualNoCase(encoding, "utf-16le")) {
1648
    return UCS2;
1649
22456
  } else if (StringEqualNoCase(encoding, "latin1")) {
1650
    return LATIN1;
1651
22456
  } else if (StringEqualNoCase(encoding, "binary")) {
1652
    return LATIN1;  // BINARY is a deprecated alias of LATIN1.
1653
22456
  } else if (StringEqualNoCase(encoding, "buffer")) {
1654
    return BUFFER;
1655
22456
  } else if (StringEqualNoCase(encoding, "hex")) {
1656
22451
    return HEX;
1657
  } else {
1658
5
    return default_encoding;
1659
  }
1660
}
1661
1662
1663
209255
enum encoding ParseEncoding(Isolate* isolate,
1664
                            Local<Value> encoding_v,
1665
                            enum encoding default_encoding) {
1666
209255
  CHECK(!encoding_v.IsEmpty());
1667
1668
418510
  if (!encoding_v->IsString())
1669
3830
    return default_encoding;
1670
1671
205425
  node::Utf8Value encoding(isolate, encoding_v);
1672
1673
205425
  return ParseEncoding(*encoding, default_encoding);
1674
}
1675
1676
2
Local<Value> Encode(Isolate* isolate,
1677
                    const char* buf,
1678
                    size_t len,
1679
                    enum encoding encoding) {
1680
2
  CHECK_NE(encoding, UCS2);
1681
  Local<Value> error;
1682
  return StringBytes::Encode(isolate, buf, len, encoding, &error)
1683
4
      .ToLocalChecked();
1684
}
1685
1686
Local<Value> Encode(Isolate* isolate, const uint16_t* buf, size_t len) {
1687
  Local<Value> error;
1688
  return StringBytes::Encode(isolate, buf, len, &error)
1689
      .ToLocalChecked();
1690
}
1691
1692
// Returns -1 if the handle was not valid for decoding
1693
ssize_t DecodeBytes(Isolate* isolate,
1694
                    Local<Value> val,
1695
                    enum encoding encoding) {
1696
  HandleScope scope(isolate);
1697
1698
  return StringBytes::Size(isolate, val, encoding);
1699
}
1700
1701
// Returns number of bytes written.
1702
ssize_t DecodeWrite(Isolate* isolate,
1703
                    char* buf,
1704
                    size_t buflen,
1705
                    Local<Value> val,
1706
                    enum encoding encoding) {
1707
  return StringBytes::Write(isolate, buf, buflen, val, encoding, nullptr);
1708
}
1709
1710
435
bool IsExceptionDecorated(Environment* env, Local<Value> er) {
1711

870
  if (!er.IsEmpty() && er->IsObject()) {
1712
429
    Local<Object> err_obj = er.As<Object>();
1713
    auto maybe_value =
1714
858
        err_obj->GetPrivate(env->context(), env->decorated_private_symbol());
1715
    Local<Value> decorated;
1716

858
    return maybe_value.ToLocal(&decorated) && decorated->IsTrue();
1717
  }
1718
6
  return false;
1719
}
1720
1721
432
void AppendExceptionLine(Environment* env,
1722
                         Local<Value> er,
1723
                         Local<Message> message,
1724
                         enum ErrorHandlingMode mode) {
1725
432
  if (message.IsEmpty())
1726
54
    return;
1727
1728
432
  HandleScope scope(env->isolate());
1729
  Local<Object> err_obj;
1730

864
  if (!er.IsEmpty() && er->IsObject()) {
1731
426
    err_obj = er.As<Object>();
1732
1733
426
    auto context = env->context();
1734
426
    auto processed_private_symbol = env->processed_private_symbol();
1735
    // Do it only once per message
1736
852
    if (err_obj->HasPrivate(context, processed_private_symbol).FromJust())
1737
44
      return;
1738
    err_obj->SetPrivate(
1739
        context,
1740
        processed_private_symbol,
1741
764
        True(env->isolate()));
1742
  }
1743
1744
  // Print (filename):(line number): (message).
1745
388
  ScriptOrigin origin = message->GetScriptOrigin();
1746
766
  node::Utf8Value filename(env->isolate(), message->GetScriptResourceName());
1747
388
  const char* filename_string = *filename;
1748
388
  int linenum = message->GetLineNumber();
1749
  // Print line of source code.
1750
1154
  node::Utf8Value sourceline(env->isolate(), message->GetSourceLine());
1751
388
  const char* sourceline_string = *sourceline;
1752
1753
  // Because of how node modules work, all scripts are wrapped with a
1754
  // "function (module, exports, __filename, ...) {"
1755
  // to provide script local variables.
1756
  //
1757
  // When reporting errors on the first line of a script, this wrapper
1758
  // function is leaked to the user. There used to be a hack here to
1759
  // truncate off the first 62 characters, but it caused numerous other
1760
  // problems when vm.runIn*Context() methods were used for non-module
1761
  // code.
1762
  //
1763
  // If we ever decide to re-instate such a hack, the following steps
1764
  // must be taken:
1765
  //
1766
  // 1. Pass a flag around to say "this code was wrapped"
1767
  // 2. Update the stack frame output so that it is also correct.
1768
  //
1769
  // It would probably be simpler to add a line rather than add some
1770
  // number of characters to the first line, since V8 truncates the
1771
  // sourceline to 78 characters, and we end up not providing very much
1772
  // useful debugging info to the user if we remove 62 characters.
1773
1774
  int script_start =
1775
1552
      (linenum - origin.ResourceLineOffset()->Value()) == 1 ?
1776

674
          origin.ResourceColumnOffset()->Value() : 0;
1777
1164
  int start = message->GetStartColumn(env->context()).FromMaybe(0);
1778
1164
  int end = message->GetEndColumn(env->context()).FromMaybe(0);
1779
388
  if (start >= script_start) {
1780
388
    CHECK_GE(end, start);
1781
388
    start -= script_start;
1782
388
    end -= script_start;
1783
  }
1784
1785
  char arrow[1024];
1786
388
  int max_off = sizeof(arrow) - 2;
1787
1788
  int off = snprintf(arrow,
1789
                     sizeof(arrow),
1790
                     "%s:%i\n%s\n",
1791
                     filename_string,
1792
                     linenum,
1793
388
                     sourceline_string);
1794
388
  CHECK_GE(off, 0);
1795
388
  if (off > max_off) {
1796
123
    off = max_off;
1797
  }
1798
1799
  // Print wavy underline (GetUnderline is deprecated).
1800
9223
  for (int i = 0; i < start; i++) {
1801

8962
    if (sourceline_string[i] == '\0' || off >= max_off) {
1802
      break;
1803
    }
1804
8835
    CHECK_LT(off, max_off);
1805
8835
    arrow[off++] = (sourceline_string[i] == '\t') ? '\t' : ' ';
1806
  }
1807
1078
  for (int i = start; i < end; i++) {
1808

837
    if (sourceline_string[i] == '\0' || off >= max_off) {
1809
      break;
1810
    }
1811
690
    CHECK_LT(off, max_off);
1812
690
    arrow[off++] = '^';
1813
  }
1814
388
  CHECK_LE(off, max_off);
1815
388
  arrow[off] = '\n';
1816
388
  arrow[off + 1] = '\0';
1817
1818
388
  Local<String> arrow_str = String::NewFromUtf8(env->isolate(), arrow);
1819
1820

776
  const bool can_set_arrow = !arrow_str.IsEmpty() && !err_obj.IsEmpty();
1821
  // If allocating arrow_str failed, print it out. There's not much else to do.
1822
  // If it's not an error, but something needs to be printed out because
1823
  // it's a fatal exception, also print it out from here.
1824
  // Otherwise, the arrow property will be attached to the object and handled
1825
  // by the caller.
1826


465
  if (!can_set_arrow || (mode == FATAL_ERROR && !err_obj->IsNativeError())) {
1827
10
    if (env->printed_error())
1828
      return;
1829
10
    env->set_printed_error(true);
1830
1831
10
    uv_tty_reset_mode();
1832
10
    PrintErrorString("\n%s", arrow);
1833
10
    return;
1834
  }
1835
1836

1512
  CHECK(err_obj->SetPrivate(
1837
            env->context(),
1838
            env->arrow_message_private_symbol(),
1839
378
            arrow_str).FromMaybe(false));
1840
}
1841
1842
1843
127
static void ReportException(Environment* env,
1844
                            Local<Value> er,
1845
                            Local<Message> message) {
1846
127
  HandleScope scope(env->isolate());
1847
1848
127
  AppendExceptionLine(env, er, message, FATAL_ERROR);
1849
1850
  Local<Value> trace_value;
1851
  Local<Value> arrow;
1852
127
  const bool decorated = IsExceptionDecorated(env, er);
1853
1854

506
  if (er->IsUndefined() || er->IsNull()) {
1855
4
    trace_value = Undefined(env->isolate());
1856
  } else {
1857
250
    Local<Object> err_obj = er->ToObject(env->isolate());
1858
1859
250
    trace_value = err_obj->Get(env->stack_string());
1860
    arrow =
1861
        err_obj->GetPrivate(
1862
            env->context(),
1863
375
            env->arrow_message_private_symbol()).ToLocalChecked();
1864
  }
1865
1866
254
  node::Utf8Value trace(env->isolate(), trace_value);
1867
1868
  // range errors have a trace member set to undefined
1869

381
  if (trace.length() > 0 && !trace_value->IsUndefined()) {
1870


351
    if (arrow.IsEmpty() || !arrow->IsString() || decorated) {
1871
44
      PrintErrorString("%s\n", *trace);
1872
    } else {
1873
73
      node::Utf8Value arrow_string(env->isolate(), arrow);
1874
73
      PrintErrorString("%s\n%s\n", *arrow_string, *trace);
1875
    }
1876
  } else {
1877
    // this really only happens for RangeErrors, since they're the only
1878
    // kind that won't have all this info in the trace, or when non-Error
1879
    // objects are thrown manually.
1880
    Local<Value> message;
1881
    Local<Value> name;
1882
1883
10
    if (er->IsObject()) {
1884
4
      Local<Object> err_obj = er.As<Object>();
1885
8
      message = err_obj->Get(env->message_string());
1886
8
      name = err_obj->Get(FIXED_ONE_BYTE_STRING(env->isolate(), "name"));
1887
    }
1888
1889

24
    if (message.IsEmpty() ||
1890
9
        message->IsUndefined() ||
1891

12
        name.IsEmpty() ||
1892
2
        name->IsUndefined()) {
1893
      // Not an error object. Just print as-is.
1894
9
      String::Utf8Value message(er);
1895
1896
9
      PrintErrorString("%s\n", *message ? *message :
1897
9
                                          "<toString() threw exception>");
1898
    } else {
1899
1
      node::Utf8Value name_string(env->isolate(), name);
1900
2
      node::Utf8Value message_string(env->isolate(), message);
1901
1902


3
      if (arrow.IsEmpty() || !arrow->IsString() || decorated) {
1903
1
        PrintErrorString("%s: %s\n", *name_string, *message_string);
1904
      } else {
1905
        node::Utf8Value arrow_string(env->isolate(), arrow);
1906
        PrintErrorString("%s\n%s: %s\n",
1907
                         *arrow_string,
1908
                         *name_string,
1909
                         *message_string);
1910
1
      }
1911
    }
1912
  }
1913
1914
254
  fflush(stderr);
1915
127
}
1916
1917
1918
2
static void ReportException(Environment* env, const TryCatch& try_catch) {
1919
2
  ReportException(env, try_catch.Exception(), try_catch.Message());
1920
2
}
1921
1922
1923
// Executes a str within the current v8 context.
1924
3200
static Local<Value> ExecuteString(Environment* env,
1925
                                  Local<String> source,
1926
                                  Local<String> filename) {
1927
3200
  EscapableHandleScope scope(env->isolate());
1928
6400
  TryCatch try_catch(env->isolate());
1929
1930
  // try_catch must be nonverbose to disable FatalException() handler,
1931
  // we will handle exceptions ourself.
1932
3200
  try_catch.SetVerbose(false);
1933
1934
3200
  ScriptOrigin origin(filename);
1935
  MaybeLocal<v8::Script> script =
1936
3200
      v8::Script::Compile(env->context(), source, &origin);
1937
3200
  if (script.IsEmpty()) {
1938
    ReportException(env, try_catch);
1939
    exit(3);
1940
  }
1941
1942
6400
  Local<Value> result = script.ToLocalChecked()->Run();
1943
3200
  if (result.IsEmpty()) {
1944
    ReportException(env, try_catch);
1945
    exit(4);
1946
  }
1947
1948
3200
  return scope.Escape(result);
1949
}
1950
1951
1952
1
static void GetActiveRequests(const FunctionCallbackInfo<Value>& args) {
1953
1
  Environment* env = Environment::GetCurrent(args);
1954
1955
1
  Local<Array> ary = Array::New(args.GetIsolate());
1956
1
  Local<Context> ctx = env->context();
1957
1
  Local<Function> fn = env->push_values_to_array_function();
1958
9
  Local<Value> argv[NODE_PUSH_VAL_TO_ARRAY_MAX];
1959
1
  size_t idx = 0;
1960
1961
13
  for (auto w : *env->req_wrap_queue()) {
1962
24
    if (w->persistent().IsEmpty())
1963
      continue;
1964
24
    argv[idx] = w->object();
1965
12
    if (++idx >= arraysize(argv)) {
1966
3
      fn->Call(ctx, ary, idx, argv).ToLocalChecked();
1967
1
      idx = 0;
1968
    }
1969
  }
1970
1971
1
  if (idx > 0) {
1972
3
    fn->Call(ctx, ary, idx, argv).ToLocalChecked();
1973
  }
1974
1975
2
  args.GetReturnValue().Set(ary);
1976
1
}
1977
1978
1979
// Non-static, friend of HandleWrap. Could have been a HandleWrap method but
1980
// implemented here for consistency with GetActiveRequests().
1981
6
void GetActiveHandles(const FunctionCallbackInfo<Value>& args) {
1982
6
  Environment* env = Environment::GetCurrent(args);
1983
1984
6
  Local<Array> ary = Array::New(env->isolate());
1985
6
  Local<Context> ctx = env->context();
1986
6
  Local<Function> fn = env->push_values_to_array_function();
1987
54
  Local<Value> argv[NODE_PUSH_VAL_TO_ARRAY_MAX];
1988
6
  size_t idx = 0;
1989
1990
6
  Local<String> owner_sym = env->owner_string();
1991
1992
35
  for (auto w : *env->handle_wrap_queue()) {
1993

58
    if (w->persistent().IsEmpty() || !HandleWrap::HasRef(w))
1994
1
      continue;
1995
28
    Local<Object> object = w->object();
1996
28
    Local<Value> owner = object->Get(owner_sym);
1997
56
    if (owner->IsUndefined())
1998
5
      owner = object;
1999
28
    argv[idx] = owner;
2000
28
    if (++idx >= arraysize(argv)) {
2001
6
      fn->Call(ctx, ary, idx, argv).ToLocalChecked();
2002
2
      idx = 0;
2003
    }
2004
  }
2005
6
  if (idx > 0) {
2006
15
    fn->Call(ctx, ary, idx, argv).ToLocalChecked();
2007
  }
2008
2009
12
  args.GetReturnValue().Set(ary);
2010
6
}
2011
2012
2013
NO_RETURN void Abort() {
2014
  DumpBacktrace(stderr);
2015
  fflush(stderr);
2016
  ABORT_NO_BACKTRACE();
2017
}
2018
2019
2020
NO_RETURN void Assert(const char* const (*args)[4]) {
2021
  auto filename = (*args)[0];
2022
  auto linenum = (*args)[1];
2023
  auto message = (*args)[2];
2024
  auto function = (*args)[3];
2025
2026
  char exepath[256];
2027
  size_t exepath_size = sizeof(exepath);
2028
  if (uv_exepath(exepath, &exepath_size))
2029
    snprintf(exepath, sizeof(exepath), "node");
2030
2031
  char pid[12] = {0};
2032
#ifndef _WIN32
2033
  snprintf(pid, sizeof(pid), "[%u]", getpid());
2034
#endif
2035
2036
  fprintf(stderr, "%s%s: %s:%s:%s%s Assertion `%s' failed.\n",
2037
          exepath, pid, filename, linenum,
2038
          function, *function ? ":" : "", message);
2039
  fflush(stderr);
2040
2041
  Abort();
2042
}
2043
2044
2045
static void Abort(const FunctionCallbackInfo<Value>& args) {
2046
  Abort();
2047
}
2048
2049
2050
99
static void Chdir(const FunctionCallbackInfo<Value>& args) {
2051
99
  Environment* env = Environment::GetCurrent(args);
2052
2053


489
  if (args.Length() != 1 || !args[0]->IsString()) {
2054
6
    return env->ThrowTypeError("Bad argument.");
2055
  }
2056
2057
96
  node::Utf8Value path(args.GetIsolate(), args[0]);
2058
96
  int err = uv_chdir(*path);
2059
96
  if (err) {
2060
    return env->ThrowUVException(err, "uv_chdir");
2061
96
  }
2062
}
2063
2064
2065
10332
static void Cwd(const FunctionCallbackInfo<Value>& args) {
2066
10332
  Environment* env = Environment::GetCurrent(args);
2067
#ifdef _WIN32
2068
  /* MAX_PATH is in characters, not bytes. Make sure we have enough headroom. */
2069
  char buf[MAX_PATH * 4];
2070
#else
2071
  char buf[PATH_MAX];
2072
#endif
2073
2074
10332
  size_t cwd_len = sizeof(buf);
2075
10332
  int err = uv_cwd(buf, &cwd_len);
2076
10332
  if (err) {
2077
10345
    return env->ThrowUVException(err, "uv_cwd");
2078
  }
2079
2080
  Local<String> cwd = String::NewFromUtf8(env->isolate(),
2081
                                          buf,
2082
                                          String::kNormalString,
2083
10319
                                          cwd_len);
2084
20638
  args.GetReturnValue().Set(cwd);
2085
}
2086
2087
2088
9860
static void Umask(const FunctionCallbackInfo<Value>& args) {
2089
9860
  Environment* env = Environment::GetCurrent(args);
2090
  uint32_t old;
2091
2092


19735
  if (args.Length() < 1 || args[0]->IsUndefined()) {
2093
9855
    old = umask(0);
2094
9855
    umask(static_cast<mode_t>(old));
2095


24
  } else if (!args[0]->IsInt32() && !args[0]->IsString()) {
2096
1
    return env->ThrowTypeError("argument must be an integer or octal string.");
2097
  } else {
2098
    int oct;
2099
8
    if (args[0]->IsInt32()) {
2100
4
      oct = args[0]->Uint32Value();
2101
    } else {
2102
2
      oct = 0;
2103
2
      node::Utf8Value str(env->isolate(), args[0]);
2104
2105
      // Parse the octal string.
2106

9
      for (size_t i = 0; i < str.length(); i++) {
2107
8
        char c = (*str)[i];
2108

8
        if (c > '7' || c < '0') {
2109
1
          return env->ThrowTypeError("invalid octal string");
2110
        }
2111
7
        oct *= 8;
2112
7
        oct += c - '0';
2113
1
      }
2114
    }
2115
3
    old = umask(static_cast<mode_t>(oct));
2116
  }
2117
2118
19716
  args.GetReturnValue().Set(old);
2119
}
2120
2121
2122
#if defined(__POSIX__) && !defined(__ANDROID__)
2123
2124
static const uid_t uid_not_found = static_cast<uid_t>(-1);
2125
static const gid_t gid_not_found = static_cast<gid_t>(-1);
2126
2127
2128
4
static uid_t uid_by_name(const char* name) {
2129
  struct passwd pwd;
2130
  struct passwd* pp;
2131
  char buf[8192];
2132
2133
4
  errno = 0;
2134
4
  pp = nullptr;
2135
2136

4
  if (getpwnam_r(name, &pwd, buf, sizeof(buf), &pp) == 0 && pp != nullptr) {
2137
2
    return pp->pw_uid;
2138
  }
2139
2140
2
  return uid_not_found;
2141
}
2142
2143
2144
static char* name_by_uid(uid_t uid) {
2145
  struct passwd pwd;
2146
  struct passwd* pp;
2147
  char buf[8192];
2148
  int rc;
2149
2150
  errno = 0;
2151
  pp = nullptr;
2152
2153
  if ((rc = getpwuid_r(uid, &pwd, buf, sizeof(buf), &pp)) == 0 &&
2154
      pp != nullptr) {
2155
    return strdup(pp->pw_name);
2156
  }
2157
2158
  if (rc == 0) {
2159
    errno = ENOENT;
2160
  }
2161
2162
  return nullptr;
2163
}
2164
2165
2166
2
static gid_t gid_by_name(const char* name) {
2167
  struct group pwd;
2168
  struct group* pp;
2169
  char buf[8192];
2170
2171
2
  errno = 0;
2172
2
  pp = nullptr;
2173
2174

2
  if (getgrnam_r(name, &pwd, buf, sizeof(buf), &pp) == 0 && pp != nullptr) {
2175
    return pp->gr_gid;
2176
  }
2177
2178
2
  return gid_not_found;
2179
}
2180
2181
2182
#if 0  // For future use.
2183
static const char* name_by_gid(gid_t gid) {
2184
  struct group pwd;
2185
  struct group* pp;
2186
  char buf[8192];
2187
  int rc;
2188
2189
  errno = 0;
2190
  pp = nullptr;
2191
2192
  if ((rc = getgrgid_r(gid, &pwd, buf, sizeof(buf), &pp)) == 0 &&
2193
      pp != nullptr) {
2194
    return strdup(pp->gr_name);
2195
  }
2196
2197
  if (rc == 0) {
2198
    errno = ENOENT;
2199
  }
2200
2201
  return nullptr;
2202
}
2203
#endif
2204
2205
2206
4
static uid_t uid_by_name(Isolate* isolate, Local<Value> value) {
2207
4
  if (value->IsUint32()) {
2208
    return static_cast<uid_t>(value->Uint32Value());
2209
  } else {
2210
4
    node::Utf8Value name(isolate, value);
2211
4
    return uid_by_name(*name);
2212
  }
2213
}
2214
2215
2216
2
static gid_t gid_by_name(Isolate* isolate, Local<Value> value) {
2217
2
  if (value->IsUint32()) {
2218
    return static_cast<gid_t>(value->Uint32Value());
2219
  } else {
2220
2
    node::Utf8Value name(isolate, value);
2221
2
    return gid_by_name(*name);
2222
  }
2223
}
2224
2225
359
static void GetUid(const FunctionCallbackInfo<Value>& args) {
2226
  // uid_t is an uint32_t on all supported platforms.
2227
1077
  args.GetReturnValue().Set(static_cast<uint32_t>(getuid()));
2228
359
}
2229
2230
2231
282
static void GetGid(const FunctionCallbackInfo<Value>& args) {
2232
  // gid_t is an uint32_t on all supported platforms.
2233
846
  args.GetReturnValue().Set(static_cast<uint32_t>(getgid()));
2234
282
}
2235
2236
2237
1
static void GetEUid(const FunctionCallbackInfo<Value>& args) {
2238
  // uid_t is an uint32_t on all supported platforms.
2239
3
  args.GetReturnValue().Set(static_cast<uint32_t>(geteuid()));
2240
1
}
2241
2242
2243
1
static void GetEGid(const FunctionCallbackInfo<Value>& args) {
2244
  // gid_t is an uint32_t on all supported platforms.
2245
3
  args.GetReturnValue().Set(static_cast<uint32_t>(getegid()));
2246
1
}
2247
2248
2249
1
static void SetGid(const FunctionCallbackInfo<Value>& args) {
2250
1
  Environment* env = Environment::GetCurrent(args);
2251
2252


6
  if (!args[0]->IsUint32() && !args[0]->IsString()) {
2253
    return env->ThrowTypeError("setgid argument must be a number or a string");
2254
  }
2255
2256
1
  gid_t gid = gid_by_name(env->isolate(), args[0]);
2257
2258
1
  if (gid == gid_not_found) {
2259
1
    return env->ThrowError("setgid group id does not exist");
2260
  }
2261
2262
  if (setgid(gid)) {
2263
    return env->ThrowErrnoException(errno, "setgid");
2264
  }
2265
}
2266
2267
2268
1
static void SetEGid(const FunctionCallbackInfo<Value>& args) {
2269
1
  Environment* env = Environment::GetCurrent(args);
2270
2271


6
  if (!args[0]->IsUint32() && !args[0]->IsString()) {
2272
    return env->ThrowTypeError("setegid argument must be a number or string");
2273
  }
2274
2275
1
  gid_t gid = gid_by_name(env->isolate(), args[0]);
2276
2277
1
  if (gid == gid_not_found) {
2278
1
    return env->ThrowError("setegid group id does not exist");
2279
  }
2280
2281
  if (setegid(gid)) {
2282
    return env->ThrowErrnoException(errno, "setegid");
2283
  }
2284
}
2285
2286
2287
2
static void SetUid(const FunctionCallbackInfo<Value>& args) {
2288
2
  Environment* env = Environment::GetCurrent(args);
2289
2290


12
  if (!args[0]->IsUint32() && !args[0]->IsString()) {
2291
    return env->ThrowTypeError("setuid argument must be a number or a string");
2292
  }
2293
2294
2
  uid_t uid = uid_by_name(env->isolate(), args[0]);
2295
2296
2
  if (uid == uid_not_found) {
2297
1
    return env->ThrowError("setuid user id does not exist");
2298
  }
2299
2300
1
  if (setuid(uid)) {
2301
1
    return env->ThrowErrnoException(errno, "setuid");
2302
  }
2303
}
2304
2305
2306
3
static void SetEUid(const FunctionCallbackInfo<Value>& args) {
2307
3
  Environment* env = Environment::GetCurrent(args);
2308
2309


18
  if (!args[0]->IsUint32() && !args[0]->IsString()) {
2310
1
    return env->ThrowTypeError("seteuid argument must be a number or string");
2311
  }
2312
2313
2
  uid_t uid = uid_by_name(env->isolate(), args[0]);
2314
2315
2
  if (uid == uid_not_found) {
2316
1
    return env->ThrowError("seteuid user id does not exist");
2317
  }
2318
2319
1
  if (seteuid(uid)) {
2320
1
    return env->ThrowErrnoException(errno, "seteuid");
2321
  }
2322
}
2323
2324
2325
2
static void GetGroups(const FunctionCallbackInfo<Value>& args) {
2326
2
  Environment* env = Environment::GetCurrent(args);
2327
2328
2
  int ngroups = getgroups(0, nullptr);
2329
2330
2
  if (ngroups == -1) {
2331
    return env->ThrowErrnoException(errno, "getgroups");
2332
  }
2333
2334
2
  gid_t* groups = new gid_t[ngroups];
2335
2336
2
  ngroups = getgroups(ngroups, groups);
2337
2338
2
  if (ngroups == -1) {
2339
    delete[] groups;
2340
    return env->ThrowErrnoException(errno, "getgroups");
2341
  }
2342
2343
2
  Local<Array> groups_list = Array::New(env->isolate(), ngroups);
2344
2
  bool seen_egid = false;
2345
2
  gid_t egid = getegid();
2346
2347
4
  for (int i = 0; i < ngroups; i++) {
2348
6
    groups_list->Set(i, Integer::New(env->isolate(), groups[i]));
2349
2
    if (groups[i] == egid)
2350
2
      seen_egid = true;
2351
  }
2352
2353
2
  delete[] groups;
2354
2355
2
  if (seen_egid == false) {
2356
    groups_list->Set(ngroups, Integer::New(env->isolate(), egid));
2357
  }
2358
2359
4
  args.GetReturnValue().Set(groups_list);
2360
}
2361
2362
2363
static void SetGroups(const FunctionCallbackInfo<Value>& args) {
2364
  Environment* env = Environment::GetCurrent(args);
2365
2366
  if (!args[0]->IsArray()) {
2367
    return env->ThrowTypeError("argument 1 must be an array");
2368
  }
2369
2370
  Local<Array> groups_list = args[0].As<Array>();
2371
  size_t size = groups_list->Length();
2372
  gid_t* groups = new gid_t[size];
2373
2374
  for (size_t i = 0; i < size; i++) {
2375
    gid_t gid = gid_by_name(env->isolate(), groups_list->Get(i));
2376
2377
    if (gid == gid_not_found) {
2378
      delete[] groups;
2379
      return env->ThrowError("group name not found");
2380
    }
2381
2382
    groups[i] = gid;
2383
  }
2384
2385
  int rc = setgroups(size, groups);
2386
  delete[] groups;
2387
2388
  if (rc == -1) {
2389
    return env->ThrowErrnoException(errno, "setgroups");
2390
  }
2391
}
2392
2393
2394
static void InitGroups(const FunctionCallbackInfo<Value>& args) {
2395
  Environment* env = Environment::GetCurrent(args);
2396
2397
  if (!args[0]->IsUint32() && !args[0]->IsString()) {
2398
    return env->ThrowTypeError("argument 1 must be a number or a string");
2399
  }
2400
2401
  if (!args[1]->IsUint32() && !args[1]->IsString()) {
2402
    return env->ThrowTypeError("argument 2 must be a number or a string");
2403
  }
2404
2405
  node::Utf8Value arg0(env->isolate(), args[0]);
2406
  gid_t extra_group;
2407
  bool must_free;
2408
  char* user;
2409
2410
  if (args[0]->IsUint32()) {
2411
    user = name_by_uid(args[0]->Uint32Value());
2412
    must_free = true;
2413
  } else {
2414
    user = *arg0;
2415
    must_free = false;
2416
  }
2417
2418
  if (user == nullptr) {
2419
    return env->ThrowError("initgroups user not found");
2420
  }
2421
2422
  extra_group = gid_by_name(env->isolate(), args[1]);
2423
2424
  if (extra_group == gid_not_found) {
2425
    if (must_free)
2426
      free(user);
2427
    return env->ThrowError("initgroups extra group not found");
2428
  }
2429
2430
  int rc = initgroups(user, extra_group);
2431
2432
  if (must_free) {
2433
    free(user);
2434
  }
2435
2436
  if (rc) {
2437
    return env->ThrowErrnoException(errno, "initgroups");
2438
  }
2439
}
2440
2441
#endif  // __POSIX__ && !defined(__ANDROID__)
2442
2443
2444
3065
static void WaitForInspectorDisconnect(Environment* env) {
2445
#if HAVE_INSPECTOR
2446
3065
  if (env->inspector_agent()->IsConnected()) {
2447
    // Restore signal dispositions, the app is done and is no longer
2448
    // capable of handling signals.
2449
#if defined(__POSIX__) && !defined(NODE_SHARED_MODE)
2450
    struct sigaction act;
2451
8
    memset(&act, 0, sizeof(act));
2452
256
    for (unsigned nr = 1; nr < kMaxSignal; nr += 1) {
2453

248
      if (nr == SIGKILL || nr == SIGSTOP || nr == SIGPROF)
2454
24
        continue;
2455
224
      act.sa_handler = (nr == SIGPIPE) ? SIG_IGN : SIG_DFL;
2456
224
      CHECK_EQ(0, sigaction(nr, &act, nullptr));
2457
    }
2458
#endif
2459
8
    env->inspector_agent()->WaitForDisconnect();
2460
  }
2461
#endif
2462
3065
}
2463
2464
2465
225
static void Exit(const FunctionCallbackInfo<Value>& args) {
2466
225
  WaitForInspectorDisconnect(Environment::GetCurrent(args));
2467
450
  exit(args[0]->Int32Value());
2468
}
2469
2470
2471
static void Uptime(const FunctionCallbackInfo<Value>& args) {
2472
  Environment* env = Environment::GetCurrent(args);
2473
  double uptime;
2474
2475
  uv_update_time(env->event_loop());
2476
  uptime = uv_now(env->event_loop()) - prog_start_time;
2477
2478
  args.GetReturnValue().Set(Number::New(env->isolate(), uptime / 1000));
2479
}
2480
2481
2482
7
static void MemoryUsage(const FunctionCallbackInfo<Value>& args) {
2483
7
  Environment* env = Environment::GetCurrent(args);
2484
2485
  size_t rss;
2486
7
  int err = uv_resident_set_memory(&rss);
2487
7
  if (err) {
2488
7
    return env->ThrowUVException(err, "uv_resident_set_memory");
2489
  }
2490
2491
7
  Isolate* isolate = env->isolate();
2492
  // V8 memory usage
2493
7
  HeapStatistics v8_heap_stats;
2494
7
  isolate->GetHeapStatistics(&v8_heap_stats);
2495
2496
  // Get the double array pointer from the Float64Array argument.
2497
14
  CHECK(args[0]->IsFloat64Array());
2498
14
  Local<Float64Array> array = args[0].As<Float64Array>();
2499
7
  CHECK_EQ(array->Length(), 4);
2500
7
  Local<ArrayBuffer> ab = array->Buffer();
2501
7
  double* fields = static_cast<double*>(ab->GetContents().Data());
2502
2503
7
  fields[0] = rss;
2504
7
  fields[1] = v8_heap_stats.total_heap_size();
2505
7
  fields[2] = v8_heap_stats.used_heap_size();
2506
14
  fields[3] = isolate->AdjustAmountOfExternalAllocatedMemory(0);
2507
}
2508
2509
2510
40
static void Kill(const FunctionCallbackInfo<Value>& args) {
2511
40
  Environment* env = Environment::GetCurrent(args);
2512
2513
40
  if (args.Length() != 2) {
2514
40
    return env->ThrowError("Bad argument.");
2515
  }
2516
2517
80
  int pid = args[0]->Int32Value();
2518
80
  int sig = args[1]->Int32Value();
2519
40
  int err = uv_kill(pid, sig);
2520
80
  args.GetReturnValue().Set(err);
2521
}
2522
2523
// used in Hrtime() below
2524
#define NANOS_PER_SEC 1000000000
2525
2526
// Hrtime exposes libuv's uv_hrtime() high-resolution timer.
2527
// The value returned by uv_hrtime() is a 64-bit int representing nanoseconds,
2528
// so this function instead fills in an Uint32Array with 3 entries,
2529
// to avoid any integer overflow possibility.
2530
// The first two entries contain the second part of the value
2531
// broken into the upper/lower 32 bits to be converted back in JS,
2532
// because there is no Uint64Array in JS.
2533
// The third entry contains the remaining nanosecond part of the value.
2534
243417
static void Hrtime(const FunctionCallbackInfo<Value>& args) {
2535
243417
  uint64_t t = uv_hrtime();
2536
2537
730251
  Local<ArrayBuffer> ab = args[0].As<Uint32Array>()->Buffer();
2538
243417
  uint32_t* fields = static_cast<uint32_t*>(ab->GetContents().Data());
2539
2540
243417
  fields[0] = (t / NANOS_PER_SEC) >> 32;
2541
243417
  fields[1] = (t / NANOS_PER_SEC) & 0xffffffff;
2542
243417
  fields[2] = t % NANOS_PER_SEC;
2543
243417
}
2544
2545
// Microseconds in a second, as a float, used in CPUUsage() below
2546
#define MICROS_PER_SEC 1e6
2547
2548
// CPUUsage use libuv's uv_getrusage() this-process resource usage accessor,
2549
// to access ru_utime (user CPU time used) and ru_stime (system CPU time used),
2550
// which are uv_timeval_t structs (long tv_sec, long tv_usec).
2551
// Returns those values as Float64 microseconds in the elements of the array
2552
// passed to the function.
2553
33
static void CPUUsage(const FunctionCallbackInfo<Value>& args) {
2554
  uv_rusage_t rusage;
2555
2556
  // Call libuv to get the values we'll return.
2557
33
  int err = uv_getrusage(&rusage);
2558
33
  if (err) {
2559
    // On error, return the strerror version of the error code.
2560
    Local<String> errmsg = OneByteString(args.GetIsolate(), uv_strerror(err));
2561
    args.GetReturnValue().Set(errmsg);
2562
33
    return;
2563
  }
2564
2565
  // Get the double array pointer from the Float64Array argument.
2566
66
  CHECK(args[0]->IsFloat64Array());
2567
66
  Local<Float64Array> array = args[0].As<Float64Array>();
2568
33
  CHECK_EQ(array->Length(), 2);
2569
33
  Local<ArrayBuffer> ab = array->Buffer();
2570
33
  double* fields = static_cast<double*>(ab->GetContents().Data());
2571
2572
  // Set the Float64Array elements to be user / system values in microseconds.
2573
33
  fields[0] = MICROS_PER_SEC * rusage.ru_utime.tv_sec + rusage.ru_utime.tv_usec;
2574
33
  fields[1] = MICROS_PER_SEC * rusage.ru_stime.tv_sec + rusage.ru_stime.tv_usec;
2575
}
2576
2577
103936
extern "C" void node_module_register(void* m) {
2578
103936
  struct node_module* mp = reinterpret_cast<struct node_module*>(m);
2579
2580
103936
  if (mp->nm_flags & NM_F_BUILTIN) {
2581
100603
    mp->nm_link = modlist_builtin;
2582
100603
    modlist_builtin = mp;
2583
3333
  } else if (mp->nm_flags & NM_F_INTERNAL) {
2584
3245
    mp->nm_link = modlist_internal;
2585
3245
    modlist_internal = mp;
2586
88
  } else if (!node_is_initialized) {
2587
    // "Linked" modules are included as part of the node project.
2588
    // Like builtins they are registered *before* node::Init runs.
2589
    mp->nm_flags = NM_F_LINKED;
2590
    mp->nm_link = modlist_linked;
2591
    modlist_linked = mp;
2592
  } else {
2593
88
    modpending = mp;
2594
  }
2595
103936
}
2596
2597
83000
inline struct node_module* FindModule(struct node_module* list,
2598
                                      const char* name,
2599
                                      int flag) {
2600
  struct node_module* mp;
2601
2602
1361457
  for (mp = list; mp != nullptr; mp = mp->nm_link) {
2603
1355055
    if (strcmp(mp->nm_modname, name) == 0)
2604
76598
      break;
2605
  }
2606
2607

83000
  CHECK(mp == nullptr || (mp->nm_flags & flag) != 0);
2608
83000
  return mp;
2609
}
2610
2611
79800
node_module* get_builtin_module(const char* name) {
2612
79800
  return FindModule(modlist_builtin, name, NM_F_BUILTIN);
2613
}
2614
3200
node_module* get_internal_module(const char* name) {
2615
3200
  return FindModule(modlist_internal, name, NM_F_INTERNAL);
2616
}
2617
node_module* get_linked_module(const char* name) {
2618
  return FindModule(modlist_linked, name, NM_F_LINKED);
2619
}
2620
2621
186
struct DLib {
2622
  std::string filename_;
2623
  std::string errmsg_;
2624
  void* handle_;
2625
  int flags_;
2626
2627
#ifdef __POSIX__
2628
  static const int kDefaultFlags = RTLD_LAZY;
2629
2630
93
  bool Open() {
2631
93
    handle_ = dlopen(filename_.c_str(), flags_);
2632
93
    if (handle_ != nullptr)
2633
90
      return true;
2634
3
    errmsg_ = dlerror();
2635
3
    return false;
2636
  }
2637
2638
6
  void Close() {
2639
6
    if (handle_ != nullptr)
2640
3
      dlclose(handle_);
2641
6
  }
2642
#else  // !__POSIX__
2643
  static const int kDefaultFlags = 0;
2644
  uv_lib_t lib_;
2645
2646
  bool Open() {
2647
    int ret = uv_dlopen(filename_.c_str(), &lib_);
2648
    if (ret == 0) {
2649
      handle_ = static_cast<void*>(lib_.handle);
2650
      return true;
2651
    }
2652
    errmsg_ = uv_dlerror(&lib_);
2653
    uv_dlclose(&lib_);
2654
    return false;
2655
  }
2656
2657
  void Close() {
2658
    uv_dlclose(&lib_);
2659
  }
2660
#endif  // !__POSIX__
2661
};
2662
2663
// DLOpen is process.dlopen(module, filename, flags).
2664
// Used to load 'module.node' dynamically shared objects.
2665
//
2666
// FIXME(bnoordhuis) Not multi-context ready. TBD how to resolve the conflict
2667
// when two contexts try to load the same shared object. Maybe have a shadow
2668
// cache that's a plain C list or hash table that's shared across contexts?
2669
93
static void DLOpen(const FunctionCallbackInfo<Value>& args) {
2670
93
  Environment* env = Environment::GetCurrent(args);
2671
2672
93
  CHECK_EQ(modpending, nullptr);
2673
2674
93
  if (args.Length() < 2) {
2675
    env->ThrowError("process.dlopen needs at least 2 arguments.");
2676
    return;
2677
  }
2678
2679
93
  int32_t flags = DLib::kDefaultFlags;
2680


189
  if (args.Length() > 2 && !args[2]->Int32Value(env->context()).To(&flags)) {
2681
    return env->ThrowTypeError("flag argument must be an integer.");
2682
  }
2683
2684
279
  Local<Object> module = args[0]->ToObject(env->isolate());  // Cast
2685
93
  node::Utf8Value filename(env->isolate(), args[1]);  // Cast
2686
180
  DLib dlib;
2687
93
  dlib.filename_ = *filename;
2688
93
  dlib.flags_ = flags;
2689
93
  bool is_opened = dlib.Open();
2690
2691
  // Objects containing v14 or later modules will have registered themselves
2692
  // on the pending list.  Activate all of them now.  At present, only one
2693
  // module per object is supported.
2694
93
  node_module* const mp = modpending;
2695
93
  modpending = nullptr;
2696
2697
93
  if (!is_opened) {
2698
3
    Local<String> errmsg = OneByteString(env->isolate(), dlib.errmsg_.c_str());
2699
3
    dlib.Close();
2700
#ifdef _WIN32
2701
    // Windows needs to add the filename into the error message
2702
    errmsg = String::Concat(errmsg, args[1]->ToString(env->isolate()));
2703
#endif  // _WIN32
2704
3
    env->isolate()->ThrowException(Exception::Error(errmsg));
2705
3
    return;
2706
  }
2707
2708
90
  if (mp == nullptr) {
2709
2
    dlib.Close();
2710
2
    env->ThrowError("Module did not self-register.");
2711
2
    return;
2712
  }
2713
88
  if (mp->nm_version == -1) {
2714
44
    if (env->EmitNapiWarning()) {
2715
      ProcessEmitWarning(env, "N-API is an experimental feature and could "
2716
42
                         "change at any time.");
2717
    }
2718
44
  } else if (mp->nm_version != NODE_MODULE_VERSION) {
2719
    char errmsg[1024];
2720
    snprintf(errmsg,
2721
             sizeof(errmsg),
2722
             "The module '%s'"
2723
             "\nwas compiled against a different Node.js version using"
2724
             "\nNODE_MODULE_VERSION %d. This version of Node.js requires"
2725
             "\nNODE_MODULE_VERSION %d. Please try re-compiling or "
2726
             "re-installing\nthe module (for instance, using `npm rebuild` "
2727
             "or `npm install`).",
2728
1
             *filename, mp->nm_version, NODE_MODULE_VERSION);
2729
2730
    // NOTE: `mp` is allocated inside of the shared library's memory, calling
2731
    // `dlclose` will deallocate it
2732
1
    dlib.Close();
2733
1
    env->ThrowError(errmsg);
2734
1
    return;
2735
  }
2736
87
  if (mp->nm_flags & NM_F_BUILTIN) {
2737
    dlib.Close();
2738
    env->ThrowError("Built-in module self-registered.");
2739
    return;
2740
  }
2741
2742
87
  mp->nm_dso_handle = dlib.handle_;
2743
87
  mp->nm_link = modlist_addon;
2744
87
  modlist_addon = mp;
2745
2746
87
  Local<String> exports_string = env->exports_string();
2747
261
  Local<Object> exports = module->Get(exports_string)->ToObject(env->isolate());
2748
2749
87
  if (mp->nm_context_register_func != nullptr) {
2750
92
    mp->nm_context_register_func(exports, module, env->context(), mp->nm_priv);
2751
41
  } else if (mp->nm_register_func != nullptr) {
2752
82
    mp->nm_register_func(exports, module, mp->nm_priv);
2753
  } else {
2754
    dlib.Close();
2755
    env->ThrowError("Module has no declared entry point.");
2756
    return;
2757
87
  }
2758
2759
  // Tell coverity that 'handle' should not be freed when we return.
2760
  // coverity[leaked_storage]
2761
}
2762
2763
2764
static void OnFatalError(const char* location, const char* message) {
2765
  if (location) {
2766
    PrintErrorString("FATAL ERROR: %s %s\n", location, message);
2767
  } else {
2768
    PrintErrorString("FATAL ERROR: %s\n", message);
2769
  }
2770
  fflush(stderr);
2771
  ABORT();
2772
}
2773
2774
2775
NO_RETURN void FatalError(const char* location, const char* message) {
2776
  OnFatalError(location, message);
2777
  // to suppress compiler warning
2778
  ABORT();
2779
}
2780
2781
2782
1272
void FatalException(Isolate* isolate,
2783
                    Local<Value> error,
2784
                    Local<Message> message) {
2785
1272
  HandleScope scope(isolate);
2786
2787
1272
  Environment* env = Environment::GetCurrent(isolate);
2788
1272
  Local<Object> process_object = env->process_object();
2789
1272
  Local<String> fatal_exception_string = env->fatal_exception_string();
2790
  Local<Function> fatal_exception_function =
2791
2544
      process_object->Get(fatal_exception_string).As<Function>();
2792
2793
1272
  int exit_code = 0;
2794
1272
  if (!fatal_exception_function->IsFunction()) {
2795
    // failed before the process._fatalException function was added!
2796
    // this is probably pretty bad.  Nothing to do but report and exit.
2797
    ReportException(env, error, message);
2798
    exit_code = 6;
2799
  }
2800
2801
1272
  if (exit_code == 0) {
2802
1272
    TryCatch fatal_try_catch(isolate);
2803
2804
    // Do not call FatalException when _fatalException handler throws
2805
1272
    fatal_try_catch.SetVerbose(false);
2806
2807
    // this will return true if the JS layer handled it, false otherwise
2808
    Local<Value> caught =
2809
1272
        fatal_exception_function->Call(process_object, 1, &error);
2810
2811
1269
    if (fatal_try_catch.HasCaught()) {
2812
      // the fatal exception function threw, so we must exit
2813
2
      ReportException(env, fatal_try_catch);
2814
2
      exit_code = 7;
2815
    }
2816
2817

2536
    if (exit_code == 0 && false == caught->BooleanValue()) {
2818
125
      ReportException(env, error, message);
2819
125
      exit_code = 1;
2820
1269
    }
2821
  }
2822
2823
1269
  if (exit_code) {
2824
#if HAVE_INSPECTOR
2825
127
    env->inspector_agent()->FatalException(error, message);
2826
#endif
2827
127
    exit(exit_code);
2828
1142
  }
2829
1142
}
2830
2831
2832
2
void FatalException(Isolate* isolate, const TryCatch& try_catch) {
2833
2
  HandleScope scope(isolate);
2834
2
  if (!try_catch.IsVerbose()) {
2835
2
    FatalException(isolate, try_catch.Exception(), try_catch.Message());
2836
1
  }
2837
1
}
2838
2839
2840
1270
static void OnMessage(Local<Message> message, Local<Value> error) {
2841
  // The current version of V8 sends messages for errors only
2842
  // (thus `error` is always set).
2843
1270
  FatalException(Isolate::GetCurrent(), error, message);
2844
1141
}
2845
2846
2847
void ClearFatalExceptionHandlers(Environment* env) {
2848
  Local<Object> process = env->process_object();
2849
  Local<Value> events =
2850
      process->Get(env->context(), env->events_string()).ToLocalChecked();
2851
2852
  if (events->IsObject()) {
2853
    events.As<Object>()->Set(
2854
        env->context(),
2855
        OneByteString(env->isolate(), "uncaughtException"),
2856
        Undefined(env->isolate())).FromJust();
2857
  }
2858
2859
  process->Set(
2860
      env->context(),
2861
      env->domain_string(),
2862
      Undefined(env->isolate())).FromJust();
2863
}
2864
2865
// Call process.emitWarning(str), fmt is a snprintf() format string
2866
46
void ProcessEmitWarning(Environment* env, const char* fmt, ...) {
2867
  char warning[1024];
2868
  va_list ap;
2869
2870
46
  va_start(ap, fmt);
2871
46
  vsnprintf(warning, sizeof(warning), fmt, ap);
2872
46
  va_end(ap);
2873
2874
46
  HandleScope handle_scope(env->isolate());
2875
92
  Context::Scope context_scope(env->context());
2876
2877
46
  Local<Object> process = env->process_object();
2878
  MaybeLocal<Value> emit_warning = process->Get(env->context(),
2879
138
      FIXED_ONE_BYTE_STRING(env->isolate(), "emitWarning"));
2880
46
  Local<Value> arg = node::OneByteString(env->isolate(), warning);
2881
2882
  Local<Value> f;
2883
2884
46
  if (!emit_warning.ToLocal(&f)) return;
2885
46
  if (!f->IsFunction()) return;
2886
2887
  // MakeCallback() unneeded, because emitWarning is internal code, it calls
2888
  // process.emit('warning', ..), but does so on the nextTick.
2889
138
  f.As<v8::Function>()->Call(process, 1, &arg);
2890
}
2891
2892
274260
static bool PullFromCache(Environment* env,
2893
                          const FunctionCallbackInfo<Value>& args,
2894
                          Local<String> module,
2895
                          Local<Object> cache) {
2896
274260
  Local<Context> context = env->context();
2897
  Local<Value> exports_v;
2898
  Local<Object> exports;
2899


1645560
  if (cache->Get(context, module).ToLocal(&exports_v) &&
2900

1485972
      exports_v->IsObject() &&
2901
663192
      exports_v->ToObject(context).ToLocal(&exports)) {
2902
388932
    args.GetReturnValue().Set(exports);
2903
194466
    return true;
2904
  }
2905
79794
  return false;
2906
}
2907
2908
73392
static Local<Object> InitModule(Environment* env,
2909
                                 node_module* mod,
2910
                                 Local<String> module) {
2911
73392
  Local<Object> exports = Object::New(env->isolate());
2912
  // Internal bindings don't have a "module" object, only exports.
2913
73392
  CHECK_EQ(mod->nm_register_func, nullptr);
2914
73392
  CHECK_NE(mod->nm_context_register_func, nullptr);
2915
73392
  Local<Value> unused = Undefined(env->isolate());
2916
  mod->nm_context_register_func(exports,
2917
                                unused,
2918
                                env->context(),
2919
73392
                                mod->nm_priv);
2920
73392
  return exports;
2921
}
2922
2923
2
static void ThrowIfNoSuchModule(Environment* env, const char* module_v) {
2924
  char errmsg[1024];
2925
  snprintf(errmsg,
2926
           sizeof(errmsg),
2927
           "No such module: %s",
2928
2
           module_v);
2929
2
  env->ThrowError(errmsg);
2930
2
}
2931
2932
267860
static void Binding(const FunctionCallbackInfo<Value>& args) {
2933
267860
  Environment* env = Environment::GetCurrent(args);
2934
2935
  Local<String> module;
2936
1262708
  if (!args[0]->ToString(env->context()).ToLocal(&module)) return;
2937
2938
267860
  Local<Object> cache = env->binding_cache_object();
2939
2940
267860
  if (PullFromCache(env, args, module, cache))
2941
191266
    return;
2942
2943
  // Append a string to process.moduleLoadList
2944
  char buf[1024];
2945
76594
  node::Utf8Value module_v(env->isolate(), module);
2946
76594
  snprintf(buf, sizeof(buf), "Binding %s", *module_v);
2947
2948
76594
  Local<Array> modules = env->module_load_list_array();
2949
76594
  uint32_t l = modules->Length();
2950
153188
  modules->Set(l, OneByteString(env->isolate(), buf));
2951
2952
76594
  node_module* mod = get_builtin_module(*module_v);
2953
  Local<Object> exports;
2954
76594
  if (mod != nullptr) {
2955
70192
    exports = InitModule(env, mod, module);
2956
6402
  } else if (!strcmp(*module_v, "constants")) {
2957
3200
    exports = Object::New(env->isolate());
2958
12800
    CHECK(exports->SetPrototype(env->context(),
2959
                                Null(env->isolate())).FromJust());
2960
3200
    DefineConstants(env->isolate(), exports);
2961
3202
  } else if (!strcmp(*module_v, "natives")) {
2962
3200
    exports = Object::New(env->isolate());
2963
3200
    DefineJavaScript(env, exports);
2964
  } else {
2965
2
    return ThrowIfNoSuchModule(env, *module_v);
2966
  }
2967
76592
  cache->Set(module, exports);
2968
2969
153184
  args.GetReturnValue().Set(exports);
2970
}
2971
2972
6400
static void InternalBinding(const FunctionCallbackInfo<Value>& args) {
2973
6400
  Environment* env = Environment::GetCurrent(args);
2974
2975
  Local<String> module;
2976
28800
  if (!args[0]->ToString(env->context()).ToLocal(&module)) return;
2977
2978
6400
  Local<Object> cache = env->internal_binding_cache_object();
2979
2980
6400
  if (PullFromCache(env, args, module, cache))
2981
3200
    return;
2982
2983
  // Append a string to process.moduleLoadList
2984
  char buf[1024];
2985
3200
  node::Utf8Value module_v(env->isolate(), module);
2986
3200
  snprintf(buf, sizeof(buf), "Internal Binding %s", *module_v);
2987
2988
3200
  Local<Array> modules = env->module_load_list_array();
2989
3200
  uint32_t l = modules->Length();
2990
6400
  modules->Set(l, OneByteString(env->isolate(), buf));
2991
2992
3200
  node_module* mod = get_internal_module(*module_v);
2993
3200
  if (mod == nullptr) return ThrowIfNoSuchModule(env, *module_v);
2994
3200
  Local<Object> exports = InitModule(env, mod, module);
2995
3200
  cache->Set(module, exports);
2996
2997
6400
  args.GetReturnValue().Set(exports);
2998
}
2999
3000
static void LinkedBinding(const FunctionCallbackInfo<Value>& args) {
3001
  Environment* env = Environment::GetCurrent(args.GetIsolate());
3002
3003
  Local<String> module_name;
3004
  if (!args[0]->ToString(env->context()).ToLocal(&module_name)) return;
3005
3006
  Local<Object> cache = env->binding_cache_object();
3007
  Local<Value> exports_v = cache->Get(module_name);
3008
3009
  if (exports_v->IsObject())
3010
    return args.GetReturnValue().Set(exports_v.As<Object>());
3011
3012
  node::Utf8Value module_name_v(env->isolate(), module_name);
3013
  node_module* mod = get_linked_module(*module_name_v);
3014
3015
  if (mod == nullptr) {
3016
    char errmsg[1024];
3017
    snprintf(errmsg,
3018
             sizeof(errmsg),
3019
             "No such module was linked: %s",
3020
             *module_name_v);
3021
    return env->ThrowError(errmsg);
3022
  }
3023
3024
  Local<Object> module = Object::New(env->isolate());
3025
  Local<Object> exports = Object::New(env->isolate());
3026
  Local<String> exports_prop = String::NewFromUtf8(env->isolate(), "exports");
3027
  module->Set(exports_prop, exports);
3028
3029
  if (mod->nm_context_register_func != nullptr) {
3030
    mod->nm_context_register_func(exports,
3031
                                  module,
3032
                                  env->context(),
3033
                                  mod->nm_priv);
3034
  } else if (mod->nm_register_func != nullptr) {
3035
    mod->nm_register_func(exports, module, mod->nm_priv);
3036
  } else {
3037
    return env->ThrowError("Linked module has no declared entry point.");
3038
  }
3039
3040
  auto effective_exports = module->Get(exports_prop);
3041
  cache->Set(module_name, effective_exports);
3042
3043
  args.GetReturnValue().Set(effective_exports);
3044
}
3045
3046
10
static void ProcessTitleGetter(Local<Name> property,
3047
                               const PropertyCallbackInfo<Value>& info) {
3048
  char buffer[512];
3049
10
  uv_get_process_title(buffer, sizeof(buffer));
3050
30
  info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), buffer));
3051
10
}
3052
3053
3054
70
static void ProcessTitleSetter(Local<Name> property,
3055
                               Local<Value> value,
3056
                               const PropertyCallbackInfo<void>& info) {
3057
70
  node::Utf8Value title(info.GetIsolate(), value);
3058
  // TODO(piscisaureus): protect with a lock
3059
70
  uv_set_process_title(*title);
3060
70
}
3061
3062
3063
225272
static void EnvGetter(Local<Name> property,
3064
                      const PropertyCallbackInfo<Value>& info) {
3065
225272
  Isolate* isolate = info.GetIsolate();
3066
225272
  if (property->IsSymbol()) {
3067
195900
    return info.GetReturnValue().SetUndefined();
3068
  }
3069
#ifdef __POSIX__
3070
225258
  node::Utf8Value key(isolate, property);
3071
225258
  const char* val = getenv(*key);
3072
225258
  if (val) {
3073
587574
    return info.GetReturnValue().Set(String::NewFromUtf8(isolate, val));
3074
29400
  }
3075
#else  // _WIN32
3076
  node::TwoByteValue key(isolate, property);
3077
  WCHAR buffer[32767];  // The maximum size allowed for environment variables.
3078
  DWORD result = GetEnvironmentVariableW(reinterpret_cast<WCHAR*>(*key),
3079
                                         buffer,
3080
                                         arraysize(buffer));
3081
  // If result >= sizeof buffer the buffer was too small. That should never
3082
  // happen. If result == 0 and result != ERROR_SUCCESS the variable was not
3083
  // not found.
3084
  if ((result > 0 || GetLastError() == ERROR_SUCCESS) &&
3085
      result < arraysize(buffer)) {
3086
    const uint16_t* two_byte_buffer = reinterpret_cast<const uint16_t*>(buffer);
3087
    Local<String> rc = String::NewFromTwoByte(isolate, two_byte_buffer);
3088
    return info.GetReturnValue().Set(rc);
3089
  }
3090
#endif
3091
}
3092
3093
3094
184
static void EnvSetter(Local<Name> property,
3095
                      Local<Value> value,
3096
                      const PropertyCallbackInfo<Value>& info) {
3097
#ifdef __POSIX__
3098
184
  node::Utf8Value key(info.GetIsolate(), property);
3099
368
  node::Utf8Value val(info.GetIsolate(), value);
3100
184
  setenv(*key, *val, 1);
3101
#else  // _WIN32
3102
  node::TwoByteValue key(info.GetIsolate(), property);
3103
  node::TwoByteValue val(info.GetIsolate(), value);
3104
  WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key);
3105
  // Environment variables that start with '=' are read-only.
3106
  if (key_ptr[0] != L'=') {
3107
    SetEnvironmentVariableW(key_ptr, reinterpret_cast<WCHAR*>(*val));
3108
  }
3109
#endif
3110
  // Whether it worked or not, always return value.
3111
552
  info.GetReturnValue().Set(value);
3112
184
}
3113
3114
3115
150415
static void EnvQuery(Local<Name> property,
3116
                     const PropertyCallbackInfo<Integer>& info) {
3117
150415
  int32_t rc = -1;  // Not found unless proven otherwise.
3118
300830
  if (property->IsString()) {
3119
#ifdef __POSIX__
3120
150414
    node::Utf8Value key(info.GetIsolate(), property);
3121
150414
    if (getenv(*key))
3122
148432
      rc = 0;
3123
#else  // _WIN32
3124
    node::TwoByteValue key(info.GetIsolate(), property);
3125
    WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key);
3126
    if (GetEnvironmentVariableW(key_ptr, nullptr, 0) > 0 ||
3127
        GetLastError() == ERROR_SUCCESS) {
3128
      rc = 0;
3129
      if (key_ptr[0] == L'=') {
3130
        // Environment variables that start with '=' are hidden and read-only.
3131
        rc = static_cast<int32_t>(v8::ReadOnly) |
3132
             static_cast<int32_t>(v8::DontDelete) |
3133
             static_cast<int32_t>(v8::DontEnum);
3134
      }
3135
    }
3136
#endif
3137
  }
3138
150415
  if (rc != -1)
3139
296864
    info.GetReturnValue().Set(rc);
3140
150415
}
3141
3142
3143
701
static void EnvDeleter(Local<Name> property,
3144
                       const PropertyCallbackInfo<Boolean>& info) {
3145
1402
  if (property->IsString()) {
3146
#ifdef __POSIX__
3147
700
    node::Utf8Value key(info.GetIsolate(), property);
3148
700
    unsetenv(*key);
3149
#else
3150
    node::TwoByteValue key(info.GetIsolate(), property);
3151
    WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key);
3152
    SetEnvironmentVariableW(key_ptr, nullptr);
3153
#endif
3154
  }
3155
3156
  // process.env never has non-configurable properties, so always
3157
  // return true like the tc39 delete operator.
3158
1402
  info.GetReturnValue().Set(true);
3159
701
}
3160
3161
3162
2818
static void EnvEnumerator(const PropertyCallbackInfo<Array>& info) {
3163
2818
  Environment* env = Environment::GetCurrent(info);
3164
2818
  Isolate* isolate = env->isolate();
3165
2818
  Local<Context> ctx = env->context();
3166
2818
  Local<Function> fn = env->push_values_to_array_function();
3167
25362
  Local<Value> argv[NODE_PUSH_VAL_TO_ARRAY_MAX];
3168
2818
  size_t idx = 0;
3169
3170
#ifdef __POSIX__
3171
2818
  int size = 0;
3172
174369
  while (environ[size])
3173
168733
    size++;
3174
3175
2818
  Local<Array> envarr = Array::New(isolate);
3176
3177
171551
  for (int i = 0; i < size; ++i) {
3178
168733
    const char* var = environ[i];
3179
168733
    const char* s = strchr(var, '=');
3180
168733
    const int length = s ? s - var : strlen(var);
3181
    argv[idx] = String::NewFromUtf8(isolate,
3182
                                    var,
3183
                                    String::kNormalString,
3184
337466
                                    length);
3185
168733
    if (++idx >= arraysize(argv)) {
3186
58611
      fn->Call(ctx, envarr, idx, argv).ToLocalChecked();
3187
19537
      idx = 0;
3188
    }
3189
  }
3190
2818
  if (idx > 0) {
3191
8454
    fn->Call(ctx, envarr, idx, argv).ToLocalChecked();
3192
  }
3193
#else  // _WIN32
3194
  WCHAR* environment = GetEnvironmentStringsW();
3195
  if (environment == nullptr)
3196
    return;  // This should not happen.
3197
  Local<Array> envarr = Array::New(isolate);
3198
  WCHAR* p = environment;
3199
  while (*p) {
3200
    WCHAR *s;
3201
    if (*p == L'=') {
3202
      // If the key starts with '=' it is a hidden environment variable.
3203
      p += wcslen(p) + 1;
3204
      continue;
3205
    } else {
3206
      s = wcschr(p, L'=');
3207
    }
3208
    if (!s) {
3209
      s = p + wcslen(p);
3210
    }
3211
    const uint16_t* two_byte_buffer = reinterpret_cast<const uint16_t*>(p);
3212
    const size_t two_byte_buffer_len = s - p;
3213
    argv[idx] = String::NewFromTwoByte(isolate,
3214
                                       two_byte_buffer,
3215
                                       String::kNormalString,
3216
                                       two_byte_buffer_len);
3217
    if (++idx >= arraysize(argv)) {
3218
      fn->Call(ctx, envarr, idx, argv).ToLocalChecked();
3219
      idx = 0;
3220
    }
3221
    p = s + wcslen(s) + 1;
3222
  }
3223
  if (idx > 0) {
3224
    fn->Call(ctx, envarr, idx, argv).ToLocalChecked();
3225
  }
3226
  FreeEnvironmentStringsW(environment);
3227
#endif
3228
3229
5636
  info.GetReturnValue().Set(envarr);
3230
2818
}
3231
3232
3233
3206
static Local<Object> GetFeatures(Environment* env) {
3234
3206
  EscapableHandleScope scope(env->isolate());
3235
3236
3206
  Local<Object> obj = Object::New(env->isolate());
3237
#if defined(DEBUG) && DEBUG
3238
  Local<Value> debug = True(env->isolate());
3239
#else
3240
3206
  Local<Value> debug = False(env->isolate());
3241
#endif  // defined(DEBUG) && DEBUG
3242
3243
6412
  obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "debug"), debug);
3244
9618
  obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "uv"), True(env->isolate()));
3245
  // TODO(bnoordhuis) ping libuv
3246
9618
  obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "ipv6"), True(env->isolate()));
3247
3248
#ifndef OPENSSL_NO_NEXTPROTONEG
3249
6412
  Local<Boolean> tls_npn = True(env->isolate());
3250
#else
3251
  Local<Boolean> tls_npn = False(env->isolate());
3252
#endif
3253
6412
  obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "tls_npn"), tls_npn);
3254
3255
#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
3256
6412
  Local<Boolean> tls_alpn = True(env->isolate());
3257
#else
3258
  Local<Boolean> tls_alpn = False(env->isolate());
3259
#endif
3260
6412
  obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "tls_alpn"), tls_alpn);
3261
3262
#ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
3263
6412
  Local<Boolean> tls_sni = True(env->isolate());
3264
#else
3265
  Local<Boolean> tls_sni = False(env->isolate());
3266
#endif
3267
6412
  obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "tls_sni"), tls_sni);
3268
3269
#if !defined(OPENSSL_NO_TLSEXT) && defined(SSL_CTX_set_tlsext_status_cb)
3270
6412
  Local<Boolean> tls_ocsp = True(env->isolate());
3271
#else
3272
  Local<Boolean> tls_ocsp = False(env->isolate());
3273
#endif  // !defined(OPENSSL_NO_TLSEXT) && defined(SSL_CTX_set_tlsext_status_cb)
3274
6412
  obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "tls_ocsp"), tls_ocsp);
3275
3276
  obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "tls"),
3277
           Boolean::New(env->isolate(),
3278
9618
                        get_builtin_module("crypto") != nullptr));
3279
3280
3206
  return scope.Escape(obj);
3281
}
3282
3283
3284
81
static void DebugPortGetter(Local<Name> property,
3285
                            const PropertyCallbackInfo<Value>& info) {
3286
81
  int port = debug_options.port();
3287
#if HAVE_INSPECTOR
3288
81
  if (port == 0) {
3289
20
    Environment* env = Environment::GetCurrent(info);
3290
20
    if (auto io = env->inspector_agent()->io())
3291
17
      port = io->port();
3292
  }
3293
#endif  // HAVE_INSPECTOR
3294
162
  info.GetReturnValue().Set(port);
3295
81
}
3296
3297
3298
static void DebugPortSetter(Local<Name> property,
3299
                            Local<Value> value,
3300
                            const PropertyCallbackInfo<void>& info) {
3301
  debug_options.set_port(value->Int32Value());
3302
}
3303
3304
3305
static void DebugProcess(const FunctionCallbackInfo<Value>& args);
3306
static void DebugPause(const FunctionCallbackInfo<Value>& args);
3307
static void DebugEnd(const FunctionCallbackInfo<Value>& args);
3308
3309
namespace {
3310
3311
70764
void NeedImmediateCallbackGetter(Local<Name> property,
3312
                                 const PropertyCallbackInfo<Value>& info) {
3313
70764
  Environment* env = Environment::GetCurrent(info);
3314
70764
  const uv_check_t* immediate_check_handle = env->immediate_check_handle();
3315
  bool active = uv_is_active(
3316
70764
      reinterpret_cast<const uv_handle_t*>(immediate_check_handle));
3317
212292
  info.GetReturnValue().Set(active);
3318
70764
}
3319
3320
3321
8179
void NeedImmediateCallbackSetter(
3322
    Local<Name> property,
3323
    Local<Value> value,
3324
    const PropertyCallbackInfo<void>& info) {
3325
8179
  Environment* env = Environment::GetCurrent(info);
3326
3327
8179
  uv_check_t* immediate_check_handle = env->immediate_check_handle();
3328
  bool active = uv_is_active(
3329
8179
      reinterpret_cast<const uv_handle_t*>(immediate_check_handle));
3330
3331
8179
  if (active == value->BooleanValue())
3332
8201
    return;
3333
3334
8157
  uv_idle_t* immediate_idle_handle = env->immediate_idle_handle();
3335
3336
8157
  if (active) {
3337
4075
    uv_check_stop(immediate_check_handle);
3338
4075
    uv_idle_stop(immediate_idle_handle);
3339
  } else {
3340
4082
    uv_check_start(immediate_check_handle, CheckImmediate);
3341
    // Idle handle is needed only to stop the event loop from blocking in poll.
3342
4082
    uv_idle_start(immediate_idle_handle, IdleImmediateDummy);
3343
  }
3344
}
3345
3346
3347
void StartProfilerIdleNotifier(const FunctionCallbackInfo<Value>& args) {
3348
  Environment* env = Environment::GetCurrent(args);
3349
  env->StartProfilerIdleNotifier();
3350
}
3351
3352
3353
void StopProfilerIdleNotifier(const FunctionCallbackInfo<Value>& args) {
3354
  Environment* env = Environment::GetCurrent(args);
3355
  env->StopProfilerIdleNotifier();
3356
}
3357
3358
3359
#define READONLY_PROPERTY(obj, str, var)                                      \
3360
  do {                                                                        \
3361
    obj->DefineOwnProperty(env->context(),                                    \
3362
                           OneByteString(env->isolate(), str),                \
3363
                           var,                                               \
3364
                           v8::ReadOnly).FromJust();                          \
3365
  } while (0)
3366
3367
#define READONLY_DONT_ENUM_PROPERTY(obj, str, var)                            \
3368
  do {                                                                        \
3369
    obj->DefineOwnProperty(env->context(),                                    \
3370
                           OneByteString(env->isolate(), str),                \
3371
                           var,                                               \
3372
                           static_cast<v8::PropertyAttribute>(v8::ReadOnly |  \
3373
                                                              v8::DontEnum))  \
3374
        .FromJust();                                                          \
3375
  } while (0)
3376
3377
}  // anonymous namespace
3378
3379
3206
void SetupProcessObject(Environment* env,
3380
                        int argc,
3381
                        const char* const* argv,
3382
                        int exec_argc,
3383
                        const char* const* exec_argv) {
3384
3206
  HandleScope scope(env->isolate());
3385
3386
3206
  Local<Object> process = env->process_object();
3387
3388
3206
  auto title_string = FIXED_ONE_BYTE_STRING(env->isolate(), "title");
3389
12824
  CHECK(process->SetAccessor(env->context(),
3390
                             title_string,
3391
                             ProcessTitleGetter,
3392
                             ProcessTitleSetter,
3393
                             env->as_external()).FromJust());
3394
3395
  // process.version
3396
16030
  READONLY_PROPERTY(process,
3397
                    "version",
3398
                    FIXED_ONE_BYTE_STRING(env->isolate(), NODE_VERSION));
3399
3400
  // process.moduleLoadList
3401
16030
  READONLY_PROPERTY(process,
3402
                    "moduleLoadList",
3403
                    env->module_load_list_array());
3404
3405
  // process.versions
3406
3206
  Local<Object> versions = Object::New(env->isolate());
3407
12824
  READONLY_PROPERTY(process, "versions", versions);
3408
3409
  const char http_parser_version[] = NODE_STRINGIFY(HTTP_PARSER_VERSION_MAJOR)
3410
                                     "."
3411
                                     NODE_STRINGIFY(HTTP_PARSER_VERSION_MINOR)
3412
                                     "."
3413
3206
                                     NODE_STRINGIFY(HTTP_PARSER_VERSION_PATCH);
3414
16030
  READONLY_PROPERTY(versions,
3415
                    "http_parser",
3416
                    FIXED_ONE_BYTE_STRING(env->isolate(), http_parser_version));
3417
3418
  // +1 to get rid of the leading 'v'
3419
16030
  READONLY_PROPERTY(versions,
3420
                    "node",
3421
                    OneByteString(env->isolate(), NODE_VERSION + 1));
3422
16030
  READONLY_PROPERTY(versions,
3423
                    "v8",
3424
                    OneByteString(env->isolate(), V8::GetVersion()));
3425
16030
  READONLY_PROPERTY(versions,
3426
                    "uv",
3427
                    OneByteString(env->isolate(), uv_version_string()));
3428
16030
  READONLY_PROPERTY(versions,
3429
                    "zlib",
3430
                    FIXED_ONE_BYTE_STRING(env->isolate(), ZLIB_VERSION));
3431
16030
  READONLY_PROPERTY(versions,
3432
                    "ares",
3433
                    FIXED_ONE_BYTE_STRING(env->isolate(), ARES_VERSION_STR));
3434
3435
3206
  const char node_modules_version[] = NODE_STRINGIFY(NODE_MODULE_VERSION);
3436
16030
  READONLY_PROPERTY(
3437
      versions,
3438
      "modules",
3439
      FIXED_ONE_BYTE_STRING(env->isolate(), node_modules_version));
3440
3441
16030
  READONLY_PROPERTY(versions,
3442
                    "nghttp2",
3443
                    FIXED_ONE_BYTE_STRING(env->isolate(), NGHTTP2_VERSION));
3444
3445
  // process._promiseRejectEvent
3446
3206
  Local<Object> promiseRejectEvent = Object::New(env->isolate());
3447
12824
  READONLY_DONT_ENUM_PROPERTY(process,
3448
                              "_promiseRejectEvent",
3449
                              promiseRejectEvent);
3450
16030
  READONLY_PROPERTY(promiseRejectEvent,
3451
                    "unhandled",
3452
                    Integer::New(env->isolate(),
3453
                                 v8::kPromiseRejectWithNoHandler));
3454
16030
  READONLY_PROPERTY(promiseRejectEvent,
3455
                    "handled",
3456
                    Integer::New(env->isolate(),
3457
                                 v8::kPromiseHandlerAddedAfterReject));
3458
3459
#if HAVE_OPENSSL
3460
  // Stupid code to slice out the version string.
3461
  {  // NOLINT(whitespace/braces)
3462
    size_t i, j, k;
3463
    int c;
3464
28854
    for (i = j = 0, k = sizeof(OPENSSL_VERSION_TEXT) - 1; i < k; ++i) {
3465
28854
      c = OPENSSL_VERSION_TEXT[i];
3466

28854
      if ('0' <= c && c <= '9') {
3467
19236
        for (j = i + 1; j < k; ++j) {
3468
19236
          c = OPENSSL_VERSION_TEXT[j];
3469
19236
          if (c == ' ')
3470
3206
            break;
3471
        }
3472
3206
        break;
3473
      }
3474
    }
3475
16030
    READONLY_PROPERTY(
3476
        versions,
3477
        "openssl",
3478
        OneByteString(env->isolate(), &OPENSSL_VERSION_TEXT[i], j - i));
3479
  }
3480
#endif
3481
3482
  // process.arch
3483
16030
  READONLY_PROPERTY(process, "arch", OneByteString(env->isolate(), NODE_ARCH));
3484
3485
  // process.platform
3486
16030
  READONLY_PROPERTY(process,
3487
                    "platform",
3488
                    OneByteString(env->isolate(), NODE_PLATFORM));
3489
3490
  // process.release
3491
3206
  Local<Object> release = Object::New(env->isolate());
3492
12824
  READONLY_PROPERTY(process, "release", release);
3493
16030
  READONLY_PROPERTY(release, "name",
3494
                    OneByteString(env->isolate(), NODE_RELEASE));
3495
3496
// if this is a release build and no explicit base has been set
3497
// substitute the standard release download URL
3498
#ifndef NODE_RELEASE_URLBASE
3499
# if NODE_VERSION_IS_RELEASE
3500
#  define NODE_RELEASE_URLBASE "https://nodejs.org/download/release/"
3501
# endif
3502
#endif
3503
3504
#if defined(NODE_RELEASE_URLBASE)
3505
#  define NODE_RELEASE_URLPFX NODE_RELEASE_URLBASE "v" NODE_VERSION_STRING "/"
3506
#  define NODE_RELEASE_URLFPFX NODE_RELEASE_URLPFX "node-v" NODE_VERSION_STRING
3507
3508
  READONLY_PROPERTY(release,
3509
                    "sourceUrl",
3510
                    OneByteString(env->isolate(),
3511
                    NODE_RELEASE_URLFPFX ".tar.gz"));
3512
  READONLY_PROPERTY(release,
3513
                    "headersUrl",
3514
                    OneByteString(env->isolate(),
3515
                    NODE_RELEASE_URLFPFX "-headers.tar.gz"));
3516
#  ifdef _WIN32
3517
  READONLY_PROPERTY(release,
3518
                    "libUrl",
3519
                    OneByteString(env->isolate(),
3520
                    strcmp(NODE_ARCH, "ia32") ? NODE_RELEASE_URLPFX "win-"
3521
                                                NODE_ARCH "/node.lib"
3522
                                              : NODE_RELEASE_URLPFX
3523
                                                "win-x86/node.lib"));
3524
#  endif
3525
#endif
3526
3527
  // process.argv
3528
3206
  Local<Array> arguments = Array::New(env->isolate(), argc);
3529
12835
  for (int i = 0; i < argc; ++i) {
3530
28887
    arguments->Set(i, String::NewFromUtf8(env->isolate(), argv[i]));
3531
  }
3532
6412
  process->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "argv"), arguments);
3533
3534
  // process.execArgv
3535
3206
  Local<Array> exec_arguments = Array::New(env->isolate(), exec_argc);
3536
3909
  for (int i = 0; i < exec_argc; ++i) {
3537
2109
    exec_arguments->Set(i, String::NewFromUtf8(env->isolate(), exec_argv[i]));
3538
  }
3539
  process->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "execArgv"),
3540
6412
               exec_arguments);
3541
3542
  // create process.env
3543
  Local<ObjectTemplate> process_env_template =
3544
3206
      ObjectTemplate::New(env->isolate());
3545
  process_env_template->SetHandler(NamedPropertyHandlerConfiguration(
3546
          EnvGetter,
3547
          EnvSetter,
3548
          EnvQuery,
3549
          EnvDeleter,
3550
          EnvEnumerator,
3551
9618
          env->as_external()));
3552
3553
  Local<Object> process_env =
3554
9618
      process_env_template->NewInstance(env->context()).ToLocalChecked();
3555
6412
  process->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "env"), process_env);
3556
3557
16030
  READONLY_PROPERTY(process, "pid", Integer::New(env->isolate(), getpid()));
3558
16030
  READONLY_PROPERTY(process, "features", GetFeatures(env));
3559
3560
  auto need_immediate_callback_string =
3561
3206
      FIXED_ONE_BYTE_STRING(env->isolate(), "_needImmediateCallback");
3562
12824
  CHECK(process->SetAccessor(env->context(), need_immediate_callback_string,
3563
                             NeedImmediateCallbackGetter,
3564
                             NeedImmediateCallbackSetter,
3565
                             env->as_external()).FromJust());
3566
3567
  // -e, --eval
3568
3206
  if (eval_string) {
3569
765
    READONLY_PROPERTY(process,
3570
                      "_eval",
3571
                      String::NewFromUtf8(env->isolate(), eval_string));
3572
  }
3573
3574
  // -p, --print
3575
3206
  if (print_eval) {
3576
330
    READONLY_PROPERTY(process, "_print_eval", True(env->isolate()));
3577
  }
3578
3579
  // -c, --check
3580
3206
  if (syntax_check_only) {
3581
130
    READONLY_PROPERTY(process, "_syntax_check_only", True(env->isolate()));
3582
  }
3583
3584
  // -i, --interactive
3585
3206
  if (force_repl) {
3586
45
    READONLY_PROPERTY(process, "_forceRepl", True(env->isolate()));
3587
  }
3588
3589
  // -r, --require
3590
3206
  if (!preload_modules.empty()) {
3591
14
    Local<Array> array = Array::New(env->isolate());
3592
32
    for (unsigned int i = 0; i < preload_modules.size(); ++i) {
3593
      Local<String> module = String::NewFromUtf8(env->isolate(),
3594
18
                                                 preload_modules[i].c_str());
3595
18
      array->Set(i, module);
3596
    }
3597
56
    READONLY_PROPERTY(process,
3598
                      "_preload_modules",
3599
                      array);
3600
3601
14
    preload_modules.clear();
3602
  }
3603
3604
  // --no-deprecation
3605
3206
  if (no_deprecation) {
3606
20
    READONLY_PROPERTY(process, "noDeprecation", True(env->isolate()));
3607
  }
3608
3609
  // --no-warnings
3610
3206
  if (no_process_warnings) {
3611
60
    READONLY_PROPERTY(process, "noProcessWarnings", True(env->isolate()));
3612
  }
3613
3614
  // --trace-warnings
3615
3206