#include "node.h" #if (SCRIPT_ENGINE_TYPE == SCRIPT_ENGINE_V8) && SE_ENABLE_INSPECTOR #include "env.h" #include "http_parser.h" #include "util.h" #include #include #include #include #ifdef __POSIX__ #include #endif #define NODE_VERSION "JSB2.0" //cjh added static inline const char *errno_string(int errorno) { #define ERRNO_CASE(e) \ case e: return #e; switch (errorno) { #ifdef EACCES ERRNO_CASE(EACCES); #endif #ifdef EADDRINUSE ERRNO_CASE(EADDRINUSE); #endif #ifdef EADDRNOTAVAIL ERRNO_CASE(EADDRNOTAVAIL); #endif #ifdef EAFNOSUPPORT ERRNO_CASE(EAFNOSUPPORT); #endif #ifdef EAGAIN ERRNO_CASE(EAGAIN); #endif #ifdef EWOULDBLOCK #if EAGAIN != EWOULDBLOCK ERRNO_CASE(EWOULDBLOCK); #endif #endif #ifdef EALREADY ERRNO_CASE(EALREADY); #endif #ifdef EBADF ERRNO_CASE(EBADF); #endif #ifdef EBADMSG ERRNO_CASE(EBADMSG); #endif #ifdef EBUSY ERRNO_CASE(EBUSY); #endif #ifdef ECANCELED ERRNO_CASE(ECANCELED); #endif #ifdef ECHILD ERRNO_CASE(ECHILD); #endif #ifdef ECONNABORTED ERRNO_CASE(ECONNABORTED); #endif #ifdef ECONNREFUSED ERRNO_CASE(ECONNREFUSED); #endif #ifdef ECONNRESET ERRNO_CASE(ECONNRESET); #endif #ifdef EDEADLK ERRNO_CASE(EDEADLK); #endif #ifdef EDESTADDRREQ ERRNO_CASE(EDESTADDRREQ); #endif #ifdef EDOM ERRNO_CASE(EDOM); #endif #ifdef EDQUOT ERRNO_CASE(EDQUOT); #endif #ifdef EEXIST ERRNO_CASE(EEXIST); #endif #ifdef EFAULT ERRNO_CASE(EFAULT); #endif #ifdef EFBIG ERRNO_CASE(EFBIG); #endif #ifdef EHOSTUNREACH ERRNO_CASE(EHOSTUNREACH); #endif #ifdef EIDRM ERRNO_CASE(EIDRM); #endif #ifdef EILSEQ ERRNO_CASE(EILSEQ); #endif #ifdef EINPROGRESS ERRNO_CASE(EINPROGRESS); #endif #ifdef EINTR ERRNO_CASE(EINTR); #endif #ifdef EINVAL ERRNO_CASE(EINVAL); #endif #ifdef EIO ERRNO_CASE(EIO); #endif #ifdef EISCONN ERRNO_CASE(EISCONN); #endif #ifdef EISDIR ERRNO_CASE(EISDIR); #endif #ifdef ELOOP ERRNO_CASE(ELOOP); #endif #ifdef EMFILE ERRNO_CASE(EMFILE); #endif #ifdef EMLINK ERRNO_CASE(EMLINK); #endif #ifdef EMSGSIZE ERRNO_CASE(EMSGSIZE); #endif #ifdef EMULTIHOP ERRNO_CASE(EMULTIHOP); #endif #ifdef ENAMETOOLONG ERRNO_CASE(ENAMETOOLONG); #endif #ifdef ENETDOWN ERRNO_CASE(ENETDOWN); #endif #ifdef ENETRESET ERRNO_CASE(ENETRESET); #endif #ifdef ENETUNREACH ERRNO_CASE(ENETUNREACH); #endif #ifdef ENFILE ERRNO_CASE(ENFILE); #endif #ifdef ENOBUFS ERRNO_CASE(ENOBUFS); #endif #ifdef ENODATA ERRNO_CASE(ENODATA); #endif #ifdef ENODEV ERRNO_CASE(ENODEV); #endif #ifdef ENOENT ERRNO_CASE(ENOENT); #endif #ifdef ENOEXEC ERRNO_CASE(ENOEXEC); #endif #ifdef ENOLINK ERRNO_CASE(ENOLINK); #endif #ifdef ENOLCK #if ENOLINK != ENOLCK ERRNO_CASE(ENOLCK); #endif #endif #ifdef ENOMEM ERRNO_CASE(ENOMEM); #endif #ifdef ENOMSG ERRNO_CASE(ENOMSG); #endif #ifdef ENOPROTOOPT ERRNO_CASE(ENOPROTOOPT); #endif #ifdef ENOSPC ERRNO_CASE(ENOSPC); #endif #ifdef ENOSR ERRNO_CASE(ENOSR); #endif #ifdef ENOSTR ERRNO_CASE(ENOSTR); #endif #ifdef ENOSYS ERRNO_CASE(ENOSYS); #endif #ifdef ENOTCONN ERRNO_CASE(ENOTCONN); #endif #ifdef ENOTDIR ERRNO_CASE(ENOTDIR); #endif #ifdef ENOTEMPTY #if ENOTEMPTY != EEXIST ERRNO_CASE(ENOTEMPTY); #endif #endif #ifdef ENOTSOCK ERRNO_CASE(ENOTSOCK); #endif #ifdef ENOTSUP ERRNO_CASE(ENOTSUP); #else #ifdef EOPNOTSUPP ERRNO_CASE(EOPNOTSUPP); #endif #endif #ifdef ENOTTY ERRNO_CASE(ENOTTY); #endif #ifdef ENXIO ERRNO_CASE(ENXIO); #endif #ifdef EOVERFLOW ERRNO_CASE(EOVERFLOW); #endif #ifdef EPERM ERRNO_CASE(EPERM); #endif #ifdef EPIPE ERRNO_CASE(EPIPE); #endif #ifdef EPROTO ERRNO_CASE(EPROTO); #endif #ifdef EPROTONOSUPPORT ERRNO_CASE(EPROTONOSUPPORT); #endif #ifdef EPROTOTYPE ERRNO_CASE(EPROTOTYPE); #endif #ifdef ERANGE ERRNO_CASE(ERANGE); #endif #ifdef EROFS ERRNO_CASE(EROFS); #endif #ifdef ESPIPE ERRNO_CASE(ESPIPE); #endif #ifdef ESRCH ERRNO_CASE(ESRCH); #endif #ifdef ESTALE ERRNO_CASE(ESTALE); #endif #ifdef ETIME ERRNO_CASE(ETIME); #endif #ifdef ETIMEDOUT ERRNO_CASE(ETIMEDOUT); #endif #ifdef ETXTBSY ERRNO_CASE(ETXTBSY); #endif #ifdef EXDEV ERRNO_CASE(EXDEV); #endif default: return ""; } } #ifdef __POSIX__ void RegisterSignalHandler(int signal, void (*handler)(int signal), bool reset_handler) { struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_handler = handler; #ifndef __FreeBSD__ // FreeBSD has a nasty bug with SA_RESETHAND reseting the SA_SIGINFO, that is // in turn set for a libthr wrapper. This leads to a crash. // Work around the issue by manually setting SIG_DFL in the signal handler sa.sa_flags = reset_handler ? SA_RESETHAND : 0; #endif sigfillset(&sa.sa_mask); CHECK_EQ(sigaction(signal, &sa, nullptr), 0); } #endif // __POSIX__ using namespace v8; namespace node { static bool v8_is_profiling = false; Local ErrnoException(Isolate *isolate, int errorno, const char *syscall, const char *msg, const char *path) { Environment *env = Environment::GetCurrent(isolate); Local e; Local estring = OneByteString(env->isolate(), errno_string(errorno)); if (msg == nullptr || msg[0] == '\0') { msg = strerror(errorno); } Local message = OneByteString(env->isolate(), msg); Local cons = String::Concat(env->isolate(), estring, FIXED_ONE_BYTE_STRING(env->isolate(), ", ")); cons = String::Concat(env->isolate(), cons, message); Local path_string; if (path != nullptr) { // IDEA(bnoordhuis) It's questionable to interpret the file path as UTF-8. path_string = String::NewFromUtf8(env->isolate(), path, v8::NewStringType::kNormal).ToLocalChecked(); } if (path_string.IsEmpty() == false) { cons = String::Concat(env->isolate(), cons, FIXED_ONE_BYTE_STRING(env->isolate(), " '")); cons = String::Concat(env->isolate(), cons, path_string); cons = String::Concat(env->isolate(), cons, FIXED_ONE_BYTE_STRING(env->isolate(), "'")); } e = Exception::Error(cons); Local obj = e->ToObject(env->context()).ToLocalChecked(); obj->Set(env->context(), env->errno_string(), Integer::New(env->isolate(), errorno)).Check(); obj->Set(env->context(), env->code_string(), estring).Check(); if (path_string.IsEmpty() == false) { obj->Set(env->context(), env->path_string(), path_string).Check(); } if (syscall != nullptr) { obj->Set(env->context(), env->syscall_string(), OneByteString(env->isolate(), syscall)).Check(); } return e; } static Local StringFromPath(Isolate *isolate, const char *path) { #ifdef _WIN32 if (strncmp(path, "\\\\?\\UNC\\", 8) == 0) { return String::Concat(isolate, FIXED_ONE_BYTE_STRING(isolate, "\\\\"), String::NewFromUtf8(isolate, path + 8).ToLocalChecked()); } else if (strncmp(path, "\\\\?\\", 4) == 0) { return String::NewFromUtf8(isolate, path + 4).ToLocalChecked(); } #endif return String::NewFromUtf8(isolate, path, v8::NewStringType::kNormal).ToLocalChecked(); } Local UVException(Isolate *isolate, int errorno, const char *syscall, const char *msg, const char *path) { return UVException(isolate, errorno, syscall, msg, path, nullptr); } Local UVException(Isolate *isolate, int errorno, const char *syscall, const char *msg, const char *path, const char *dest) { Environment *env = Environment::GetCurrent(isolate); if (!msg || !msg[0]) msg = uv_strerror(errorno); Local js_code = OneByteString(isolate, uv_err_name(errorno)); Local js_syscall = OneByteString(isolate, syscall); Local js_path; Local js_dest; Local js_msg = js_code; js_msg = String::Concat(isolate, js_msg, FIXED_ONE_BYTE_STRING(isolate, ": ")); js_msg = String::Concat(isolate, js_msg, OneByteString(isolate, msg)); js_msg = String::Concat(isolate, js_msg, FIXED_ONE_BYTE_STRING(isolate, ", ")); js_msg = String::Concat(isolate, js_msg, js_syscall); if (path != nullptr) { js_path = StringFromPath(isolate, path); js_msg = String::Concat(isolate, js_msg, FIXED_ONE_BYTE_STRING(isolate, " '")); js_msg = String::Concat(isolate, js_msg, js_path); js_msg = String::Concat(isolate, js_msg, FIXED_ONE_BYTE_STRING(isolate, "'")); } if (dest != nullptr) { js_dest = StringFromPath(isolate, dest); js_msg = String::Concat(isolate, js_msg, FIXED_ONE_BYTE_STRING(isolate, " -> '")); js_msg = String::Concat(isolate, js_msg, js_dest); js_msg = String::Concat(isolate, js_msg, FIXED_ONE_BYTE_STRING(isolate, "'")); } Local e = Exception::Error(js_msg)->ToObject(isolate->GetCurrentContext()).ToLocalChecked(); e->Set(isolate->GetCurrentContext(), env->errno_string(), Integer::New(isolate, errorno)).Check(); e->Set(isolate->GetCurrentContext(), env->code_string(), js_code).Check(); e->Set(isolate->GetCurrentContext(), env->syscall_string(), js_syscall).Check(); if (!js_path.IsEmpty()) e->Set(isolate->GetCurrentContext(), env->path_string(), js_path).Check(); if (!js_dest.IsEmpty()) e->Set(isolate->GetCurrentContext(), env->dest_string(), js_dest).Check(); return e; } MaybeLocal MakeCallback(Environment *env, Local recv, const Local callback, int argc, Local argv[], async_context asyncContext) { // If you hit this assertion, you forgot to enter the v8::Context first. CHECK_EQ(env->context(), env->isolate()->GetCurrentContext()); Local object; // Environment::AsyncCallbackScope callback_scope(env); // bool disposed_domain = false; // // if (recv->IsObject()) { // object = recv.As(); // } // // if (env->using_domains()) { // CHECK(recv->IsObject()); // disposed_domain = DomainEnter(env, object); // if (disposed_domain) return Undefined(env->isolate()); // } MaybeLocal ret; // { // AsyncHooks::ExecScope exec_scope(env, asyncContext.async_id, // asyncContext.trigger_async_id); // // if (asyncContext.async_id != 0) { // if (!AsyncWrap::EmitBefore(env, asyncContext.async_id)) // return Local(); // } // // ret = callback->Call(env->context(), recv, argc, argv); // // if (ret.IsEmpty()) { // // NOTE: For backwards compatibility with public API we return Undefined() // // if the top level call threw. // return callback_scope.in_makecallback() ? // ret : Undefined(env->isolate()); // } // // if (asyncContext.async_id != 0) { // if (!AsyncWrap::EmitAfter(env, asyncContext.async_id)) // return Local(); // } // } // // if (env->using_domains()) { // disposed_domain = DomainExit(env, object); // if (disposed_domain) return Undefined(env->isolate()); // } // // if (callback_scope.in_makecallback()) { // return ret; // } // // Environment::TickInfo* tick_info = env->tick_info(); // // if (tick_info->length() == 0) { // env->isolate()->RunMicrotasks(); // } // // // Make sure the stack unwound properly. If there are nested MakeCallback's // // then it should return early and not reach this code. // CHECK_EQ(env->current_async_id(), asyncContext.async_id); // CHECK_EQ(env->trigger_id(), asyncContext.trigger_async_id); // // Local process = env->process_object(); // // if (tick_info->length() == 0) { // tick_info->set_index(0); // return ret; // } // // if (env->tick_callback_function()->Call(process, 0, nullptr).IsEmpty()) { // return Undefined(env->isolate()); // } return ret; } // Public MakeCallback()s MaybeLocal MakeCallback(Isolate *isolate, Local recv, const char *method, int argc, Local argv[], async_context asyncContext) { Local method_string = String::NewFromUtf8(isolate, method, v8::NewStringType::kNormal) .ToLocalChecked(); return MakeCallback(isolate, recv, method_string, argc, argv, asyncContext); } MaybeLocal MakeCallback(Isolate *isolate, Local recv, Local symbol, int argc, Local argv[], async_context asyncContext) { Local callback_v = recv->Get(isolate->GetCurrentContext(), symbol).ToLocalChecked(); if (callback_v.IsEmpty()) return Local(); if (!callback_v->IsFunction()) return Local(); Local callback = callback_v.As(); return MakeCallback(isolate, recv, callback, argc, argv, asyncContext); } MaybeLocal MakeCallback(Isolate *isolate, Local recv, Local callback, int argc, Local argv[], async_context asyncContext) { // Observe the following two subtleties: // // 1. The environment is retrieved from the callback function's context. // 2. The context to enter is retrieved from the environment. // // Because of the AssignToContext() call in src/node_contextify.cc, // the two contexts need not be the same. Environment *env = Environment::GetCurrent(callback->GetCreationContext().ToLocalChecked()); Context::Scope context_scope(env->context()); return MakeCallback(env, recv.As(), callback, argc, argv, asyncContext); } // Legacy MakeCallback()s Local MakeCallback(Isolate *isolate, Local recv, const char *method, int argc, Local *argv) { EscapableHandleScope handle_scope(isolate); return handle_scope.Escape( MakeCallback(isolate, recv, method, argc, argv, {0, 0}) .FromMaybe(Local())); } Local MakeCallback(Isolate *isolate, Local recv, Local symbol, int argc, Local *argv) { EscapableHandleScope handle_scope(isolate); return handle_scope.Escape( MakeCallback(isolate, recv, symbol, argc, argv, {0, 0}) .FromMaybe(Local())); } Local MakeCallback(Isolate *isolate, Local recv, Local callback, int argc, Local *argv) { EscapableHandleScope handle_scope(isolate); return handle_scope.Escape( MakeCallback(isolate, recv, callback, argc, argv, {0, 0}) .FromMaybe(Local())); } IsolateData *CreateIsolateData(Isolate *isolate, uv_loop_t *loop) { return new IsolateData(isolate, loop); } void FreeIsolateData(IsolateData *isolate_data) { delete isolate_data; } Environment *CreateEnvironment(IsolateData *isolate_data, Local context, int argc, const char *const *argv, int exec_argc, const char *const *exec_argv) { Isolate *isolate = context->GetIsolate(); HandleScope handle_scope(isolate); Context::Scope context_scope(context); auto env = new Environment(isolate_data, context); env->Start(argc, argv, exec_argc, exec_argv, v8_is_profiling); return env; } void FreeEnvironment(Environment *env) { delete env; } NO_RETURN void Abort() { DumpBacktrace(stderr); fflush(stderr); ABORT_NO_BACKTRACE(); } NO_RETURN void Assert(const char *const (*args)[4]) { auto filename = (*args)[0]; auto linenum = (*args)[1]; auto message = (*args)[2]; auto function = (*args)[3]; char exepath[256]; size_t exepath_size = sizeof(exepath); if (uv_exepath(exepath, &exepath_size)) snprintf(exepath, sizeof(exepath), "node"); char pid[12] = {0}; #ifndef _WIN32 snprintf(pid, sizeof(pid), "[%u]", getpid()); #endif SE_LOGE("%s%s: %s:%s:%s%s Assertion `%s' failed.\n", exepath, pid, filename, linenum, function, *function ? ":" : "", message); Abort(); } static void Abort(const FunctionCallbackInfo &args) { Abort(); } #define READONLY_PROPERTY(obj, str, var) \ do { \ obj->DefineOwnProperty(env->context(), \ OneByteString(env->isolate(), str), \ var, \ v8::ReadOnly) \ .FromJust(); \ } while (0) #define READONLY_DONT_ENUM_PROPERTY(obj, str, var) \ do { \ obj->DefineOwnProperty(env->context(), \ OneByteString(env->isolate(), str), \ var, \ static_cast(v8::ReadOnly | \ v8::DontEnum)) \ .FromJust(); \ } while (0) static void ProcessTitleGetter(Local property, const PropertyCallbackInfo &info) { char buffer[512]; uv_get_process_title(buffer, sizeof(buffer)); info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), buffer, v8::NewStringType::kNormal).ToLocalChecked()); } static void ProcessTitleSetter(Local property, Local value, const PropertyCallbackInfo &info) { node::Utf8Value title(info.GetIsolate(), value); // REFINE(piscisaureus): protect with a lock uv_set_process_title(*title); } void SetupProcessObject(Environment *env, int argc, const char *const *argv, int exec_argc, const char *const *exec_argv) { HandleScope scope(env->isolate()); Local process = env->process_object(); auto title_string = FIXED_ONE_BYTE_STRING(env->isolate(), "title"); CHECK(process->SetAccessor(env->context(), title_string, ProcessTitleGetter, ProcessTitleSetter, env->as_external()) .FromJust()); // process.version READONLY_PROPERTY(process, "version", FIXED_ONE_BYTE_STRING(env->isolate(), NODE_VERSION)); // process.moduleLoadList READONLY_PROPERTY(process, "moduleLoadList", env->module_load_list_array()); // process.versions Local versions = Object::New(env->isolate()); READONLY_PROPERTY(process, "versions", versions); const char http_parser_version[] = NODE_STRINGIFY(HTTP_PARSER_VERSION_MAJOR) "." NODE_STRINGIFY(HTTP_PARSER_VERSION_MINOR) "." NODE_STRINGIFY(HTTP_PARSER_VERSION_PATCH); READONLY_PROPERTY(versions, "http_parser", FIXED_ONE_BYTE_STRING(env->isolate(), http_parser_version)); // +1 to get rid of the leading 'v' READONLY_PROPERTY(versions, "node", OneByteString(env->isolate(), NODE_VERSION)); READONLY_PROPERTY(versions, "v8", OneByteString(env->isolate(), V8::GetVersion())); READONLY_PROPERTY(versions, "uv", OneByteString(env->isolate(), uv_version_string())); SE_LOGD("libuv version: %s\n", uv_version_string()); // READONLY_PROPERTY(versions, // "zlib", // FIXED_ONE_BYTE_STRING(env->isolate(), ZLIB_VERSION)); // READONLY_PROPERTY(versions, // "ares", // FIXED_ONE_BYTE_STRING(env->isolate(), ARES_VERSION_STR)); // const char node_modules_version[] = NODE_STRINGIFY(NODE_MODULE_VERSION); // READONLY_PROPERTY( // versions, // "modules", // FIXED_ONE_BYTE_STRING(env->isolate(), node_modules_version)); // process._promiseRejectEvent Local promiseRejectEvent = Object::New(env->isolate()); READONLY_DONT_ENUM_PROPERTY(process, "_promiseRejectEvent", promiseRejectEvent); READONLY_PROPERTY(promiseRejectEvent, "unhandled", Integer::New(env->isolate(), v8::kPromiseRejectWithNoHandler)); READONLY_PROPERTY(promiseRejectEvent, "handled", Integer::New(env->isolate(), v8::kPromiseHandlerAddedAfterReject)); //#if HAVE_OPENSSL // // Stupid code to slice out the version string. // { // NOLINT(whitespace/braces) // size_t i, j, k; // int c; // for (i = j = 0, k = sizeof(OPENSSL_VERSION_TEXT) - 1; i < k; ++i) { // c = OPENSSL_VERSION_TEXT[i]; // if ('0' <= c && c <= '9') { // for (j = i + 1; j < k; ++j) { // c = OPENSSL_VERSION_TEXT[j]; // if (c == ' ') // break; // } // break; // } // } // READONLY_PROPERTY( // versions, // "openssl", // OneByteString(env->isolate(), &OPENSSL_VERSION_TEXT[i], j - i)); // } //#endif // process.arch READONLY_PROPERTY(process, "arch", OneByteString(env->isolate(), "x64")); //IDEA: cjh // process.platform READONLY_PROPERTY(process, "platform", OneByteString(env->isolate(), "macOS")); //IDEA: cjh // process.release Local release = Object::New(env->isolate()); READONLY_PROPERTY(process, "release", release); READONLY_PROPERTY(release, "name", OneByteString(env->isolate(), "node")); // if this is a release build and no explicit base has been set // substitute the standard release download URL #ifndef NODE_RELEASE_URLBASE #if NODE_VERSION_IS_RELEASE #define NODE_RELEASE_URLBASE "https://nodejs.org/download/release/" #endif #endif #if defined(NODE_RELEASE_URLBASE) #define NODE_RELEASE_URLPFX NODE_RELEASE_URLBASE "v" NODE_VERSION_STRING "/" #define NODE_RELEASE_URLFPFX NODE_RELEASE_URLPFX "node-v" NODE_VERSION_STRING READONLY_PROPERTY(release, "sourceUrl", OneByteString(env->isolate(), NODE_RELEASE_URLFPFX ".tar.gz")); READONLY_PROPERTY(release, "headersUrl", OneByteString(env->isolate(), NODE_RELEASE_URLFPFX "-headers.tar.gz")); #ifdef _WIN32 READONLY_PROPERTY(release, "libUrl", OneByteString(env->isolate(), strcmp(NODE_ARCH, "ia32") ? NODE_RELEASE_URLPFX "win-" NODE_ARCH "/node.lib" : NODE_RELEASE_URLPFX "win-x86/node.lib")); #endif #endif // process.argv Local arguments = Array::New(env->isolate(), argc); for (int i = 0; i < argc; ++i) { arguments->Set(env->context(), i, String::NewFromUtf8(env->isolate(), argv[i], v8::NewStringType::kNormal).ToLocalChecked()).Check(); } process->Set(env->context(), FIXED_ONE_BYTE_STRING(env->isolate(), "argv"), arguments).Check(); // process.execArgv Local exec_arguments = Array::New(env->isolate(), exec_argc); for (int i = 0; i < exec_argc; ++i) { exec_arguments->Set(env->context(), i, String::NewFromUtf8(env->isolate(), exec_argv[i], v8::NewStringType::kNormal).ToLocalChecked()).Check(); } process->Set(env->context(), FIXED_ONE_BYTE_STRING(env->isolate(), "execArgv"), exec_arguments) .Check(); // create process.env // Local process_env_template = // ObjectTemplate::New(env->isolate()); // process_env_template->SetHandler(NamedPropertyHandlerConfiguration( // EnvGetter, // EnvSetter, // EnvQuery, // EnvDeleter, // EnvEnumerator, // env->as_external())); // // Local process_env = // process_env_template->NewInstance(env->context()).ToLocalChecked(); // process->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "env"), process_env); // // READONLY_PROPERTY(process, "pid", Integer::New(env->isolate(), getpid())); // READONLY_PROPERTY(process, "features", GetFeatures(env)); // // auto need_immediate_callback_string = // FIXED_ONE_BYTE_STRING(env->isolate(), "_needImmediateCallback"); // CHECK(process->SetAccessor(env->context(), need_immediate_callback_string, // NeedImmediateCallbackGetter, // NeedImmediateCallbackSetter, // env->as_external()).FromJust()); // // // -e, --eval // if (eval_string) { // READONLY_PROPERTY(process, // "_eval", // String::NewFromUtf8(env->isolate(), eval_string)); // } // // // -p, --print // if (print_eval) { // READONLY_PROPERTY(process, "_print_eval", True(env->isolate())); // } // // // -c, --check // if (syntax_check_only) { // READONLY_PROPERTY(process, "_syntax_check_only", True(env->isolate())); // } // // // -i, --interactive // if (force_repl) { // READONLY_PROPERTY(process, "_forceRepl", True(env->isolate())); // } // // -r, --require // if (!preload_modules.empty()) { // Local array = Array::New(env->isolate()); // for (unsigned int i = 0; i < preload_modules.size(); ++i) { // Local module = String::NewFromUtf8(env->isolate(), // preload_modules[i].c_str()); // array->Set(i, module); // } // READONLY_PROPERTY(process, // "_preload_modules", // array); // // preload_modules.clear(); // } // // // --no-deprecation // if (no_deprecation) { // READONLY_PROPERTY(process, "noDeprecation", True(env->isolate())); // } // // // --no-warnings // if (no_process_warnings) { // READONLY_PROPERTY(process, "noProcessWarnings", True(env->isolate())); // } // // // --trace-warnings // if (trace_warnings) { // READONLY_PROPERTY(process, "traceProcessWarnings", True(env->isolate())); // } // // // --throw-deprecation // if (throw_deprecation) { // READONLY_PROPERTY(process, "throwDeprecation", True(env->isolate())); // } // //#ifdef NODE_NO_BROWSER_GLOBALS // // configure --no-browser-globals // READONLY_PROPERTY(process, "_noBrowserGlobals", True(env->isolate())); //#endif // NODE_NO_BROWSER_GLOBALS // // // --prof-process // if (prof_process) { // READONLY_PROPERTY(process, "profProcess", True(env->isolate())); // } // // // --trace-deprecation // if (trace_deprecation) { // READONLY_PROPERTY(process, "traceDeprecation", True(env->isolate())); // } // // // REFINE(refack): move the following 3 to `node_config` // // --inspect-brk // if (debug_options.wait_for_connect()) { // READONLY_DONT_ENUM_PROPERTY(process, // "_breakFirstLine", True(env->isolate())); // } // // // --inspect --debug-brk // if (debug_options.deprecated_invocation()) { // READONLY_DONT_ENUM_PROPERTY(process, // "_deprecatedDebugBrk", True(env->isolate())); // } // // // --debug or, --debug-brk without --inspect // if (debug_options.invalid_invocation()) { // READONLY_DONT_ENUM_PROPERTY(process, // "_invalidDebug", True(env->isolate())); // } // // // --security-revert flags //#define V(code, _, __) \ //do { \ //if (IsReverted(REVERT_ ## code)) { \ //READONLY_PROPERTY(process, "REVERT_" #code, True(env->isolate())); \ //} \ //} while (0); // REVERSIONS(V) //#undef V // // size_t exec_path_len = 2 * PATH_MAX; // char* exec_path = new char[exec_path_len]; // Local exec_path_value; // if (uv_exepath(exec_path, &exec_path_len) == 0) { // exec_path_value = String::NewFromUtf8(env->isolate(), // exec_path, // String::kNormalString, // exec_path_len); // } else { // exec_path_value = String::NewFromUtf8(env->isolate(), argv[0]); // } // process->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "execPath"), // exec_path_value); // delete[] exec_path; // // auto debug_port_string = FIXED_ONE_BYTE_STRING(env->isolate(), "debugPort"); // CHECK(process->SetAccessor(env->context(), // debug_port_string, // DebugPortGetter, // DebugPortSetter, // env->as_external()).FromJust()); // // // define various internal methods // env->SetMethod(process, // "_startProfilerIdleNotifier", // StartProfilerIdleNotifier); // env->SetMethod(process, // "_stopProfilerIdleNotifier", // StopProfilerIdleNotifier); // env->SetMethod(process, "_getActiveRequests", GetActiveRequests); // env->SetMethod(process, "_getActiveHandles", GetActiveHandles); // env->SetMethod(process, "reallyExit", Exit); // env->SetMethod(process, "abort", Abort); // env->SetMethod(process, "chdir", Chdir); // env->SetMethod(process, "cwd", Cwd); // // env->SetMethod(process, "umask", Umask); // //#if defined(__POSIX__) && !defined(__ANDROID__) // env->SetMethod(process, "getuid", GetUid); // env->SetMethod(process, "geteuid", GetEUid); // env->SetMethod(process, "setuid", SetUid); // env->SetMethod(process, "seteuid", SetEUid); // // env->SetMethod(process, "setgid", SetGid); // env->SetMethod(process, "setegid", SetEGid); // env->SetMethod(process, "getgid", GetGid); // env->SetMethod(process, "getegid", GetEGid); // // env->SetMethod(process, "getgroups", GetGroups); // env->SetMethod(process, "setgroups", SetGroups); // env->SetMethod(process, "initgroups", InitGroups); //#endif // __POSIX__ && !defined(__ANDROID__) // // env->SetMethod(process, "_kill", Kill); // // env->SetMethod(process, "_debugProcess", DebugProcess); // env->SetMethod(process, "_debugPause", DebugPause); // env->SetMethod(process, "_debugEnd", DebugEnd); // // env->SetMethod(process, "hrtime", Hrtime); // // env->SetMethod(process, "cpuUsage", CPUUsage); // // env->SetMethod(process, "dlopen", DLOpen); // // env->SetMethod(process, "uptime", Uptime); // env->SetMethod(process, "memoryUsage", MemoryUsage); // // env->SetMethod(process, "binding", Binding); // env->SetMethod(process, "_linkedBinding", LinkedBinding); // // env->SetMethod(process, "_setupProcessObject", SetupProcessObject); // env->SetMethod(process, "_setupNextTick", SetupNextTick); // env->SetMethod(process, "_setupPromises", SetupPromises); // env->SetMethod(process, "_setupDomainUse", SetupDomainUse); // pre-set _events object for faster emit checks Local events_obj = Object::New(env->isolate()); CHECK(events_obj->SetPrototype(env->context(), Null(env->isolate())) .FromJust()); process->Set(env->context(), env->events_string(), events_obj).Check(); } #undef READONLY_PROPERTY } // namespace node #endif // #if (SCRIPT_ENGINE_TYPE == SCRIPT_ENGINE_V8) && SE_ENABLE_INSPECTOR