33 #if defined HAVE_PERFCTR 41 #if defined(NODE_HAVE_I18N_SUPPORT) 49 #if defined HAVE_DTRACE || defined HAVE_ETW 53 #if defined HAVE_LTTNG 63 #include "http_parser.h" 64 #include "nghttp2/nghttp2ver.h" 71 #if NODE_USE_V8_PLATFORM 72 #include "libplatform/libplatform.h" 73 #endif // NODE_USE_V8_PLATFORM 75 #include "v8-profiler.h" 78 #ifdef NODE_ENABLE_VTUNE_PROFILING 79 #include "../deps/v8/src/third_party/vtune/v8-vtune.h" 90 #include <sys/types.h> 95 #if defined(NODE_HAVE_I18N_SUPPORT) 96 #include <unicode/uvernum.h> 99 #if defined(LEAK_SANITIZER) 100 #include <sanitizer/lsan_interface.h> 103 #if defined(_MSC_VER) 106 #define getpid GetCurrentProcessId 111 #include <sys/resource.h> 115 #if defined(__POSIX__) && !defined(__ANDROID__) 121 #include <crt_externs.h> 122 #define environ (*_NSGetEnviron()) 123 #elif !defined(_MSC_VER) 130 using v8::ArrayBuffer;
133 using v8::EscapableHandleScope;
135 using v8::Float64Array;
137 using v8::FunctionCallbackInfo;
138 using v8::HandleScope;
139 using v8::HeapStatistics;
144 using v8::MaybeLocal;
147 using v8::NamedPropertyHandlerConfiguration;
151 using v8::ObjectTemplate;
153 using v8::PromiseHookType;
154 using v8::PromiseRejectMessage;
155 using v8::PropertyCallbackInfo;
156 using v8::ScriptOrigin;
157 using v8::SealHandleScope;
160 using v8::Uint32Array;
166 static bool print_eval =
false;
167 static bool force_repl =
false;
168 static bool syntax_check_only =
false;
169 static bool trace_deprecation =
false;
170 static bool throw_deprecation =
false;
171 static bool trace_sync_io =
false;
172 static bool track_heap_objects =
false;
173 static const char* eval_string =
nullptr;
174 static std::vector<std::string> preload_modules;
175 static const int v8_default_thread_pool_size = 4;
176 static int v8_thread_pool_size = v8_default_thread_pool_size;
177 static bool prof_process =
false;
178 static bool v8_is_profiling =
false;
179 static bool node_is_initialized =
false;
184 static bool trace_enabled =
false;
185 static std::string trace_enabled_categories;
186 static bool abort_on_uncaught_exception =
false;
191 #if defined(NODE_HAVE_I18N_SUPPORT) 193 std::string icu_data_dir;
204 bool ssl_openssl_cert_store =
205 #if defined(NODE_OPENSSL_CERT_STORE) 213 bool enable_fips_crypto =
false;
214 bool force_fips_crypto =
false;
215 # endif // NODE_FIPS_MODE 216 std::string openssl_config;
217 #endif // HAVE_OPENSSL 254 static double prog_start_time;
256 static Mutex node_isolate_mutex;
257 static v8::Isolate* node_isolate;
262 #if NODE_USE_V8_PLATFORM 263 void Initialize(
int thread_pool_size, uv_loop_t* loop) {
267 trace_enabled ? tracing_agent_->GetTracingController() :
nullptr);
268 V8::InitializePlatform(platform_);
270 trace_enabled ? tracing_agent_->GetTracingController() :
nullptr);
274 platform_->Shutdown();
277 delete tracing_agent_;
278 tracing_agent_ =
nullptr;
281 void DrainVMTasks() {
282 platform_->DrainBackgroundTasks();
286 bool StartInspector(Environment *env,
const char* script_path,
291 return env->inspector_agent()->Start(platform_, script_path, options);
294 bool InspectorStarted(Environment *env) {
295 return env->inspector_agent()->IsStarted();
297 #endif // HAVE_INSPECTOR 299 void StartTracingAgent() {
300 tracing_agent_->Start(trace_enabled_categories);
303 void StopTracingAgent() {
304 tracing_agent_->Stop();
309 #else // !NODE_USE_V8_PLATFORM 310 void Initialize(
int thread_pool_size, uv_loop_t* loop) {}
312 void DrainVMTasks() {}
313 bool StartInspector(Environment *env,
const char* script_path,
315 env->ThrowError(
"Node compiled with NODE_USE_V8_PLATFORM=0");
319 void StartTracingAgent() {
320 fprintf(stderr,
"Node compiled with NODE_USE_V8_PLATFORM=0, " 321 "so event tracing is not available.\n");
323 void StopTracingAgent() {}
324 #endif // !NODE_USE_V8_PLATFORM 326 #if !NODE_USE_V8_PLATFORM || !HAVE_INSPECTOR 327 bool InspectorStarted(Environment *env) {
330 #endif // !NODE_USE_V8_PLATFORM || !HAVE_INSPECTOR 334 static const unsigned kMaxSignal = 32;
337 static void PrintErrorString(
const char* format, ...) {
339 va_start(ap, format);
341 HANDLE stderr_handle = GetStdHandle(STD_ERROR_HANDLE);
344 if (stderr_handle == INVALID_HANDLE_VALUE ||
345 stderr_handle ==
nullptr ||
346 uv_guess_handle(_fileno(stderr)) != UV_TTY) {
347 vfprintf(stderr, format, ap);
353 int n = _vscprintf(format, ap);
354 std::vector<char> out(n + 1);
355 vsprintf(out.data(), format, ap);
358 n = MultiByteToWideChar(CP_UTF8, 0, out.data(), -1,
nullptr, 0);
360 std::vector<wchar_t> wbuf(n);
361 MultiByteToWideChar(CP_UTF8, 0, out.data(), -1, wbuf.data(),
n);
365 WriteConsoleW(stderr_handle, wbuf.data(), n - 1,
nullptr,
nullptr);
367 vfprintf(stderr, format, ap);
373 static void CheckImmediate(uv_check_t* handle) {
374 Environment* env = Environment::from_immediate_check_handle(handle);
375 HandleScope scope(env->isolate());
376 Context::Scope context_scope(env->context());
378 env->process_object(),
379 env->immediate_callback_string(),
382 {0, 0}).ToLocalChecked();
386 static void IdleImmediateDummy(uv_idle_t* handle) {
392 static inline const char *errno_string(
int errorno) {
393 #define ERRNO_CASE(e) case e: return #e; 416 # if EAGAIN != EWOULDBLOCK 586 # if ENOLINK != ENOLCK 628 # if ENOTEMPTY != EEXIST 670 #ifdef EPROTONOSUPPORT 719 #define SIGNO_CASE(e) case e: return #e; 746 # if SIGABRT != SIGIOT 847 # if SIGPOLL != SIGIO 853 # if SIGLOST != SIGABRT 859 # if SIGPWR != SIGLOST 865 # if !defined(SIGPWR) || SIGINFO != SIGPWR 884 Environment* env = Environment::GetCurrent(isolate);
887 Local<String> estring = OneByteString(env->isolate(), errno_string(errorno));
888 if (msg ==
nullptr || msg[0] ==
'\0') {
889 msg = strerror(errorno);
891 Local<String> message = OneByteString(env->isolate(), msg);
894 String::Concat(estring, FIXED_ONE_BYTE_STRING(env->isolate(),
", "));
895 cons = String::Concat(cons, message);
897 Local<String> path_string;
898 if (path !=
nullptr) {
900 path_string = String::NewFromUtf8(env->isolate(), path);
903 if (path_string.IsEmpty() ==
false) {
904 cons = String::Concat(cons, FIXED_ONE_BYTE_STRING(env->isolate(),
" '"));
905 cons = String::Concat(cons, path_string);
906 cons = String::Concat(cons, FIXED_ONE_BYTE_STRING(env->isolate(),
"'"));
908 e = Exception::Error(cons);
910 Local<Object> obj = e->ToObject(env->isolate());
911 obj->Set(env->errno_string(),
Integer::New(env->isolate(), errorno));
912 obj->Set(env->code_string(), estring);
914 if (path_string.IsEmpty() ==
false) {
915 obj->Set(env->path_string(), path_string);
918 if (syscall !=
nullptr) {
919 obj->Set(env->syscall_string(), OneByteString(env->isolate(), syscall));
926 static Local<String> StringFromPath(Isolate* isolate,
const char* path) {
928 if (strncmp(path,
"\\\\?\\UNC\\", 8) == 0) {
929 return String::Concat(FIXED_ONE_BYTE_STRING(isolate,
"\\\\"),
930 String::NewFromUtf8(isolate, path + 8));
931 }
else if (strncmp(path,
"\\\\?\\", 4) == 0) {
932 return String::NewFromUtf8(isolate, path + 4);
936 return String::NewFromUtf8(isolate, path);
945 return UVException(isolate, errorno, syscall, msg, path,
nullptr);
955 Environment* env = Environment::GetCurrent(isolate);
958 msg = uv_strerror(errorno);
960 Local<String> js_code = OneByteString(isolate, uv_err_name(errorno));
961 Local<String> js_syscall = OneByteString(isolate, syscall);
962 Local<String> js_path;
963 Local<String> js_dest;
965 Local<String> js_msg = js_code;
966 js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate,
": "));
967 js_msg = String::Concat(js_msg, OneByteString(isolate, msg));
968 js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate,
", "));
969 js_msg = String::Concat(js_msg, js_syscall);
971 if (path !=
nullptr) {
972 js_path = StringFromPath(isolate, path);
974 js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate,
" '"));
975 js_msg = String::Concat(js_msg, js_path);
976 js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate,
"'"));
979 if (dest !=
nullptr) {
980 js_dest = StringFromPath(isolate, dest);
982 js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate,
" -> '"));
983 js_msg = String::Concat(js_msg, js_dest);
984 js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate,
"'"));
987 Local<Object> e = Exception::Error(js_msg)->ToObject(isolate);
989 e->Set(env->errno_string(),
Integer::New(isolate, errorno));
990 e->Set(env->code_string(), js_code);
991 e->Set(env->syscall_string(), js_syscall);
992 if (!js_path.IsEmpty())
993 e->Set(env->path_string(), js_path);
994 if (!js_dest.IsEmpty())
995 e->Set(env->dest_string(), js_dest);
1004 if (linux_at_secure || getuid() != geteuid() || getgid() != getegid())
1008 if (
const char* value = getenv(key)) {
1022 static const char *winapi_strerror(
const int errorno,
bool* must_free) {
1023 char *errmsg =
nullptr;
1025 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
1026 FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr, errorno,
1027 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&errmsg, 0,
nullptr);
1033 for (
int i = strlen(errmsg) - 1;
1034 i >= 0 && (errmsg[i] ==
'\n' || errmsg[i] ==
'\r'); i--) {
1042 return "Unknown error";
1047 Local<Value> WinapiErrnoException(Isolate* isolate,
1049 const char* syscall,
1052 Environment* env = Environment::GetCurrent(isolate);
1054 bool must_free =
false;
1055 if (!msg || !msg[0]) {
1056 msg = winapi_strerror(errorno, &must_free);
1058 Local<String> message = OneByteString(env->isolate(), msg);
1061 Local<String> cons1 =
1062 String::Concat(message, FIXED_ONE_BYTE_STRING(isolate,
" '"));
1063 Local<String> cons2 =
1064 String::Concat(cons1, String::NewFromUtf8(isolate, path));
1065 Local<String> cons3 =
1066 String::Concat(cons2, FIXED_ONE_BYTE_STRING(isolate,
"'"));
1067 e = Exception::Error(cons3);
1069 e = Exception::Error(message);
1072 Local<Object> obj = e->ToObject(env->isolate());
1073 obj->Set(env->errno_string(),
Integer::New(isolate, errorno));
1075 if (path !=
nullptr) {
1076 obj->Set(env->path_string(), String::NewFromUtf8(isolate, path));
1079 if (syscall !=
nullptr) {
1080 obj->Set(env->syscall_string(), OneByteString(isolate, syscall));
1084 LocalFree((HLOCAL)msg);
1091 void* ArrayBufferAllocator::Allocate(
size_t size) {
1093 return node::UncheckedCalloc(size);
1095 return node::UncheckedMalloc(size);
1100 bool DomainHasErrorHandler(
const Environment* env,
1101 const Local<Object>& domain) {
1102 HandleScope scope(env->isolate());
1104 Local<Value> domain_event_listeners_v = domain->Get(env->events_string());
1105 if (!domain_event_listeners_v->IsObject())
1108 Local<Object> domain_event_listeners_o =
1109 domain_event_listeners_v.As<Object>();
1111 Local<Value> domain_error_listeners_v =
1112 domain_event_listeners_o->Get(env->error_string());
1114 if (domain_error_listeners_v->IsFunction() ||
1115 (domain_error_listeners_v->IsArray() &&
1116 domain_error_listeners_v.As<Array>()->
Length() > 0))
1122 bool DomainsStackHasErrorHandler(
const Environment* env) {
1123 HandleScope scope(env->isolate());
1125 if (!env->using_domains())
1128 Local<Array> domains_stack_array = env->domains_stack_array().As<Array>();
1129 if (domains_stack_array->Length() == 0)
1132 uint32_t domains_stack_length = domains_stack_array->Length();
1133 for (uint32_t i = domains_stack_length; i > 0; --i) {
1134 Local<Value> domain_v = domains_stack_array->Get(i - 1);
1135 if (!domain_v->IsObject())
1138 Local<Object> domain = domain_v.As<Object>();
1139 if (DomainHasErrorHandler(env, domain))
1147 bool ShouldAbortOnUncaughtException(Isolate* isolate) {
1148 HandleScope scope(isolate);
1150 Environment* env = Environment::GetCurrent(isolate);
1151 Local<Object> process_object = env->process_object();
1152 Local<String> emitting_top_level_domain_error_key =
1153 env->emitting_top_level_domain_error_string();
1154 bool isEmittingTopLevelDomainError =
1155 process_object->Get(emitting_top_level_domain_error_key)->BooleanValue();
1157 return isEmittingTopLevelDomainError || !DomainsStackHasErrorHandler(env);
1161 void DomainPromiseHook(PromiseHookType type,
1162 Local<Promise> promise,
1163 Local<Value> parent,
1165 Environment* env =
static_cast<Environment*
>(arg);
1166 Local<Context> context = env->context();
1168 if (type == PromiseHookType::kInit && env->in_domain()) {
1169 promise->Set(context,
1170 env->domain_string(),
1171 env->domain_array()->Get(context,
1172 0).ToLocalChecked()).FromJust();
1176 if (type == PromiseHookType::kBefore) {
1178 }
else if (type == PromiseHookType::kAfter) {
1184 void SetupDomainUse(
const FunctionCallbackInfo<Value>& args) {
1185 Environment* env = Environment::GetCurrent(args);
1187 if (env->using_domains())
1189 env->set_using_domains(
true);
1191 HandleScope scope(env->isolate());
1192 Local<Object> process_object = env->process_object();
1194 Local<String> tick_callback_function_key = env->tick_domain_cb_string();
1195 Local<Function> tick_callback_function =
1196 process_object->Get(tick_callback_function_key).As<Function>();
1198 if (!tick_callback_function->IsFunction()) {
1199 fprintf(stderr,
"process._tickDomainCallback assigned to non-function\n");
1203 process_object->Set(env->tick_callback_string(), tick_callback_function);
1204 env->set_tick_callback_function(tick_callback_function);
1206 CHECK(args[0]->IsArray());
1207 env->set_domain_array(args[0].As<Array>());
1209 CHECK(args[1]->IsArray());
1210 env->set_domains_stack_array(args[1].As<Array>());
1213 env->process_object()->Delete(
1215 FIXED_ONE_BYTE_STRING(args.GetIsolate(),
"_setupDomainUse")).FromJust();
1217 uint32_t*
const fields = env->domain_flag()->fields();
1218 uint32_t
const fields_count = env->domain_flag()->fields_count();
1220 Local<ArrayBuffer> array_buffer =
1223 env->AddPromiseHook(DomainPromiseHook, static_cast<void*>(env));
1225 args.GetReturnValue().Set(
Uint32Array::New(array_buffer, 0, fields_count));
1229 void RunMicrotasks(
const FunctionCallbackInfo<Value>& args) {
1230 args.GetIsolate()->RunMicrotasks();
1235 Environment* env = Environment::GetCurrent(args);
1237 CHECK(args[0]->IsFunction());
1239 env->set_push_values_to_array_function(args[0].As<Function>());
1240 env->process_object()->Delete(
1242 FIXED_ONE_BYTE_STRING(env->isolate(),
"_setupProcessObject")).FromJust();
1246 void SetupNextTick(
const FunctionCallbackInfo<Value>& args) {
1247 Environment* env = Environment::GetCurrent(args);
1249 CHECK(args[0]->IsFunction());
1250 CHECK(args[1]->IsObject());
1252 env->set_tick_callback_function(args[0].As<Function>());
1254 env->SetMethod(args[1].As<Object>(),
"runMicrotasks", RunMicrotasks);
1257 env->process_object()->Delete(
1259 FIXED_ONE_BYTE_STRING(args.GetIsolate(),
"_setupNextTick")).FromJust();
1262 uint32_t*
const fields = env->tick_info()->fields();
1263 uint32_t
const fields_count = env->tick_info()->fields_count();
1265 Local<ArrayBuffer> array_buffer =
1268 args.GetReturnValue().Set(
Uint32Array::New(array_buffer, 0, fields_count));
1271 void PromiseRejectCallback(PromiseRejectMessage message) {
1272 Local<Promise> promise = message.GetPromise();
1273 Isolate* isolate = promise->GetIsolate();
1274 Local<Value> value = message.GetValue();
1275 Local<Integer>
event =
Integer::New(isolate, message.GetEvent());
1277 Environment* env = Environment::GetCurrent(isolate);
1278 Local<Function> callback = env->promise_reject_function();
1280 if (value.IsEmpty())
1281 value = Undefined(isolate);
1283 Local<Value> args[] = { event, promise, value };
1284 Local<Object> process = env->process_object();
1286 callback->Call(process, arraysize(args), args);
1289 void SetupPromises(
const FunctionCallbackInfo<Value>& args) {
1290 Environment* env = Environment::GetCurrent(args);
1291 Isolate* isolate = env->isolate();
1293 CHECK(args[0]->IsFunction());
1295 isolate->SetPromiseRejectCallback(PromiseRejectCallback);
1296 env->set_promise_reject_function(args[0].As<Function>());
1298 env->process_object()->Delete(
1300 FIXED_ONE_BYTE_STRING(isolate,
"_setupPromises")).FromJust();
1307 Environment* env = Environment::GetCurrent(isolate);
1308 env->AddPromiseHook(fn, arg);
1314 const Local<Function> callback,
1316 Local<Value> argv[],
1319 CHECK_EQ(env->context(), env->isolate()->GetCurrentContext());
1321 Local<Object> object;
1323 Environment::AsyncCallbackScope callback_scope(env);
1324 bool disposed_domain =
false;
1326 if (recv->IsObject()) {
1327 object = recv.As<Object>();
1330 if (env->using_domains()) {
1331 CHECK(recv->IsObject());
1333 if (disposed_domain)
return Undefined(env->isolate());
1336 MaybeLocal<Value> ret;
1339 AsyncHooks::ExecScope exec_scope(env, asyncContext.
async_id,
1345 AsyncWrap::EmitBefore(env, asyncContext.
async_id);
1348 ret = callback->Call(env->context(), recv, argc, argv);
1350 if (ret.IsEmpty()) {
1353 return callback_scope.in_makecallback() ?
1354 ret : Undefined(env->isolate());
1358 AsyncWrap::EmitAfter(env, asyncContext.
async_id);
1362 if (env->using_domains()) {
1364 if (disposed_domain)
return Undefined(env->isolate());
1367 if (callback_scope.in_makecallback()) {
1371 Environment::TickInfo* tick_info = env->tick_info();
1373 if (tick_info->length() == 0) {
1374 env->isolate()->RunMicrotasks();
1379 CHECK_EQ(env->current_async_id(), asyncContext.
async_id);
1382 Local<Object> process = env->process_object();
1384 if (tick_info->length() == 0) {
1385 tick_info->set_index(0);
1389 if (env->tick_callback_function()->Call(process, 0,
nullptr).IsEmpty()) {
1390 return Undefined(env->isolate());
1404 Local<Value> argv[],
1406 Local<String> method_string =
1407 String::NewFromUtf8(isolate, method, v8::NewStringType::kNormal)
1409 return MakeCallback(isolate, recv, method_string, argc, argv, asyncContext);
1415 Local<String> symbol,
1417 Local<Value> argv[],
1419 Local<Value> callback_v = recv->Get(symbol);
1420 if (callback_v.IsEmpty())
return Local<Value>();
1421 if (!callback_v->IsFunction())
return Local<Value>();
1422 Local<Function> callback = callback_v.As<Function>();
1423 return MakeCallback(isolate, recv, callback, argc, argv, asyncContext);
1429 Local<Function> callback,
1431 Local<Value> argv[],
1440 Environment* env = Environment::GetCurrent(callback->CreationContext());
1441 Context::Scope context_scope(env->context());
1442 return MakeCallback(env, recv.As<Value>(), callback, argc, argv,
1453 Local<Value>* argv) {
1454 EscapableHandleScope handle_scope(isolate);
1455 return handle_scope.Escape(
1456 MakeCallback(isolate, recv, method, argc, argv, {0, 0})
1457 .FromMaybe(Local<Value>()));
1463 Local<String> symbol,
1465 Local<Value>* argv) {
1466 EscapableHandleScope handle_scope(isolate);
1467 return handle_scope.Escape(
1468 MakeCallback(isolate, recv, symbol, argc, argv, {0, 0})
1469 .FromMaybe(Local<Value>()));
1475 Local<Function> callback,
1477 Local<Value>* argv) {
1478 EscapableHandleScope handle_scope(isolate);
1479 return handle_scope.Escape(
1480 MakeCallback(isolate, recv, callback, argc, argv, {0, 0})
1481 .FromMaybe(Local<Value>()));
1486 enum encoding default_encoding) {
1487 switch (encoding[0]) {
1490 if (encoding[1] ==
't' && encoding[2] ==
'f') {
1492 encoding += encoding[3] ==
'-' ? 4 : 3;
1493 if (encoding[0] ==
'8' && encoding[1] ==
'\0')
1495 if (strncmp(encoding,
"16le", 4) == 0)
1499 }
else if (encoding[1] ==
'c' && encoding[2] ==
's') {
1500 encoding += encoding[3] ==
'-' ? 4 : 3;
1501 if (encoding[0] ==
'2' && encoding[1] ==
'\0')
1507 if (encoding[1] ==
'a') {
1508 if (strncmp(encoding + 2,
"tin1", 4) == 0)
1514 if (encoding[1] ==
'i') {
1515 if (strncmp(encoding + 2,
"nary", 4) == 0)
1519 }
else if (encoding[1] ==
'u') {
1520 if (strncmp(encoding + 2,
"ffer", 4) == 0)
1525 return default_encoding;
1530 if (StringEqualNoCase(encoding,
"utf8")) {
1532 }
else if (StringEqualNoCase(encoding,
"utf-8")) {
1534 }
else if (StringEqualNoCase(encoding,
"ascii")) {
1536 }
else if (StringEqualNoCase(encoding,
"base64")) {
1538 }
else if (StringEqualNoCase(encoding,
"ucs2")) {
1540 }
else if (StringEqualNoCase(encoding,
"ucs-2")) {
1542 }
else if (StringEqualNoCase(encoding,
"utf16le")) {
1544 }
else if (StringEqualNoCase(encoding,
"utf-16le")) {
1546 }
else if (StringEqualNoCase(encoding,
"latin1")) {
1548 }
else if (StringEqualNoCase(encoding,
"binary")) {
1550 }
else if (StringEqualNoCase(encoding,
"buffer")) {
1552 }
else if (StringEqualNoCase(encoding,
"hex")) {
1555 return default_encoding;
1561 Local<Value> encoding_v,
1563 CHECK(!encoding_v.IsEmpty());
1565 if (!encoding_v->IsString())
1566 return default_encoding;
1568 node::Utf8Value
encoding(isolate, encoding_v);
1577 CHECK_NE(encoding,
UCS2);
1593 HandleScope scope(isolate);
1595 return StringBytes::Size(isolate, val, encoding);
1604 return StringBytes::Write(isolate, buf, buflen, val, encoding,
nullptr);
1608 if (!er.IsEmpty() && er->IsObject()) {
1609 Local<Object> err_obj = er.As<Object>();
1611 err_obj->GetPrivate(env->context(), env->decorated_private_symbol());
1612 Local<Value> decorated;
1613 return maybe_value.ToLocal(&decorated) && decorated->IsTrue();
1620 Local<Message> message,
1621 enum ErrorHandlingMode mode) {
1622 if (message.IsEmpty())
1625 HandleScope scope(env->isolate());
1626 Local<Object> err_obj;
1627 if (!er.IsEmpty() && er->IsObject()) {
1628 err_obj = er.As<Object>();
1630 auto context = env->context();
1631 auto processed_private_symbol = env->processed_private_symbol();
1633 if (err_obj->HasPrivate(context, processed_private_symbol).FromJust())
1635 err_obj->SetPrivate(
1637 processed_private_symbol,
1638 True(env->isolate()));
1642 node::Utf8Value filename(env->isolate(), message->GetScriptResourceName());
1643 const char* filename_string = *filename;
1644 int linenum = message->GetLineNumber();
1646 node::Utf8Value sourceline(env->isolate(), message->GetSourceLine());
1647 const char* sourceline_string = *sourceline;
1670 int start = message->GetStartColumn(env->context()).FromMaybe(0);
1671 int end = message->GetEndColumn(env->context()).FromMaybe(0);
1674 int max_off =
sizeof(arrow) - 2;
1676 int off = snprintf(arrow,
1683 if (off > max_off) {
1688 for (
int i = 0; i < start; i++) {
1689 if (sourceline_string[i] ==
'\0' || off >= max_off) {
1692 CHECK_LT(off, max_off);
1693 arrow[off++] = (sourceline_string[i] ==
'\t') ?
'\t' :
' ';
1695 for (
int i = start; i < end; i++) {
1696 if (sourceline_string[i] ==
'\0' || off >= max_off) {
1699 CHECK_LT(off, max_off);
1702 CHECK_LE(off, max_off);
1704 arrow[off + 1] =
'\0';
1706 Local<String> arrow_str = String::NewFromUtf8(env->isolate(), arrow);
1708 const bool can_set_arrow = !arrow_str.IsEmpty() && !err_obj.IsEmpty();
1714 if (!can_set_arrow || (mode == FATAL_ERROR && !err_obj->IsNativeError())) {
1715 if (env->printed_error())
1717 env->set_printed_error(
true);
1719 uv_tty_reset_mode();
1720 PrintErrorString(
"\n%s", arrow);
1724 CHECK(err_obj->SetPrivate(
1726 env->arrow_message_private_symbol(),
1727 arrow_str).FromMaybe(
false));
1731 static void ReportException(Environment* env,
1733 Local<Message> message) {
1734 HandleScope scope(env->isolate());
1738 Local<Value> trace_value;
1742 if (er->IsUndefined() || er->IsNull()) {
1743 trace_value = Undefined(env->isolate());
1745 Local<Object> err_obj = er->ToObject(env->isolate());
1747 trace_value = err_obj->Get(env->stack_string());
1749 err_obj->GetPrivate(
1751 env->arrow_message_private_symbol()).ToLocalChecked();
1754 node::Utf8Value trace(env->isolate(), trace_value);
1757 if (trace.length() > 0 && !trace_value->IsUndefined()) {
1758 if (arrow.IsEmpty() || !arrow->IsString() || decorated) {
1759 PrintErrorString(
"%s\n", *trace);
1761 node::Utf8Value arrow_string(env->isolate(), arrow);
1762 PrintErrorString(
"%s\n%s\n", *arrow_string, *trace);
1768 Local<Value> message;
1771 if (er->IsObject()) {
1772 Local<Object> err_obj = er.As<Object>();
1773 message = err_obj->Get(env->message_string());
1774 name = err_obj->Get(FIXED_ONE_BYTE_STRING(env->isolate(),
"name"));
1777 if (message.IsEmpty() ||
1778 message->IsUndefined() ||
1780 name->IsUndefined()) {
1782 String::Utf8Value message(er);
1784 PrintErrorString(
"%s\n", *message ? *message :
1785 "<toString() threw exception>");
1787 node::Utf8Value name_string(env->isolate(), name);
1788 node::Utf8Value message_string(env->isolate(), message);
1790 if (arrow.IsEmpty() || !arrow->IsString() || decorated) {
1791 PrintErrorString(
"%s: %s\n", *name_string, *message_string);
1793 node::Utf8Value arrow_string(env->isolate(), arrow);
1794 PrintErrorString(
"%s\n%s: %s\n",
1806 static void ReportException(Environment* env,
const TryCatch& try_catch) {
1807 ReportException(env, try_catch.Exception(), try_catch.Message());
1812 static Local<Value> ExecuteString(Environment* env,
1814 Local<String> filename) {
1815 EscapableHandleScope scope(env->isolate());
1816 TryCatch try_catch(env->isolate());
1820 try_catch.SetVerbose(
false);
1822 ScriptOrigin origin(filename);
1823 MaybeLocal<v8::Script>
script =
1824 v8::Script::Compile(env->context(),
source, &origin);
1825 if (script.IsEmpty()) {
1826 ReportException(env, try_catch);
1830 Local<Value> result = script.ToLocalChecked()->Run();
1831 if (result.IsEmpty()) {
1832 ReportException(env, try_catch);
1836 return scope.Escape(result);
1840 static void GetActiveRequests(
const FunctionCallbackInfo<Value>& args) {
1841 Environment* env = Environment::GetCurrent(args);
1843 Local<Array> ary =
Array::New(args.GetIsolate());
1844 Local<Context>
ctx = env->context();
1845 Local<Function> fn = env->push_values_to_array_function();
1846 Local<Value> argv[NODE_PUSH_VAL_TO_ARRAY_MAX];
1849 for (
auto w : *env->req_wrap_queue()) {
1850 if (w->persistent().IsEmpty())
1852 argv[idx] = w->object();
1853 if (++idx >= arraysize(argv)) {
1854 fn->Call(ctx, ary, idx, argv).ToLocalChecked();
1860 fn->Call(ctx, ary, idx, argv).ToLocalChecked();
1863 args.GetReturnValue().Set(ary);
1870 Environment* env = Environment::GetCurrent(args);
1872 Local<Array> ary =
Array::New(env->isolate());
1873 Local<Context>
ctx = env->context();
1874 Local<Function> fn = env->push_values_to_array_function();
1875 Local<Value> argv[NODE_PUSH_VAL_TO_ARRAY_MAX];
1878 Local<String> owner_sym = env->owner_string();
1880 for (
auto w : *env->handle_wrap_queue()) {
1881 if (w->persistent().IsEmpty() || !HandleWrap::HasRef(w))
1883 Local<Object>
object = w->object();
1884 Local<Value> owner =
object->Get(owner_sym);
1885 if (owner->IsUndefined())
1888 if (++idx >= arraysize(argv)) {
1889 fn->Call(ctx, ary, idx, argv).ToLocalChecked();
1894 fn->Call(ctx, ary, idx, argv).ToLocalChecked();
1897 args.GetReturnValue().Set(ary);
1904 ABORT_NO_BACKTRACE();
1908 NO_RETURN
void Assert(
const char*
const (*args)[4]) {
1909 auto filename = (*args)[0];
1910 auto linenum = (*args)[1];
1911 auto message = (*args)[2];
1912 auto function = (*args)[3];
1915 size_t exepath_size =
sizeof(exepath);
1916 if (uv_exepath(exepath, &exepath_size))
1917 snprintf(exepath,
sizeof(exepath),
"node");
1921 snprintf(pid,
sizeof(pid),
"[%u]", getpid());
1924 fprintf(stderr,
"%s%s: %s:%s:%s%s Assertion `%s' failed.\n",
1925 exepath, pid, filename, linenum,
1926 function, *
function ?
":" :
"", message);
1933 static void Abort(
const FunctionCallbackInfo<Value>& args) {
1938 static void Chdir(
const FunctionCallbackInfo<Value>& args) {
1939 Environment* env = Environment::GetCurrent(args);
1941 if (args.Length() != 1 || !args[0]->IsString()) {
1942 return env->ThrowTypeError(
"Bad argument.");
1945 node::Utf8Value path(args.GetIsolate(), args[0]);
1946 int err = uv_chdir(*path);
1948 return env->ThrowUVException(err,
"uv_chdir");
1953 static void Cwd(
const FunctionCallbackInfo<Value>& args) {
1954 Environment* env = Environment::GetCurrent(args);
1957 char buf[MAX_PATH * 4];
1962 size_t cwd_len =
sizeof(
buf);
1963 int err = uv_cwd(buf, &cwd_len);
1965 return env->ThrowUVException(err,
"uv_cwd");
1968 Local<String> cwd = String::NewFromUtf8(env->isolate(),
1970 String::kNormalString,
1972 args.GetReturnValue().Set(cwd);
1976 static void Umask(
const FunctionCallbackInfo<Value>& args) {
1977 Environment* env = Environment::GetCurrent(args);
1980 if (args.Length() < 1 || args[0]->IsUndefined()) {
1982 umask(static_cast<mode_t>(old));
1983 }
else if (!args[0]->IsInt32() && !args[0]->IsString()) {
1984 return env->ThrowTypeError(
"argument must be an integer or octal string.");
1987 if (args[0]->IsInt32()) {
1988 oct = args[0]->Uint32Value();
1991 node::Utf8Value str(env->isolate(), args[0]);
1994 for (
size_t i = 0; i < str.length(); i++) {
1996 if (c >
'7' || c <
'0') {
1997 return env->ThrowTypeError(
"invalid octal string");
2003 old = umask(static_cast<mode_t>(oct));
2006 args.GetReturnValue().Set(old);
2010 #if defined(__POSIX__) && !defined(__ANDROID__) 2012 static const uid_t uid_not_found =
static_cast<uid_t
>(-1);
2013 static const gid_t gid_not_found =
static_cast<gid_t
>(-1);
2016 static uid_t uid_by_name(
const char* name) {
2024 if (getpwnam_r(name, &pwd, buf,
sizeof(buf), &pp) == 0 && pp !=
nullptr) {
2028 return uid_not_found;
2032 static char* name_by_uid(uid_t uid) {
2041 if ((rc = getpwuid_r(uid, &pwd, buf,
sizeof(buf), &pp)) == 0 &&
2043 return strdup(pp->pw_name);
2054 static gid_t gid_by_name(
const char* name) {
2062 if (getgrnam_r(name, &pwd, buf,
sizeof(buf), &pp) == 0 && pp !=
nullptr) {
2066 return gid_not_found;
2070 #if 0 // For future use. 2071 static const char* name_by_gid(gid_t gid) {
2080 if ((rc = getgrgid_r(gid, &pwd, buf,
sizeof(buf), &pp)) == 0 &&
2082 return strdup(pp->gr_name);
2094 static uid_t uid_by_name(Isolate* isolate, Local<Value> value) {
2095 if (value->IsUint32()) {
2096 return static_cast<uid_t
>(value->Uint32Value());
2098 node::Utf8Value name(isolate, value);
2099 return uid_by_name(*name);
2104 static gid_t gid_by_name(Isolate* isolate, Local<Value> value) {
2105 if (value->IsUint32()) {
2106 return static_cast<gid_t
>(value->Uint32Value());
2108 node::Utf8Value name(isolate, value);
2109 return gid_by_name(*name);
2113 static void GetUid(
const FunctionCallbackInfo<Value>& args) {
2115 args.GetReturnValue().Set(static_cast<uint32_t>(getuid()));
2119 static void GetGid(
const FunctionCallbackInfo<Value>& args) {
2121 args.GetReturnValue().Set(static_cast<uint32_t>(getgid()));
2125 static void GetEUid(
const FunctionCallbackInfo<Value>& args) {
2127 args.GetReturnValue().Set(static_cast<uint32_t>(geteuid()));
2131 static void GetEGid(
const FunctionCallbackInfo<Value>& args) {
2133 args.GetReturnValue().Set(static_cast<uint32_t>(getegid()));
2137 static void SetGid(
const FunctionCallbackInfo<Value>& args) {
2138 Environment* env = Environment::GetCurrent(args);
2140 if (!args[0]->IsUint32() && !args[0]->IsString()) {
2141 return env->ThrowTypeError(
"setgid argument must be a number or a string");
2144 gid_t gid = gid_by_name(env->isolate(), args[0]);
2146 if (gid == gid_not_found) {
2147 return env->ThrowError(
"setgid group id does not exist");
2151 return env->ThrowErrnoException(errno,
"setgid");
2156 static void SetEGid(
const FunctionCallbackInfo<Value>& args) {
2157 Environment* env = Environment::GetCurrent(args);
2159 if (!args[0]->IsUint32() && !args[0]->IsString()) {
2160 return env->ThrowTypeError(
"setegid argument must be a number or string");
2163 gid_t gid = gid_by_name(env->isolate(), args[0]);
2165 if (gid == gid_not_found) {
2166 return env->ThrowError(
"setegid group id does not exist");
2170 return env->ThrowErrnoException(errno,
"setegid");
2175 static void SetUid(
const FunctionCallbackInfo<Value>& args) {
2176 Environment* env = Environment::GetCurrent(args);
2178 if (!args[0]->IsUint32() && !args[0]->IsString()) {
2179 return env->ThrowTypeError(
"setuid argument must be a number or a string");
2182 uid_t uid = uid_by_name(env->isolate(), args[0]);
2184 if (uid == uid_not_found) {
2185 return env->ThrowError(
"setuid user id does not exist");
2189 return env->ThrowErrnoException(errno,
"setuid");
2194 static void SetEUid(
const FunctionCallbackInfo<Value>& args) {
2195 Environment* env = Environment::GetCurrent(args);
2197 if (!args[0]->IsUint32() && !args[0]->IsString()) {
2198 return env->ThrowTypeError(
"seteuid argument must be a number or string");
2201 uid_t uid = uid_by_name(env->isolate(), args[0]);
2203 if (uid == uid_not_found) {
2204 return env->ThrowError(
"seteuid user id does not exist");
2208 return env->ThrowErrnoException(errno,
"seteuid");
2213 static void GetGroups(
const FunctionCallbackInfo<Value>& args) {
2214 Environment* env = Environment::GetCurrent(args);
2216 int ngroups = getgroups(0,
nullptr);
2218 if (ngroups == -1) {
2219 return env->ThrowErrnoException(errno,
"getgroups");
2222 gid_t* groups =
new gid_t[ngroups];
2224 ngroups = getgroups(ngroups, groups);
2226 if (ngroups == -1) {
2228 return env->ThrowErrnoException(errno,
"getgroups");
2231 Local<Array> groups_list =
Array::New(env->isolate(), ngroups);
2232 bool seen_egid =
false;
2233 gid_t egid = getegid();
2235 for (
int i = 0; i < ngroups; i++) {
2236 groups_list->Set(i,
Integer::New(env->isolate(), groups[i]));
2237 if (groups[i] == egid)
2243 if (seen_egid ==
false) {
2244 groups_list->Set(ngroups,
Integer::New(env->isolate(), egid));
2247 args.GetReturnValue().Set(groups_list);
2251 static void SetGroups(
const FunctionCallbackInfo<Value>& args) {
2252 Environment* env = Environment::GetCurrent(args);
2254 if (!args[0]->IsArray()) {
2255 return env->ThrowTypeError(
"argument 1 must be an array");
2258 Local<Array> groups_list = args[0].As<Array>();
2259 size_t size = groups_list->Length();
2260 gid_t* groups =
new gid_t[size];
2262 for (
size_t i = 0; i < size; i++) {
2263 gid_t gid = gid_by_name(env->isolate(), groups_list->Get(i));
2265 if (gid == gid_not_found) {
2267 return env->ThrowError(
"group name not found");
2273 int rc = setgroups(size, groups);
2277 return env->ThrowErrnoException(errno,
"setgroups");
2282 static void InitGroups(
const FunctionCallbackInfo<Value>& args) {
2283 Environment* env = Environment::GetCurrent(args);
2285 if (!args[0]->IsUint32() && !args[0]->IsString()) {
2286 return env->ThrowTypeError(
"argument 1 must be a number or a string");
2289 if (!args[1]->IsUint32() && !args[1]->IsString()) {
2290 return env->ThrowTypeError(
"argument 2 must be a number or a string");
2293 node::Utf8Value arg0(env->isolate(), args[0]);
2298 if (args[0]->IsUint32()) {
2299 user = name_by_uid(args[0]->Uint32Value());
2306 if (user ==
nullptr) {
2307 return env->ThrowError(
"initgroups user not found");
2310 extra_group = gid_by_name(env->isolate(), args[1]);
2312 if (extra_group == gid_not_found) {
2315 return env->ThrowError(
"initgroups extra group not found");
2318 int rc = initgroups(user, extra_group);
2325 return env->ThrowErrnoException(errno,
"initgroups");
2329 #endif // __POSIX__ && !defined(__ANDROID__) 2332 static void WaitForInspectorDisconnect(Environment* env) {
2334 if (env->inspector_agent()->IsConnected()) {
2337 #if defined(__POSIX__) && !defined(NODE_SHARED_MODE) 2338 struct sigaction act;
2339 memset(&act, 0,
sizeof(act));
2340 for (
unsigned nr = 1; nr < kMaxSignal; nr += 1) {
2341 if (nr == SIGKILL || nr == SIGSTOP || nr == SIGPROF)
2343 act.sa_handler = (nr == SIGPIPE) ? SIG_IGN : SIG_DFL;
2344 CHECK_EQ(0, sigaction(nr, &act,
nullptr));
2347 env->inspector_agent()->WaitForDisconnect();
2353 static void Exit(
const FunctionCallbackInfo<Value>& args) {
2354 WaitForInspectorDisconnect(Environment::GetCurrent(args));
2355 exit(args[0]->Int32Value());
2359 static void Uptime(
const FunctionCallbackInfo<Value>& args) {
2360 Environment* env = Environment::GetCurrent(args);
2363 uv_update_time(env->event_loop());
2364 uptime = uv_now(env->event_loop()) - prog_start_time;
2366 args.GetReturnValue().Set(
Number::New(env->isolate(), uptime / 1000));
2370 static void MemoryUsage(
const FunctionCallbackInfo<Value>& args) {
2371 Environment* env = Environment::GetCurrent(args);
2374 int err = uv_resident_set_memory(&rss);
2376 return env->ThrowUVException(err,
"uv_resident_set_memory");
2379 Isolate* isolate = env->isolate();
2381 HeapStatistics v8_heap_stats;
2382 isolate->GetHeapStatistics(&v8_heap_stats);
2385 CHECK(args[0]->IsFloat64Array());
2386 Local<Float64Array> array = args[0].As<Float64Array>();
2387 CHECK_EQ(array->Length(), 4);
2388 Local<ArrayBuffer> ab = array->Buffer();
2389 double* fields =
static_cast<double*
>(ab->GetContents().Data());
2392 fields[1] = v8_heap_stats.total_heap_size();
2393 fields[2] = v8_heap_stats.used_heap_size();
2394 fields[3] = isolate->AdjustAmountOfExternalAllocatedMemory(0);
2398 static void Kill(
const FunctionCallbackInfo<Value>& args) {
2399 Environment* env = Environment::GetCurrent(args);
2401 if (args.Length() != 2) {
2402 return env->ThrowError(
"Bad argument.");
2405 int pid = args[0]->Int32Value();
2406 int sig = args[1]->Int32Value();
2407 int err = uv_kill(pid, sig);
2408 args.GetReturnValue().Set(err);
2412 #define NANOS_PER_SEC 1000000000 2422 static void Hrtime(
const FunctionCallbackInfo<Value>& args) {
2423 uint64_t
t = uv_hrtime();
2425 Local<ArrayBuffer> ab = args[0].As<Uint32Array>()->Buffer();
2426 uint32_t* fields =
static_cast<uint32_t*
>(ab->GetContents().Data());
2434 #define MICROS_PER_SEC 1e6 2441 static void CPUUsage(
const FunctionCallbackInfo<Value>& args) {
2445 int err = uv_getrusage(&rusage);
2448 Local<String> errmsg = OneByteString(args.GetIsolate(), uv_strerror(err));
2449 args.GetReturnValue().Set(errmsg);
2454 CHECK(args[0]->IsFloat64Array());
2455 Local<Float64Array> array = args[0].As<Float64Array>();
2456 CHECK_EQ(array->Length(), 2);
2457 Local<ArrayBuffer> ab = array->Buffer();
2458 double* fields =
static_cast<double*
>(ab->GetContents().Data());
2461 fields[0] =
MICROS_PER_SEC * rusage.ru_utime.tv_sec + rusage.ru_utime.tv_usec;
2462 fields[1] =
MICROS_PER_SEC * rusage.ru_stime.tv_sec + rusage.ru_stime.tv_usec;
2469 mp->
nm_link = modlist_builtin;
2470 modlist_builtin = mp;
2471 }
else if (!node_is_initialized) {
2476 modlist_linked = mp;
2485 for (mp = modlist_builtin; mp !=
nullptr; mp = mp->
nm_link) {
2497 for (mp = modlist_linked; mp !=
nullptr; mp = mp->
nm_link) {
2512 static void DLOpen(
const FunctionCallbackInfo<Value>& args) {
2513 Environment* env = Environment::GetCurrent(args);
2516 CHECK_EQ(modpending,
nullptr);
2518 if (args.Length() != 2) {
2519 env->ThrowError(
"process.dlopen takes exactly 2 arguments.");
2523 Local<Object> module = args[0]->ToObject(env->isolate());
2524 node::Utf8Value filename(env->isolate(), args[1]);
2525 const bool is_dlopen_error = uv_dlopen(*filename, &lib);
2531 modpending =
nullptr;
2533 if (is_dlopen_error) {
2534 Local<String> errmsg = OneByteString(env->isolate(), uv_dlerror(&lib));
2538 errmsg = String::Concat(errmsg, args[1]->ToString(env->isolate()));
2540 env->isolate()->ThrowException(Exception::Error(errmsg));
2544 if (mp ==
nullptr) {
2546 env->ThrowError(
"Module did not self-register.");
2555 "\nwas compiled against the ABI-stable Node.js API (N-API)." 2556 "\nThis feature is experimental and must be enabled on the " 2557 "\ncommand-line by adding --napi-modules.",
2563 "\nwas compiled against a different Node.js version using" 2564 "\nNODE_MODULE_VERSION %d. This version of Node.js requires" 2565 "\nNODE_MODULE_VERSION %d. Please try re-compiling or " 2566 "re-installing\nthe module (for instance, using `npm rebuild` " 2567 "or `npm install`).",
2574 env->ThrowError(errmsg);
2579 env->ThrowError(
"Built-in module self-registered.");
2587 Local<String> exports_string = env->exports_string();
2588 Local<Object> exports = module->Get(exports_string)->ToObject(env->isolate());
2596 env->ThrowError(
"Module has no declared entry point.");
2605 static void OnFatalError(
const char* location,
const char* message) {
2607 PrintErrorString(
"FATAL ERROR: %s %s\n", location, message);
2609 PrintErrorString(
"FATAL ERROR: %s\n", message);
2616 NO_RETURN
void FatalError(
const char* location,
const char* message) {
2617 OnFatalError(location, message);
2625 Local<Message> message) {
2626 HandleScope scope(isolate);
2628 Environment* env = Environment::GetCurrent(isolate);
2629 Local<Object> process_object = env->process_object();
2630 Local<String> fatal_exception_string = env->fatal_exception_string();
2631 Local<Function> fatal_exception_function =
2632 process_object->Get(fatal_exception_string).As<Function>();
2635 if (!fatal_exception_function->IsFunction()) {
2638 ReportException(env, error, message);
2642 if (exit_code == 0) {
2643 TryCatch fatal_try_catch(isolate);
2646 fatal_try_catch.SetVerbose(
false);
2649 Local<Value> caught =
2650 fatal_exception_function->Call(process_object, 1, &error);
2652 if (fatal_try_catch.HasCaught()) {
2654 ReportException(env, fatal_try_catch);
2658 if (exit_code == 0 &&
false == caught->BooleanValue()) {
2659 ReportException(env, error, message);
2666 env->inspector_agent()->FatalException(error, message);
2674 HandleScope scope(isolate);
2675 if (!try_catch.IsVerbose()) {
2676 FatalException(isolate, try_catch.Exception(), try_catch.Message());
2681 static void OnMessage(Local<Message> message, Local<Value> error) {
2689 Local<Object> process = env->process_object();
2690 Local<Value> events =
2691 process->Get(env->context(), env->events_string()).ToLocalChecked();
2693 if (events->IsObject()) {
2694 events.As<Object>()->Set(
2696 OneByteString(env->isolate(),
"uncaughtException"),
2697 Undefined(env->isolate())).FromJust();
2702 env->domain_string(),
2703 Undefined(env->isolate())).FromJust();
2712 vsnprintf(warning,
sizeof(warning), fmt, ap);
2715 HandleScope handle_scope(env->isolate());
2716 Context::Scope context_scope(env->context());
2718 Local<Object> process = env->process_object();
2719 MaybeLocal<Value> emit_warning = process->Get(env->context(),
2720 FIXED_ONE_BYTE_STRING(env->isolate(),
"emitWarning"));
2721 Local<Value> arg = node::OneByteString(env->isolate(), warning);
2725 if (!emit_warning.ToLocal(&f))
return;
2726 if (!f->IsFunction())
return;
2730 f.As<v8::Function>()->Call(process, 1, &arg);
2734 static void Binding(
const FunctionCallbackInfo<Value>& args) {
2735 Environment* env = Environment::GetCurrent(args);
2737 Local<String> module = args[0]->ToString(env->isolate());
2738 node::Utf8Value module_v(env->isolate(), module);
2740 Local<Object> cache = env->binding_cache_object();
2741 Local<Object> exports;
2743 if (cache->Has(env->context(), module).FromJust()) {
2744 exports = cache->Get(module)->ToObject(env->isolate());
2745 args.GetReturnValue().Set(exports);
2751 snprintf(buf,
sizeof(buf),
"Binding %s", *module_v);
2753 Local<Array> modules = env->module_load_list_array();
2754 uint32_t l = modules->Length();
2755 modules->Set(l, OneByteString(env->isolate(),
buf));
2758 if (mod !=
nullptr) {
2763 Local<Value> unused = Undefined(env->isolate());
2765 env->context(), mod->
nm_priv);
2766 cache->Set(module, exports);
2767 }
else if (!strcmp(*module_v,
"constants")) {
2769 CHECK(exports->SetPrototype(env->context(),
2770 Null(env->isolate())).FromJust());
2772 cache->Set(module, exports);
2773 }
else if (!strcmp(*module_v,
"natives")) {
2775 DefineJavaScript(env, exports);
2776 cache->Set(module, exports);
2781 "No such module: %s",
2783 return env->ThrowError(errmsg);
2786 args.GetReturnValue().Set(exports);
2789 static void LinkedBinding(
const FunctionCallbackInfo<Value>& args) {
2790 Environment* env = Environment::GetCurrent(args.GetIsolate());
2792 Local<String> module_name = args[0]->ToString(env->isolate());
2794 Local<Object> cache = env->binding_cache_object();
2795 Local<Value> exports_v = cache->Get(module_name);
2797 if (exports_v->IsObject())
2798 return args.GetReturnValue().Set(exports_v.As<Object>());
2800 node::Utf8Value module_name_v(env->isolate(), module_name);
2803 if (mod ==
nullptr) {
2807 "No such module was linked: %s",
2809 return env->ThrowError(errmsg);
2812 Local<Object> module =
Object::New(env->isolate());
2813 Local<Object> exports =
Object::New(env->isolate());
2814 Local<String> exports_prop = String::NewFromUtf8(env->isolate(),
"exports");
2815 module->Set(exports_prop, exports);
2817 if (mod->nm_context_register_func !=
nullptr) {
2818 mod->nm_context_register_func(exports,
2822 }
else if (mod->nm_register_func !=
nullptr) {
2823 mod->nm_register_func(exports, module, mod->nm_priv);
2825 return env->ThrowError(
"Linked module has no declared entry point.");
2828 auto effective_exports = module->Get(exports_prop);
2829 cache->Set(module_name, effective_exports);
2831 args.GetReturnValue().Set(effective_exports);
2834 static void ProcessTitleGetter(Local<Name> property,
2835 const PropertyCallbackInfo<Value>& info) {
2837 uv_get_process_title(buffer,
sizeof(buffer));
2838 info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), buffer));
2842 static void ProcessTitleSetter(Local<Name> property,
2844 const PropertyCallbackInfo<void>& info) {
2845 node::Utf8Value title(info.GetIsolate(), value);
2847 uv_set_process_title(*title);
2851 static void EnvGetter(Local<Name> property,
2852 const PropertyCallbackInfo<Value>& info) {
2853 Isolate* isolate = info.GetIsolate();
2854 if (property->IsSymbol()) {
2855 return info.GetReturnValue().SetUndefined();
2858 node::Utf8Value key(isolate, property);
2859 const char* val = getenv(*key);
2861 return info.GetReturnValue().Set(String::NewFromUtf8(isolate, val));
2864 node::TwoByteValue key(isolate, property);
2865 WCHAR buffer[32767];
2866 DWORD result = GetEnvironmentVariableW(reinterpret_cast<WCHAR*>(*key),
2872 if ((result > 0 || GetLastError() == ERROR_SUCCESS) &&
2873 result < arraysize(buffer)) {
2874 const uint16_t* two_byte_buffer =
reinterpret_cast<const uint16_t*
>(buffer);
2875 Local<String> rc = String::NewFromTwoByte(isolate, two_byte_buffer);
2876 return info.GetReturnValue().Set(rc);
2882 static void EnvSetter(Local<Name> property,
2884 const PropertyCallbackInfo<Value>& info) {
2886 node::Utf8Value key(info.GetIsolate(), property);
2887 node::Utf8Value val(info.GetIsolate(), value);
2888 setenv(*key, *val, 1);
2890 node::TwoByteValue key(info.GetIsolate(), property);
2891 node::TwoByteValue val(info.GetIsolate(), value);
2892 WCHAR* key_ptr =
reinterpret_cast<WCHAR*
>(*key);
2894 if (key_ptr[0] != L
'=') {
2895 SetEnvironmentVariableW(key_ptr, reinterpret_cast<WCHAR*>(*val));
2899 info.GetReturnValue().Set(value);
2903 static void EnvQuery(Local<Name> property,
2904 const PropertyCallbackInfo<Integer>& info) {
2906 if (property->IsString()) {
2908 node::Utf8Value key(info.GetIsolate(), property);
2912 node::TwoByteValue key(info.GetIsolate(), property);
2913 WCHAR* key_ptr =
reinterpret_cast<WCHAR*
>(*key);
2914 if (GetEnvironmentVariableW(key_ptr,
nullptr, 0) > 0 ||
2915 GetLastError() == ERROR_SUCCESS) {
2917 if (key_ptr[0] == L
'=') {
2919 rc =
static_cast<int32_t
>(v8::ReadOnly) |
2920 static_cast<int32_t>(v8::DontDelete) |
2921 static_cast<int32_t
>(v8::DontEnum);
2927 info.GetReturnValue().Set(rc);
2931 static void EnvDeleter(Local<Name> property,
2932 const PropertyCallbackInfo<Boolean>& info) {
2933 if (property->IsString()) {
2935 node::Utf8Value key(info.GetIsolate(), property);
2938 node::TwoByteValue key(info.GetIsolate(), property);
2939 WCHAR* key_ptr =
reinterpret_cast<WCHAR*
>(*key);
2940 SetEnvironmentVariableW(key_ptr,
nullptr);
2946 info.GetReturnValue().Set(
true);
2950 static void EnvEnumerator(
const PropertyCallbackInfo<Array>& info) {
2951 Environment* env = Environment::GetCurrent(info);
2952 Isolate* isolate = env->isolate();
2953 Local<Context>
ctx = env->context();
2954 Local<Function> fn = env->push_values_to_array_function();
2955 Local<Value> argv[NODE_PUSH_VAL_TO_ARRAY_MAX];
2965 for (
int i = 0; i < size; ++i) {
2967 const char*
s = strchr(var,
'=');
2968 const int length = s ? s - var : strlen(var);
2969 argv[idx] = String::NewFromUtf8(isolate,
2971 String::kNormalString,
2973 if (++idx >= arraysize(argv)) {
2974 fn->Call(ctx, envarr, idx, argv).ToLocalChecked();
2979 fn->Call(ctx, envarr, idx, argv).ToLocalChecked();
2982 WCHAR* environment = GetEnvironmentStringsW();
2983 if (environment ==
nullptr)
2986 WCHAR*
p = environment;
2994 s = wcschr(p, L
'=');
2999 const uint16_t* two_byte_buffer =
reinterpret_cast<const uint16_t*
>(
p);
3000 const size_t two_byte_buffer_len = s -
p;
3001 argv[idx] = String::NewFromTwoByte(isolate,
3003 String::kNormalString,
3004 two_byte_buffer_len);
3005 if (++idx >= arraysize(argv)) {
3006 fn->Call(ctx, envarr, idx, argv).ToLocalChecked();
3009 p = s + wcslen(s) + 1;
3012 fn->Call(ctx, envarr, idx, argv).ToLocalChecked();
3014 FreeEnvironmentStringsW(environment);
3017 info.GetReturnValue().Set(envarr);
3021 static Local<Object> GetFeatures(Environment* env) {
3022 EscapableHandleScope scope(env->isolate());
3025 #if defined(DEBUG) && DEBUG 3026 Local<Value> debug = True(env->isolate());
3028 Local<Value> debug = False(env->isolate());
3029 #endif // defined(DEBUG) && DEBUG 3031 obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(),
"debug"), debug);
3032 obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(),
"uv"), True(env->isolate()));
3034 obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(),
"ipv6"), True(env->isolate()));
3036 #ifndef OPENSSL_NO_NEXTPROTONEG 3037 Local<Boolean> tls_npn = True(env->isolate());
3039 Local<Boolean> tls_npn = False(env->isolate());
3041 obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(),
"tls_npn"), tls_npn);
3043 #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation 3044 Local<Boolean> tls_alpn = True(env->isolate());
3046 Local<Boolean> tls_alpn = False(env->isolate());
3048 obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(),
"tls_alpn"), tls_alpn);
3050 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB 3051 Local<Boolean> tls_sni = True(env->isolate());
3053 Local<Boolean> tls_sni = False(env->isolate());
3055 obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(),
"tls_sni"), tls_sni);
3057 #if !defined(OPENSSL_NO_TLSEXT) && defined(SSL_CTX_set_tlsext_status_cb) 3058 Local<Boolean> tls_ocsp = True(env->isolate());
3060 Local<Boolean> tls_ocsp = False(env->isolate());
3061 #endif // !defined(OPENSSL_NO_TLSEXT) && defined(SSL_CTX_set_tlsext_status_cb) 3062 obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(),
"tls_ocsp"), tls_ocsp);
3064 obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(),
"tls"),
3068 return scope.Escape(obj);
3072 static void DebugPortGetter(Local<Name> property,
3073 const PropertyCallbackInfo<Value>& info) {
3074 int port = debug_options.
port();
3077 Environment* env = Environment::GetCurrent(info);
3078 if (
auto io = env->inspector_agent()->io())
3081 #endif // HAVE_INSPECTOR 3082 info.GetReturnValue().Set(port);
3086 static void DebugPortSetter(Local<Name> property,
3088 const PropertyCallbackInfo<void>& info) {
3089 debug_options.
set_port(value->Int32Value());
3093 static void DebugProcess(
const FunctionCallbackInfo<Value>& args);
3094 static void DebugPause(
const FunctionCallbackInfo<Value>& args);
3095 static void DebugEnd(
const FunctionCallbackInfo<Value>& args);
3099 void NeedImmediateCallbackGetter(Local<Name> property,
3100 const PropertyCallbackInfo<Value>& info) {
3101 Environment* env = Environment::GetCurrent(info);
3102 const uv_check_t* immediate_check_handle = env->immediate_check_handle();
3103 bool active = uv_is_active(
3104 reinterpret_cast<const uv_handle_t*>(immediate_check_handle));
3105 info.GetReturnValue().Set(active);
3109 void NeedImmediateCallbackSetter(
3110 Local<Name> property,
3112 const PropertyCallbackInfo<void>& info) {
3113 Environment* env = Environment::GetCurrent(info);
3115 uv_check_t* immediate_check_handle = env->immediate_check_handle();
3116 bool active = uv_is_active(
3117 reinterpret_cast<const uv_handle_t*>(immediate_check_handle));
3119 if (active == value->BooleanValue())
3122 uv_idle_t* immediate_idle_handle = env->immediate_idle_handle();
3125 uv_check_stop(immediate_check_handle);
3126 uv_idle_stop(immediate_idle_handle);
3128 uv_check_start(immediate_check_handle, CheckImmediate);
3130 uv_idle_start(immediate_idle_handle, IdleImmediateDummy);
3135 void StartProfilerIdleNotifier(
const FunctionCallbackInfo<Value>& args) {
3136 Environment* env = Environment::GetCurrent(args);
3137 env->StartProfilerIdleNotifier();
3141 void StopProfilerIdleNotifier(
const FunctionCallbackInfo<Value>& args) {
3142 Environment* env = Environment::GetCurrent(args);
3143 env->StopProfilerIdleNotifier();
3147 #define READONLY_PROPERTY(obj, str, var) \ 3149 obj->DefineOwnProperty(env->context(), \ 3150 OneByteString(env->isolate(), str), \ 3152 v8::ReadOnly).FromJust(); \ 3155 #define READONLY_DONT_ENUM_PROPERTY(obj, str, var) \ 3157 obj->DefineOwnProperty(env->context(), \ 3158 OneByteString(env->isolate(), str), \ 3160 static_cast<v8::PropertyAttribute>(v8::ReadOnly | \ 3169 const char*
const* argv,
3171 const char*
const* exec_argv) {
3172 HandleScope scope(env->isolate());
3174 Local<Object> process = env->process_object();
3176 auto title_string = FIXED_ONE_BYTE_STRING(env->isolate(),
"title");
3177 CHECK(process->SetAccessor(env->context(),
3181 env->as_external()).FromJust());
3191 env->module_load_list_array());
3194 Local<Object> versions =
Object::New(env->isolate());
3197 const char http_parser_version[] =
NODE_STRINGIFY(HTTP_PARSER_VERSION_MAJOR)
3204 FIXED_ONE_BYTE_STRING(env->isolate(), http_parser_version));
3212 OneByteString(env->isolate(), V8::GetVersion()));
3215 OneByteString(env->isolate(), uv_version_string()));
3218 FIXED_ONE_BYTE_STRING(env->isolate(), ZLIB_VERSION));
3221 FIXED_ONE_BYTE_STRING(env->isolate(), ARES_VERSION_STR));
3227 FIXED_ONE_BYTE_STRING(env->isolate(), node_modules_version));
3231 FIXED_ONE_BYTE_STRING(env->isolate(), NGHTTP2_VERSION));
3234 Local<Object> promiseRejectEvent =
Object::New(env->isolate());
3236 "_promiseRejectEvent",
3237 promiseRejectEvent);
3241 v8::kPromiseRejectWithNoHandler));
3245 v8::kPromiseHandlerAddedAfterReject));
3252 for (i = j = 0, k =
sizeof(OPENSSL_VERSION_TEXT) - 1; i < k; ++i) {
3253 c = OPENSSL_VERSION_TEXT[i];
3254 if (
'0' <= c && c <=
'9') {
3255 for (j = i + 1; j < k; ++j) {
3256 c = OPENSSL_VERSION_TEXT[j];
3266 OneByteString(env->isolate(), &OPENSSL_VERSION_TEXT[i], j - i));
3276 OneByteString(env->isolate(), NODE_PLATFORM));
3279 Local<Object> release =
Object::New(env->isolate());
3286 #ifndef NODE_RELEASE_URLBASE 3287 # if NODE_VERSION_IS_RELEASE 3288 # define NODE_RELEASE_URLBASE "https://nodejs.org/download/release/" 3292 #if defined(NODE_RELEASE_URLBASE) 3293 # define NODE_RELEASE_URLPFX NODE_RELEASE_URLBASE "v" NODE_VERSION_STRING "/" 3294 # define NODE_RELEASE_URLFPFX NODE_RELEASE_URLPFX "node-v" NODE_VERSION_STRING 3298 OneByteString(env->isolate(),
3299 NODE_RELEASE_URLFPFX
".tar.gz"));
3302 OneByteString(env->isolate(),
3303 NODE_RELEASE_URLFPFX
"-headers.tar.gz"));
3307 OneByteString(env->isolate(),
3308 strcmp(NODE_ARCH,
"ia32") ? NODE_RELEASE_URLPFX
"win-" 3309 NODE_ARCH
"/node.lib" 3310 : NODE_RELEASE_URLPFX
3311 "win-x86/node.lib"));
3316 Local<Array> arguments =
Array::New(env->isolate(), argc);
3317 for (
int i = 0; i < argc; ++i) {
3318 arguments->Set(i, String::NewFromUtf8(env->isolate(), argv[i]));
3320 process->Set(FIXED_ONE_BYTE_STRING(env->isolate(),
"argv"), arguments);
3323 Local<Array> exec_arguments =
Array::New(env->isolate(), exec_argc);
3324 for (
int i = 0; i < exec_argc; ++i) {
3325 exec_arguments->Set(i, String::NewFromUtf8(env->isolate(), exec_argv[i]));
3327 process->Set(FIXED_ONE_BYTE_STRING(env->isolate(),
"execArgv"),
3331 Local<ObjectTemplate> process_env_template =
3333 process_env_template->SetHandler(NamedPropertyHandlerConfiguration(
3339 env->as_external()));
3341 Local<Object> process_env =
3342 process_env_template->NewInstance(env->context()).ToLocalChecked();
3343 process->Set(FIXED_ONE_BYTE_STRING(env->isolate(),
"env"), process_env);
3348 auto need_immediate_callback_string =
3349 FIXED_ONE_BYTE_STRING(env->isolate(),
"_needImmediateCallback");
3350 CHECK(process->SetAccessor(env->context(), need_immediate_callback_string,
3351 NeedImmediateCallbackGetter,
3352 NeedImmediateCallbackSetter,
3353 env->as_external()).FromJust());
3359 String::NewFromUtf8(env->isolate(), eval_string));
3368 if (syntax_check_only) {
3378 if (!preload_modules.empty()) {
3379 Local<Array> array =
Array::New(env->isolate());
3380 for (
unsigned int i = 0; i < preload_modules.size(); ++i) {
3381 Local<String> module = String::NewFromUtf8(env->isolate(),
3382 preload_modules[i].c_str());
3383 array->Set(i, module);
3389 preload_modules.clear();
3393 if (no_deprecation) {
3398 if (no_process_warnings) {
3403 if (trace_warnings) {
3408 if (throw_deprecation) {
3412 #ifdef NODE_NO_BROWSER_GLOBALS 3415 #endif // NODE_NO_BROWSER_GLOBALS 3423 if (trace_deprecation) {
3431 "_breakFirstLine", True(env->isolate()));
3437 "_deprecatedDebugBrk", True(env->isolate()));
3443 "_invalidDebug", True(env->isolate()));
3447 #define V(code, _, __) \ 3449 if (IsReverted(SECURITY_REVERT_ ## code)) { \ 3450 READONLY_PROPERTY(process, "REVERT_" #code, True(env->isolate())); \ 3453 SECURITY_REVERSIONS(
V)
3456 size_t exec_path_len = 2 * PATH_MAX;
3457 char* exec_path =
new char[exec_path_len];
3458 Local<String> exec_path_value;
3459 if (uv_exepath(exec_path, &exec_path_len) == 0) {
3460 exec_path_value = String::NewFromUtf8(env->isolate(),
3462 String::kNormalString,
3465 exec_path_value = String::NewFromUtf8(env->isolate(), argv[0]);
3467 process->Set(FIXED_ONE_BYTE_STRING(env->isolate(),
"execPath"),
3471 auto debug_port_string = FIXED_ONE_BYTE_STRING(env->isolate(),
"debugPort");
3472 CHECK(process->SetAccessor(env->context(),
3476 env->as_external()).FromJust());
3479 env->SetMethod(process,
3480 "_startProfilerIdleNotifier",
3481 StartProfilerIdleNotifier);
3482 env->SetMethod(process,
3483 "_stopProfilerIdleNotifier",
3484 StopProfilerIdleNotifier);
3485 env->SetMethod(process,
"_getActiveRequests", GetActiveRequests);
3487 env->SetMethod(process,
"reallyExit", Exit);
3488 env->SetMethod(process,
"abort",
Abort);
3489 env->SetMethod(process,
"chdir", Chdir);
3490 env->SetMethod(process,
"cwd", Cwd);
3492 env->SetMethod(process,
"umask", Umask);
3494 #if defined(__POSIX__) && !defined(__ANDROID__) 3495 env->SetMethod(process,
"getuid", GetUid);
3496 env->SetMethod(process,
"geteuid", GetEUid);
3497 env->SetMethod(process,
"setuid", SetUid);
3498 env->SetMethod(process,
"seteuid", SetEUid);
3500 env->SetMethod(process,
"setgid", SetGid);
3501 env->SetMethod(process,
"setegid", SetEGid);
3502 env->SetMethod(process,
"getgid", GetGid);
3503 env->SetMethod(process,
"getegid", GetEGid);
3505 env->SetMethod(process,
"getgroups", GetGroups);
3506 env->SetMethod(process,
"setgroups", SetGroups);
3507 env->SetMethod(process,
"initgroups", InitGroups);
3508 #endif // __POSIX__ && !defined(__ANDROID__) 3510 env->SetMethod(process,
"_kill", Kill);
3512 env->SetMethod(process,
"_debugProcess", DebugProcess);
3513 env->SetMethod(process,
"_debugPause", DebugPause);
3514 env->SetMethod(process,
"_debugEnd", DebugEnd);
3516 env->SetMethod(process,
"hrtime", Hrtime);
3518 env->SetMethod(process,
"cpuUsage", CPUUsage);
3520 env->SetMethod(process,
"dlopen", DLOpen);
3522 env->SetMethod(process,
"uptime", Uptime);
3523 env->SetMethod(process,
"memoryUsage", MemoryUsage);
3525 env->SetMethod(process,
"binding", Binding);
3526 env->SetMethod(process,
"_linkedBinding", LinkedBinding);
3529 env->SetMethod(process,
"_setupNextTick", SetupNextTick);
3530 env->SetMethod(process,
"_setupPromises", SetupPromises);
3531 env->SetMethod(process,
"_setupDomainUse", SetupDomainUse);
3534 Local<Object> events_obj =
Object::New(env->isolate());
3535 CHECK(events_obj->SetPrototype(env->context(),
3536 Null(env->isolate())).FromJust());
3537 process->Set(env->events_string(), events_obj);
3541 #undef READONLY_PROPERTY 3545 uv_tty_reset_mode();
3546 if (trace_enabled) {
3547 v8_platform.StopTracingAgent();
3551 struct sigaction sa;
3552 memset(&sa, 0,
sizeof(sa));
3553 sa.sa_handler = SIG_DFL;
3554 CHECK_EQ(sigaction(signo, &sa,
nullptr), 0);
3564 static void RawDebug(
const FunctionCallbackInfo<Value>& args) {
3565 CHECK(args.Length() == 1 && args[0]->IsString() &&
3566 "must be called with a single string");
3567 node::Utf8Value message(args.GetIsolate(), args[0]);
3568 PrintErrorString(
"%s\n", *message);
3574 HandleScope handle_scope(env->isolate());
3576 TryCatch try_catch(env->isolate());
3581 try_catch.SetVerbose(
false);
3586 Local<String> script_name = FIXED_ONE_BYTE_STRING(env->isolate(),
3587 "bootstrap_node.js");
3588 Local<Value> f_value = ExecuteString(env, MainSource(env), script_name);
3589 if (try_catch.HasCaught()) {
3590 ReportException(env, try_catch);
3594 CHECK(f_value->IsFunction());
3595 Local<Function> f = Local<Function>::Cast(f_value);
3598 Local<Object> global = env->context()->Global();
3600 #if defined HAVE_DTRACE || defined HAVE_ETW 3604 #if defined HAVE_LTTNG 3608 #if defined HAVE_PERFCTR 3618 try_catch.SetVerbose(
true);
3620 env->SetMethod(env->process_object(),
"_rawDebug", RawDebug);
3624 global->Set(FIXED_ONE_BYTE_STRING(env->isolate(),
"global"), global);
3633 Local<Value> arg = env->process_object();
3634 f->Call(Null(env->isolate()), 1, &arg);
3637 static void PrintHelp() {
3640 printf(
"Usage: node [options] [ -e script | script.js | - ] [arguments]\n" 3641 " node inspect script.js [arguments]\n" 3644 " -v, --version print Node.js version\n" 3645 " -e, --eval script evaluate script\n" 3646 " -p, --print evaluate script and print result\n" 3647 " -c, --check syntax check script without executing\n" 3648 " -i, --interactive always enter the REPL even if stdin\n" 3649 " does not appear to be a terminal\n" 3650 " -r, --require module to preload (option can be " 3652 " - script read from stdin (default; " 3653 "interactive mode if a tty)\n" 3655 " --inspect[=[host:]port] activate inspector on host:port\n" 3656 " (default: 127.0.0.1:9229)\n" 3657 " --inspect-brk[=[host:]port]\n" 3658 " activate inspector on host:port\n" 3659 " and break at start of user script\n" 3660 " --inspect-port=[host:]port\n" 3661 " set host:port for inspector\n" 3663 " --no-deprecation silence deprecation warnings\n" 3664 " --trace-deprecation show stack traces on deprecations\n" 3665 " --throw-deprecation throw an exception on deprecations\n" 3666 " --pending-deprecation emit pending deprecation warnings\n" 3667 " --no-warnings silence all process warnings\n" 3668 " --napi-modules load N-API modules\n" 3669 " --abort-on-uncaught-exception\n" 3670 " aborting instead of exiting causes a\n" 3671 " core file to be generated for analysis\n" 3672 " --expose-http2 enable experimental HTTP2 support\n" 3673 " --trace-warnings show stack traces on process warnings\n" 3674 " --redirect-warnings=file\n" 3675 " write warnings to file instead of\n" 3677 " --trace-sync-io show stack trace when use of sync IO\n" 3678 " is detected after the first tick\n" 3679 " --trace-events-enabled track trace events\n" 3680 " --trace-event-categories comma separated list of trace event\n" 3681 " categories to record\n" 3682 " --track-heap-objects track heap object allocations for heap " 3684 " --prof-process process v8 profiler output generated\n" 3686 " --zero-fill-buffers automatically zero-fill all newly " 3688 " Buffer and SlowBuffer instances\n" 3689 " --v8-options print v8 command line options\n" 3690 " --v8-pool-size=num set v8's thread pool size\n" 3692 " --tls-cipher-list=val use an alternative default TLS cipher " 3694 " --use-bundled-ca use bundled CA store" 3695 #
if !defined(NODE_OPENSSL_CERT_STORE)
3699 " --use-openssl-ca use OpenSSL's default CA store" 3700 #
if defined(NODE_OPENSSL_CERT_STORE)
3705 " --enable-fips enable FIPS crypto at startup\n" 3706 " --force-fips force FIPS crypto (cannot be disabled)\n" 3708 " --openssl-config=file load OpenSSL configuration from the\n" 3709 " specified file (overrides\n" 3712 #
if defined(NODE_HAVE_I18N_SUPPORT)
3713 " --icu-data-dir=dir set ICU data load path to dir\n" 3714 " (overrides NODE_ICU_DATA)\n" 3715 #
if !defined(NODE_HAVE_SMALL_ICU)
3716 " note: linked-in ICU data is present\n" 3718 " --preserve-symlinks preserve symbolic links when resolving\n" 3719 " --experimental-modules experimental ES Module support\n" 3720 " and caching modules\n" 3723 "Environment variables:\n" 3724 "NODE_DEBUG ','-separated list of core modules\n" 3725 " that should print debug information\n" 3726 "NODE_DISABLE_COLORS set to 1 to disable colors in the REPL\n" 3727 "NODE_EXTRA_CA_CERTS path to additional CA certificates\n" 3729 #
if defined(NODE_HAVE_I18N_SUPPORT)
3730 "NODE_ICU_DATA data path for ICU (Intl object) data\n" 3731 #
if !defined(NODE_HAVE_SMALL_ICU)
3732 " (will extend linked-in data)\n" 3735 "NODE_NO_WARNINGS set to 1 to silence process warnings\n" 3736 #
if !defined(NODE_WITHOUT_NODE_OPTIONS)
3737 "NODE_OPTIONS set CLI options in the environment\n" 3738 " via a space-separated list\n" 3741 "NODE_PATH ';'-separated list of directories\n" 3743 "NODE_PATH ':'-separated list of directories\n" 3745 " prefixed to the module search path\n" 3746 "NODE_REPL_HISTORY path to the persistent REPL history\n" 3748 "NODE_REDIRECT_WARNINGS write warnings to path instead of\n" 3750 "OPENSSL_CONF load OpenSSL configuration from file\n" 3752 "Documentation can be found at https://nodejs.org/\n");
3756 static bool ArgIsAllowed(
const char* arg,
const char* allowed) {
3757 for (; *arg && *allowed; arg++, allowed++) {
3760 if (*allowed ==
'_') {
3761 if (!(*arg ==
'_' || *arg ==
'-'))
3764 if (*arg != *allowed)
3775 return !*arg && !*allowed;
3779 static void CheckIfAllowedInEnv(
const char* exe,
bool is_env,
3784 static const char* whitelist[] = {
3791 "--trace-deprecation",
3792 "--throw-deprecation",
3797 "--redirect-warnings",
3799 "--trace-events-enabled",
3800 "--trace-events-categories",
3801 "--track-heap-objects",
3802 "--zero-fill-buffers",
3804 "--tls-cipher-list",
3813 "--abort_on_uncaught_exception",
3814 "--max_old_space_size",
3817 for (
unsigned i = 0; i < arraysize(whitelist); i++) {
3818 const char* allowed = whitelist[i];
3819 if (ArgIsAllowed(arg, allowed))
3823 fprintf(stderr,
"%s: %s is not allowed in NODE_OPTIONS\n", exe, arg);
3839 static void ParseArgs(
int* argc,
3842 const char*** exec_argv,
3844 const char*** v8_argv,
3846 const unsigned int nargs =
static_cast<unsigned int>(*argc);
3847 const char** new_exec_argv =
new const char*[nargs];
3848 const char** new_v8_argv =
new const char*[nargs];
3849 const char** new_argv =
new const char*[nargs];
3851 bool use_bundled_ca =
false;
3852 bool use_openssl_ca =
false;
3853 #endif // HAVE_OPENSSL 3855 for (
unsigned int i = 0; i < nargs; ++i) {
3856 new_exec_argv[i] =
nullptr;
3857 new_v8_argv[i] =
nullptr;
3858 new_argv[i] =
nullptr;
3862 unsigned int new_exec_argc = 0;
3863 unsigned int new_v8_argc = 1;
3864 unsigned int new_argc = 1;
3865 new_v8_argv[0] = argv[0];
3866 new_argv[0] = argv[0];
3868 unsigned int index = 1;
3869 bool short_circuit =
false;
3870 while (index < nargs && argv[index][0] ==
'-' && !short_circuit) {
3871 const char*
const arg = argv[index];
3872 unsigned int args_consumed = 1;
3874 CheckIfAllowedInEnv(argv[0], is_env, arg);
3878 }
else if (strcmp(arg,
"--version") == 0 || strcmp(arg,
"-v") == 0) {
3881 }
else if (strcmp(arg,
"--help") == 0 || strcmp(arg,
"-h") == 0) {
3884 }
else if (strcmp(arg,
"--eval") == 0 ||
3885 strcmp(arg,
"-e") == 0 ||
3886 strcmp(arg,
"--print") == 0 ||
3887 strcmp(arg,
"-pe") == 0 ||
3888 strcmp(arg,
"-p") == 0) {
3889 bool is_eval = strchr(arg,
'e') !=
nullptr;
3890 bool is_print = strchr(arg,
'p') !=
nullptr;
3891 print_eval = print_eval || is_print;
3893 if (is_eval ==
true) {
3895 eval_string = argv[index + 1];
3896 if (eval_string ==
nullptr) {
3897 fprintf(stderr,
"%s: %s requires an argument\n", argv[0], arg);
3900 }
else if ((index + 1 < nargs) &&
3901 argv[index + 1] !=
nullptr &&
3902 argv[index + 1][0] !=
'-') {
3904 eval_string = argv[index + 1];
3905 if (strncmp(eval_string,
"\\-", 2) == 0) {
3910 }
else if (strcmp(arg,
"--require") == 0 ||
3911 strcmp(arg,
"-r") == 0) {
3912 const char* module = argv[index + 1];
3913 if (module ==
nullptr) {
3914 fprintf(stderr,
"%s: %s requires an argument\n", argv[0], arg);
3918 preload_modules.push_back(module);
3919 }
else if (strcmp(arg,
"--check") == 0 || strcmp(arg,
"-c") == 0) {
3920 syntax_check_only =
true;
3921 }
else if (strcmp(arg,
"--interactive") == 0 || strcmp(arg,
"-i") == 0) {
3923 }
else if (strcmp(arg,
"--no-deprecation") == 0) {
3924 no_deprecation =
true;
3925 }
else if (strcmp(arg,
"--napi-modules") == 0) {
3926 load_napi_modules =
true;
3927 }
else if (strcmp(arg,
"--no-warnings") == 0) {
3928 no_process_warnings =
true;
3929 }
else if (strcmp(arg,
"--trace-warnings") == 0) {
3930 trace_warnings =
true;
3931 }
else if (strncmp(arg,
"--redirect-warnings=", 20) == 0) {
3932 config_warning_file = arg + 20;
3933 }
else if (strcmp(arg,
"--trace-deprecation") == 0) {
3934 trace_deprecation =
true;
3935 }
else if (strcmp(arg,
"--trace-sync-io") == 0) {
3936 trace_sync_io =
true;
3937 }
else if (strcmp(arg,
"--trace-events-enabled") == 0) {
3938 trace_enabled =
true;
3939 }
else if (strcmp(arg,
"--trace-event-categories") == 0) {
3940 const char* categories = argv[index + 1];
3941 if (categories ==
nullptr) {
3942 fprintf(stderr,
"%s: %s requires an argument\n", argv[0], arg);
3946 trace_enabled_categories = categories;
3947 }
else if (strcmp(arg,
"--track-heap-objects") == 0) {
3948 track_heap_objects =
true;
3949 }
else if (strcmp(arg,
"--throw-deprecation") == 0) {
3950 throw_deprecation =
true;
3951 }
else if (strncmp(arg,
"--security-revert=", 18) == 0) {
3952 const char* cve = arg + 18;
3954 }
else if (strcmp(arg,
"--preserve-symlinks") == 0) {
3955 config_preserve_symlinks =
true;
3956 }
else if (strcmp(arg,
"--experimental-modules") == 0) {
3957 config_experimental_modules =
true;
3958 }
else if (strcmp(arg,
"--prof-process") == 0) {
3959 prof_process =
true;
3960 short_circuit =
true;
3961 }
else if (strcmp(arg,
"--zero-fill-buffers") == 0) {
3963 }
else if (strcmp(arg,
"--pending-deprecation") == 0) {
3964 config_pending_deprecation =
true;
3965 }
else if (strcmp(arg,
"--v8-options") == 0) {
3966 new_v8_argv[new_v8_argc] =
"--help";
3968 }
else if (strncmp(arg,
"--v8-pool-size=", 15) == 0) {
3969 v8_thread_pool_size = atoi(arg + 15);
3971 }
else if (strncmp(arg,
"--tls-cipher-list=", 18) == 0) {
3972 default_cipher_list = arg + 18;
3973 }
else if (strncmp(arg,
"--use-openssl-ca", 16) == 0) {
3974 ssl_openssl_cert_store =
true;
3975 use_openssl_ca =
true;
3976 }
else if (strncmp(arg,
"--use-bundled-ca", 16) == 0) {
3977 use_bundled_ca =
true;
3978 ssl_openssl_cert_store =
false;
3980 }
else if (strcmp(arg,
"--enable-fips") == 0) {
3981 enable_fips_crypto =
true;
3982 }
else if (strcmp(arg,
"--force-fips") == 0) {
3983 force_fips_crypto =
true;
3985 }
else if (strncmp(arg,
"--openssl-config=", 17) == 0) {
3986 openssl_config.assign(arg + 17);
3988 #if defined(NODE_HAVE_I18N_SUPPORT) 3989 }
else if (strncmp(arg,
"--icu-data-dir=", 15) == 0) {
3990 icu_data_dir.assign(arg + 15);
3992 }
else if (strcmp(arg,
"--expose-internals") == 0 ||
3993 strcmp(arg,
"--expose_internals") == 0) {
3994 config_expose_internals =
true;
3995 }
else if (strcmp(arg,
"--expose-http2") == 0 ||
3996 strcmp(arg,
"--expose_http2") == 0) {
3997 config_expose_http2 =
true;
3998 }
else if (strcmp(arg,
"-") == 0) {
4000 }
else if (strcmp(arg,
"--") == 0) {
4003 }
else if (strcmp(arg,
"--abort-on-uncaught-exception") == 0 ||
4004 strcmp(arg,
"--abort_on_uncaught_exception") == 0) {
4005 abort_on_uncaught_exception =
true;
4007 new_v8_argv[new_v8_argc] = arg;
4011 new_v8_argv[new_v8_argc] = arg;
4015 memcpy(new_exec_argv + new_exec_argc,
4017 args_consumed *
sizeof(*argv));
4019 new_exec_argc += args_consumed;
4020 index += args_consumed;
4024 if (use_openssl_ca && use_bundled_ca) {
4026 "%s: either --use-openssl-ca or --use-bundled-ca can be used, " 4033 if (eval_string !=
nullptr && syntax_check_only) {
4035 "%s: either --check or --eval can be used, not both\n", argv[0]);
4040 const unsigned int args_left = nargs - index;
4042 if (is_env && args_left) {
4043 fprintf(stderr,
"%s: %s is not supported in NODE_OPTIONS\n",
4044 argv[0], argv[index]);
4048 memcpy(new_argv + new_argc, argv + index, args_left *
sizeof(*argv));
4049 new_argc += args_left;
4051 *exec_argc = new_exec_argc;
4052 *exec_argv = new_exec_argv;
4053 *v8_argc = new_v8_argc;
4054 *v8_argv = new_v8_argv;
4057 memcpy(argv, new_argv, new_argc *
sizeof(*argv));
4059 *argc =
static_cast<int>(new_argc);
4063 static void StartInspector(Environment* env,
const char* path,
4066 CHECK(!env->inspector_agent()->IsStarted());
4067 v8_platform.StartInspector(env, path, debug_options);
4068 #endif // HAVE_INSPECTOR 4073 void RegisterSignalHandler(
int signal,
4074 void (*handler)(
int signal),
4075 bool reset_handler) {
4076 struct sigaction sa;
4077 memset(&sa, 0,
sizeof(sa));
4078 sa.sa_handler = handler;
4083 sa.sa_flags = reset_handler ? SA_RESETHAND : 0;
4085 sigfillset(&sa.sa_mask);
4086 CHECK_EQ(sigaction(signal, &sa,
nullptr), 0);
4090 void DebugProcess(
const FunctionCallbackInfo<Value>& args) {
4091 Environment* env = Environment::GetCurrent(args);
4093 if (args.Length() != 1) {
4094 return env->ThrowError(
"Invalid number of arguments.");
4100 pid = args[0]->IntegerValue();
4101 r = kill(pid, SIGUSR1);
4103 return env->ThrowErrnoException(errno,
"kill");
4110 static int GetDebugSignalHandlerMappingName(DWORD pid,
wchar_t*
buf,
4112 return _snwprintf(buf, buf_len, L
"node-debug-handler-%u", pid);
4116 static void DebugProcess(
const FunctionCallbackInfo<Value>& args) {
4117 Environment* env = Environment::GetCurrent(args);
4118 Isolate* isolate = args.GetIsolate();
4120 HANDLE process =
nullptr;
4121 HANDLE thread =
nullptr;
4122 HANDLE mapping =
nullptr;
4123 wchar_t mapping_name[32];
4124 LPTHREAD_START_ROUTINE* handler =
nullptr;
4126 if (args.Length() != 1) {
4127 env->ThrowError(
"Invalid number of arguments.");
4131 pid = (DWORD) args[0]->IntegerValue();
4133 process = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION |
4134 PROCESS_VM_OPERATION | PROCESS_VM_WRITE |
4138 if (process ==
nullptr) {
4139 isolate->ThrowException(
4140 WinapiErrnoException(isolate, GetLastError(),
"OpenProcess"));
4144 if (GetDebugSignalHandlerMappingName(pid,
4146 arraysize(mapping_name)) < 0) {
4147 env->ThrowErrnoException(errno,
"sprintf");
4151 mapping = OpenFileMappingW(FILE_MAP_READ, FALSE, mapping_name);
4152 if (mapping ==
nullptr) {
4153 isolate->ThrowException(WinapiErrnoException(isolate,
4155 "OpenFileMappingW"));
4159 handler =
reinterpret_cast<LPTHREAD_START_ROUTINE*
>(
4160 MapViewOfFile(mapping,
4165 if (handler ==
nullptr || *handler ==
nullptr) {
4166 isolate->ThrowException(
4167 WinapiErrnoException(isolate, GetLastError(),
"MapViewOfFile"));
4171 thread = CreateRemoteThread(process,
4178 if (thread ==
nullptr) {
4179 isolate->ThrowException(WinapiErrnoException(isolate,
4181 "CreateRemoteThread"));
4186 if (WaitForSingleObject(thread, INFINITE) != WAIT_OBJECT_0) {
4187 isolate->ThrowException(WinapiErrnoException(isolate,
4189 "WaitForSingleObject"));
4194 if (process !=
nullptr)
4195 CloseHandle(process);
4196 if (thread !=
nullptr)
4197 CloseHandle(thread);
4198 if (handler !=
nullptr)
4199 UnmapViewOfFile(handler);
4200 if (mapping !=
nullptr)
4201 CloseHandle(mapping);
4206 static void DebugPause(
const FunctionCallbackInfo<Value>& args) {
4207 v8::Debug::DebugBreak(args.GetIsolate());
4211 static void DebugEnd(
const FunctionCallbackInfo<Value>& args) {
4213 Environment* env = Environment::GetCurrent(args);
4214 if (env->inspector_agent()->IsStarted()) {
4215 env->inspector_agent()->Stop();
4225 sigemptyset(&sigmask);
4226 sigaddset(&sigmask, SIGUSR1);
4227 const int err = pthread_sigmask(SIG_SETMASK, &sigmask,
nullptr);
4228 #endif // HAVE_INSPECTOR 4231 for (
int fd = STDIN_FILENO; fd <= STDERR_FILENO; fd += 1) {
4232 struct stat ignored;
4233 if (fstat(fd, &ignored) == 0)
4239 if (fd != open(
"/dev/null", O_RDWR))
4245 #endif // HAVE_INSPECTOR 4247 #ifndef NODE_SHARED_MODE 4249 struct sigaction act;
4250 memset(&act, 0,
sizeof(act));
4255 for (
unsigned nr = 1; nr < kMaxSignal; nr += 1) {
4256 if (nr == SIGKILL || nr == SIGSTOP)
4258 act.sa_handler = (nr == SIGPIPE) ? SIG_IGN : SIG_DFL;
4259 CHECK_EQ(0, sigaction(nr, &act,
nullptr));
4261 #endif // !NODE_SHARED_MODE 4263 RegisterSignalHandler(SIGINT,
SignalExit,
true);
4264 RegisterSignalHandler(SIGTERM,
SignalExit,
true);
4268 if (getrlimit(RLIMIT_NOFILE, &lim) == 0 && lim.rlim_cur != lim.rlim_max) {
4270 rlim_t min = lim.rlim_cur;
4271 rlim_t max = 1 << 20;
4273 if (lim.rlim_max != RLIM_INFINITY) {
4278 lim.rlim_cur = min + (max - min) / 2;
4279 if (setrlimit(RLIMIT_NOFILE, &lim)) {
4284 }
while (min + 1 < max);
4288 for (
int fd = 0; fd <= 2; ++fd) {
4289 auto handle =
reinterpret_cast<HANDLE
>(_get_osfhandle(fd));
4290 if (handle == INVALID_HANDLE_VALUE ||
4291 GetFileType(handle) == FILE_TYPE_UNKNOWN) {
4295 if (fd != _open(
"nul", _O_RDWR))
4306 const char*** exec_argv,
4307 bool is_env =
false) {
4310 const char** v8_argv;
4311 ParseArgs(argc, argv, exec_argc, exec_argv, &v8_argc, &v8_argv, is_env);
4317 for (
int i = 1; i < v8_argc; ++i) {
4318 if (strncmp(v8_argv[i],
"--prof",
sizeof(
"--prof") - 1) == 0) {
4319 v8_is_profiling =
true;
4328 if (v8_is_profiling) {
4329 uv_loop_configure(uv_default_loop(), UV_LOOP_BLOCK_SIGNAL, SIGPROF);
4336 V8::SetFlagsFromCommandLine(&v8_argc, const_cast<char**>(v8_argv),
true);
4339 for (
int i = 1; i < v8_argc; i++) {
4340 fprintf(stderr,
"%s: bad option: %s\n", argv[0], v8_argv[i]);
4354 const char*** exec_argv) {
4356 prog_start_time =
static_cast<double>(uv_now(uv_default_loop()));
4359 uv_disable_stdio_inheritance();
4361 #if defined(NODE_V8_OPTIONS) 4370 config_pending_deprecation =
4371 SafeGetenv(
"NODE_PENDING_DEPRECATION", &text) && text[0] ==
'1';
4377 config_preserve_symlinks =
4378 SafeGetenv(
"NODE_PRESERVE_SYMLINKS", &text) && text[0] ==
'1';
4381 if (config_warning_file.empty())
4382 SafeGetenv(
"NODE_REDIRECT_WARNINGS", &config_warning_file);
4385 if (openssl_config.empty())
4389 #if !defined(NODE_WITHOUT_NODE_OPTIONS) 4390 std::string node_options;
4391 if (
SafeGetenv(
"NODE_OPTIONS", &node_options)) {
4394 size_t max_len = 2 + (node_options.length() + 1) / 2;
4395 const char** argv_from_env =
new const char*[max_len];
4396 int argc_from_env = 0;
4398 argv_from_env[argc_from_env++] = argv[0];
4400 char* cstr = strdup(node_options.c_str());
4401 char* initptr = cstr;
4403 while ((token = strtok(initptr,
" "))) {
4405 argv_from_env[argc_from_env++] = token;
4407 argv_from_env[argc_from_env] =
nullptr;
4409 const char** exec_argv_ =
nullptr;
4410 ProcessArgv(&argc_from_env, argv_from_env, &exec_argc_, &exec_argv_,
true);
4411 delete[] exec_argv_;
4412 delete[] argv_from_env;
4419 #if defined(NODE_HAVE_I18N_SUPPORT) 4421 if (icu_data_dir.empty())
4425 if (!i18n::InitializeICUDirectory(icu_data_dir)) {
4427 "%s: could not initialize ICU " 4428 "(check NODE_ICU_DATA or --icu-data-dir parameters)\n",
4437 const char no_typed_array_heap[] =
"--typed_array_max_size_in_heap=0";
4443 node_is_initialized =
true;
4448 env->RunAtExitCallbacks();
4452 static uv_key_t thread_local_env;
4455 void AtExit(
void (*cb)(
void* arg),
void* arg) {
4456 auto env =
static_cast<Environment*
>(uv_key_get(&thread_local_env));
4461 void AtExit(Environment* env,
void (*cb)(
void* arg),
void* arg) {
4462 CHECK_NE(env,
nullptr);
4463 env->AtExit(cb, arg);
4468 HandleScope handle_scope(env->isolate());
4469 Context::Scope context_scope(env->context());
4470 Local<Object> process_object = env->process_object();
4471 Local<String> exit_code = FIXED_ONE_BYTE_STRING(env->isolate(),
"exitCode");
4472 Local<Value> args[] = {
4473 FIXED_ONE_BYTE_STRING(env->isolate(),
"beforeExit"),
4474 process_object->Get(exit_code)->ToInteger(env->isolate())
4477 process_object,
"emit", arraysize(args), args,
4478 {0, 0}).ToLocalChecked();
4484 HandleScope handle_scope(env->isolate());
4485 Context::Scope context_scope(env->context());
4486 Local<Object> process_object = env->process_object();
4487 process_object->Set(env->exiting_string(), True(env->isolate()));
4489 Local<String> exitCode = env->exit_code_string();
4490 int code = process_object->Get(exitCode)->Int32Value();
4492 Local<Value> args[] = {
4498 process_object,
"emit", arraysize(args), args,
4499 {0, 0}).ToLocalChecked();
4502 return process_object->Get(exitCode)->Int32Value();
4507 return new IsolateData(isolate, loop);
4512 delete isolate_data;
4517 Local<Context> context,
4519 const char*
const* argv,
4521 const char*
const* exec_argv) {
4522 Isolate* isolate = context->GetIsolate();
4523 HandleScope handle_scope(isolate);
4524 Context::Scope context_scope(context);
4525 auto env =
new Environment(isolate_data, context);
4526 env->Start(argc, argv, exec_argc, exec_argv, v8_is_profiling);
4536 inline int Start(Isolate* isolate, IsolateData* isolate_data,
4537 int argc,
const char*
const* argv,
4538 int exec_argc,
const char*
const* exec_argv) {
4539 HandleScope handle_scope(isolate);
4541 Context::Scope context_scope(context);
4542 Environment env(isolate_data, context);
4543 CHECK_EQ(0, uv_key_create(&thread_local_env));
4544 uv_key_set(&thread_local_env, &env);
4545 env.Start(argc, argv, exec_argc, exec_argv, v8_is_profiling);
4547 const char* path = argc > 1 ? argv[1] :
nullptr;
4548 StartInspector(&env, path, debug_options);
4553 env.set_abort_on_uncaught_exception(abort_on_uncaught_exception);
4556 Environment::AsyncCallbackScope callback_scope(&env);
4557 Environment::AsyncHooks::ExecScope exec_scope(&env, 1, 0);
4561 env.set_trace_sync_io(trace_sync_io);
4563 if (load_napi_modules) {
4565 "and could change at any time.");
4569 SealHandleScope seal(isolate);
4573 uv_run(env.event_loop(), UV_RUN_DEFAULT);
4577 v8_platform.DrainVMTasks();
4580 more = uv_loop_alive(env.event_loop());
4581 }
while (more ==
true);
4585 env.set_trace_sync_io(
false);
4587 const int exit_code =
EmitExit(&env);
4589 uv_key_delete(&thread_local_env);
4591 v8_platform.DrainVMTasks();
4592 WaitForInspectorDisconnect(&env);
4593 #if defined(LEAK_SANITIZER) 4594 __lsan_do_leak_check();
4601 int argc,
const char*
const* argv,
4602 int exec_argc,
const char*
const* exec_argv) {
4603 Isolate::CreateParams params;
4604 ArrayBufferAllocator allocator;
4605 params.array_buffer_allocator = &allocator;
4606 #ifdef NODE_ENABLE_VTUNE_PROFILING 4607 params.code_event_handler = vTune::GetVtuneCodeEventHandler();
4611 if (isolate ==
nullptr)
4614 isolate->AddMessageListener(OnMessage);
4615 isolate->SetAbortOnUncaughtExceptionCallback(ShouldAbortOnUncaughtException);
4616 isolate->SetAutorunMicrotasks(
false);
4617 isolate->SetFatalErrorHandler(OnFatalError);
4619 if (track_heap_objects) {
4620 isolate->GetHeapProfiler()->StartTrackingHeapObjects(
true);
4624 Mutex::ScopedLock scoped_lock(node_isolate_mutex);
4625 CHECK_EQ(node_isolate,
nullptr);
4626 node_isolate = isolate;
4631 Locker locker(isolate);
4632 Isolate::Scope isolate_scope(isolate);
4633 HandleScope handle_scope(isolate);
4634 IsolateData isolate_data(isolate, event_loop, allocator.zero_fill_field());
4635 exit_code =
Start(isolate, &isolate_data, argc, argv, exec_argc, exec_argv);
4639 Mutex::ScopedLock scoped_lock(node_isolate_mutex);
4640 CHECK_EQ(node_isolate, isolate);
4641 node_isolate =
nullptr;
4650 atexit([] () { uv_tty_reset_mode(); });
4657 argv = uv_setup_args(argc, argv);
4662 const char** exec_argv;
4663 Init(&argc, const_cast<const char**>(argv), &exec_argc, &exec_argv);
4667 std::string extra_ca_certs;
4668 if (
SafeGetenv(
"NODE_EXTRA_CA_CERTS", &extra_ca_certs))
4671 #ifdef NODE_FIPS_MODE 4675 #endif // NODE_FIPS_MODE 4679 #endif // HAVE_OPENSSL 4681 v8_platform.Initialize(v8_thread_pool_size, uv_default_loop());
4683 if (trace_enabled) {
4684 fprintf(stderr,
"Warning: Trace event is an experimental feature " 4685 "and could change at any time.\n");
4686 v8_platform.StartTracingAgent();
4690 v8_initialized =
true;
4691 const int exit_code =
4692 Start(uv_default_loop(), argc, argv, exec_argc, exec_argv);
4693 if (trace_enabled) {
4694 v8_platform.StopTracingAgent();
4696 v8_initialized =
false;
4705 v8_platform.Dispose();
4708 exec_argv =
nullptr;
4717 static void InitEmptyBindings() {}
4720 #endif // !HAVE_INSPECTOR void InitLTTNG(Environment *env, Local< Object > target)
void FreeEnvironment(Environment *env)
bool IsExceptionDecorated(Environment *env, Local< Value > er)
void EmitBeforeExit(Environment *env)
bool ParseOption(const char *argv0, const std::string &option)
void SetFlagsFromString(const FunctionCallbackInfo< Value > &args)
void GetActiveHandles(const FunctionCallbackInfo< Value > &args)
void AppendExceptionLine(Environment *env, Local< Value > er, Local< Message > message, enum ErrorHandlingMode mode)
#define READONLY_PROPERTY(obj, str, var)
void ClearFatalExceptionHandlers(Environment *env)
ssize_t DecodeWrite(Isolate *isolate, char *buf, size_t buflen, Local< Value > val, enum encoding encoding)
#define PERFORMANCE_MARK(env, n)
NODE_MODULE_CONTEXT_AWARE_BUILTIN(inspector, node::inspector::Agent::InitInspector)
bool inspector_enabled() const
struct node_module * nm_link
int EmitExit(Environment *env)
#define NODE_MODULE_VERSION
ssize_t DecodeBytes(Isolate *isolate, Local< Value > val, enum encoding encoding)
void ProcessEmitWarning(Environment *env, const char *fmt,...)
void FatalException(Isolate *isolate, Local< Value > error, Local< Message > message)
IsolateData * CreateIsolateData(Isolate *isolate, uv_loop_t *loop)
#define PERFORMANCE_NOW()
void DefineConstants(v8::Isolate *isolate, Local< Object > target)
void node_module_register(void *m)
void AtExit(void(*cb)(void *arg), void *arg)
NO_RETURN void FatalError(const char *location, const char *message)
void InitDTrace(Environment *env, Local< Object > target)
bool DomainEnter(Environment *env, Local< Object > object)
bool config_experimental_modules
void AddPromiseHook(v8::Isolate *isolate, promise_hook_func fn, void *arg)
void FreeIsolateData(IsolateData *isolate_data)
NO_RETURN void Assert(const char *const (*args)[4])
bool invalid_invocation() const
bool SafeGetenv(const char *key, std::string *text)
void UseExtraCaCerts(const std::string &file)
void SignalExit(int signo)
size_t Length(Local< Value > val)
Local< Value > ErrnoException(Isolate *isolate, int errorno, const char *syscall, const char *msg, const char *path)
node::DebugOptions debug_options
Environment * CreateEnvironment(IsolateData *isolate_data, Local< Context > context, int argc, const char *const *argv, int exec_argc, const char *const *exec_argv)
const char * signo_string(int signo)
node::addon_context_register_func nm_context_register_func
bool config_pending_deprecation
void Initialize(Local< Object > target, Local< Value > unused, Local< Context > context, void *priv)
std::string config_warning_file
Local< Value > Encode(Isolate *isolate, const uint16_t *buf, size_t len)
void ProcessArgv(int *argc, const char **argv, int *exec_argc, const char ***exec_argv, bool is_env=false)
struct node_module * get_linked_module(const char *name)
void InitPerfCounters(Environment *env, Local< Object > target)
enum encoding ParseEncoding(const char *encoding, enum encoding default_encoding)
::node::async_id trigger_async_id
bool config_preserve_symlinks
void DumpBacktrace(FILE *fp)
::node::async_id async_id
node::addon_register_func nm_register_func
#define READONLY_DONT_ENUM_PROPERTY(obj, str, var)
node::Environment::AsyncHooks AsyncHooks
MaybeLocal< Object > New(Isolate *isolate, Local< String > string, enum encoding enc)
bool wait_for_connect() const
void(* promise_hook_func)(v8::PromiseHookType type, v8::Local< v8::Promise > promise, v8::Local< v8::Value > parent, void *arg)
bool zero_fill_all_buffers
bool deprecated_invocation() const
MaybeLocal< Value > MakeCallback(Isolate *isolate, Local< Object > recv, Local< Function > callback, int argc, Local< Value > *argv, async_id asyncId, async_id triggerAsyncId)
void SetupProcessObject(Environment *env, int argc, const char *const *argv, int exec_argc, const char *const *exec_argv)
#define NODE_STRINGIFY(n)
node::Environment::AsyncHooks AsyncHooks
struct node_module * get_builtin_module(const char *name)
bool EntropySource(unsigned char *buffer, size_t length)
bool DomainExit(Environment *env, v8::Local< v8::Object > object)
int Start(Isolate *isolate, IsolateData *isolate_data, int argc, const char *const *argv, int exec_argc, const char *const *exec_argv)
void Init(int *argc, const char **argv, int *exec_argc, const char ***exec_argv)
bool config_expose_internals
NODE_DEPRECATED("Use ParseEncoding(isolate, ...)", inline enum encoding ParseEncoding(v8::Local< v8::Value > encoding_v, enum encoding default_encoding=LATIN1) { return ParseEncoding(v8::Isolate::GetCurrent(), encoding_v, default_encoding);}) NODE_EXTERN void FatalException(v8 NODE_DEPRECATED("Use FatalException(isolate, ...)", inline void FatalException(const v8::TryCatch &try_catch) { return FatalException(v8::Isolate::GetCurrent(), try_catch);}) NODE_EXTERN v8 NODE_EXTERN v8::Local< v8::Value > Encode(v8::Isolate *isolate, const uint16_t *buf, size_t len)
static void SetTracingController(v8::TracingController *controller)
Local< Value > UVException(Isolate *isolate, int errorno, const char *syscall, const char *msg, const char *path)
void RunAtExit(Environment *env)
void LoadEnvironment(Environment *env)