diff --git a/deps/uv/include/uv.h b/deps/uv/include/uv.h index 55f75218b58..754e27f4f8e 100644 --- a/deps/uv/include/uv.h +++ b/deps/uv/include/uv.h @@ -1418,6 +1418,8 @@ union uv_any_req { struct uv_loop_s { /* User data - use this for whatever. */ void* data; + /* Callback when loop's watcher queue updates. */ + void (*on_watcher_queue_updated)(uv_loop_t*); /* Loop reference counting. */ unsigned int active_handles; void* handle_queue[2]; diff --git a/deps/uv/src/unix/core.c b/deps/uv/src/unix/core.c index 6f284ffa7ae..e3fc31e1fd8 100644 --- a/deps/uv/src/unix/core.c +++ b/deps/uv/src/unix/core.c @@ -800,8 +800,11 @@ void uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events) { } #endif - if (QUEUE_EMPTY(&w->watcher_queue)) + if (QUEUE_EMPTY(&w->watcher_queue)) { QUEUE_INSERT_TAIL(&loop->watcher_queue, &w->watcher_queue); + if (loop->on_watcher_queue_updated) + loop->on_watcher_queue_updated(loop); + } if (loop->watchers[w->fd] == NULL) { loop->watchers[w->fd] = w; @@ -837,8 +840,11 @@ void uv__io_stop(uv_loop_t* loop, uv__io_t* w, unsigned int events) { w->events = 0; } } - else if (QUEUE_EMPTY(&w->watcher_queue)) + else if (QUEUE_EMPTY(&w->watcher_queue)) { QUEUE_INSERT_TAIL(&loop->watcher_queue, &w->watcher_queue); + if (loop->on_watcher_queue_updated) + loop->on_watcher_queue_updated(loop); + } } @@ -854,6 +860,8 @@ void uv__io_close(uv_loop_t* loop, uv__io_t* w) { void uv__io_feed(uv_loop_t* loop, uv__io_t* w) { if (QUEUE_EMPTY(&w->pending_queue)) QUEUE_INSERT_TAIL(&loop->pending_queue, &w->pending_queue); + if (loop->on_watcher_queue_updated) + loop->on_watcher_queue_updated(loop); } diff --git a/deps/uv/src/win/handle.c b/deps/uv/src/win/handle.c index 72b49d97904..81b7b62a7dc 100644 --- a/deps/uv/src/win/handle.c +++ b/deps/uv/src/win/handle.c @@ -53,7 +53,11 @@ uv_handle_type uv_guess_handle(uv_file file) { return UV_FILE; default: +#if defined(_WIN32) + return UV_FILE; +#else return UV_UNKNOWN_HANDLE; +#endif } } diff --git a/deps/uv/src/win/process.c b/deps/uv/src/win/process.c index 3a0106f82d6..9fff14f8b82 100644 --- a/deps/uv/src/win/process.c +++ b/deps/uv/src/win/process.c @@ -1075,6 +1075,9 @@ int uv_spawn(uv_loop_t* loop, process_flags |= DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP; } + /* Don't create console window. */ + process_flags |= CREATE_NO_WINDOW; + if (!CreateProcessW(application_path, arguments, NULL, diff --git a/lib/child_process.js b/lib/child_process.js index a38de2867db..d05269f4926 100644 --- a/lib/child_process.js +++ b/lib/child_process.js @@ -556,6 +556,19 @@ exports.fork = function(modulePath /*, args, options*/) { options.stdio = options.silent ? ['pipe', 'pipe', 'pipe', 'ipc'] : [0, 1, 2, 'ipc']; + // When forking a child script, we setup a special environment to make + // the atom-shell binary run like the upstream node. + if (!options.env) { + options.env = Object.create(process.env); + } + options.env['ATOM_SHELL_INTERNAL_RUN_AS_NODE'] = 1; + + // On Mac we use the helper app as node binary. + if (!options.execPath && process.type && process.platform == 'darwin') { + options.execPath = require('path').resolve(process.resourcesPath, '..', + 'Frameworks', 'Atom Helper.app', 'Contents', 'MacOS', 'Atom Helper'); + } + options.execPath = options.execPath || process.execPath; return spawn(options.execPath, args, options); diff --git a/lib/fs.js b/lib/fs.js index 472d03cc754..019ed39813a 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -838,11 +838,21 @@ fs.lstatSync = function(path) { return binding.lstat(pathModule._makeLong(path)); }; +fs.lstatSyncNoException = function(path) { + nullCheck(path); + return binding.lstatNoException(pathModule._makeLong(path)); +}; + fs.statSync = function(path) { nullCheck(path); return binding.stat(pathModule._makeLong(path)); }; +fs.statSyncNoException = function(path) { + nullCheck(path); + return binding.statNoException(pathModule._makeLong(path)); +}; + fs.readlink = function(path, callback) { callback = makeCallback(callback); if (!nullCheck(path, callback)) return; diff --git a/lib/module.js b/lib/module.js index 719f8bd50c5..c04778b1146 100644 --- a/lib/module.js +++ b/lib/module.js @@ -57,10 +57,15 @@ const debug = Module._debug; // -> a/index. function statPath(path) { + var fs = NativeModule.require('fs'); + /* try { return fs.statSync(path); } catch (ex) {} return false; + */ + var result = fs.statSyncNoException(path); + return result === false ? false : result; } // check if the directory is a package.json dir @@ -71,8 +76,11 @@ function readPackage(requestPath) { return packageMainCache[requestPath]; } + var fs = NativeModule.require('fs'); + var jsonPath = path.resolve(requestPath, 'package.json'); + if (fs.statSyncNoException(jsonPath) === false) // check existence. + return false; try { - var jsonPath = path.resolve(requestPath, 'package.json'); var json = fs.readFileSync(jsonPath, 'utf8'); } catch (e) { return false; @@ -454,30 +462,12 @@ Module.runMain = function() { }; Module._initPaths = function() { - const isWindows = process.platform === 'win32'; - - if (isWindows) { - var homeDir = process.env.USERPROFILE; - } else { - var homeDir = process.env.HOME; - } - var paths = [path.resolve(process.execPath, '..', '..', 'lib', 'node')]; - if (homeDir) { - paths.unshift(path.resolve(homeDir, '.node_libraries')); - paths.unshift(path.resolve(homeDir, '.node_modules')); - } - - var nodePath = process.env['NODE_PATH']; - if (nodePath) { - paths = nodePath.split(path.delimiter).concat(paths); - } - modulePaths = paths; // clone as a read-only copy, for introspection. - Module.globalPaths = modulePaths.slice(0); + Module.globalPaths = modulePaths; }; // bootstrap repl diff --git a/node.gyp b/node.gyp index dab7f6b28f1..bbd77e066dc 100644 --- a/node.gyp +++ b/node.gyp @@ -76,8 +76,8 @@ 'targets': [ { - 'target_name': 'iojs', - 'type': 'executable', + 'target_name': 'node', + 'type': 'shared_library', 'dependencies': [ 'node_js2c#host', @@ -105,7 +105,6 @@ 'src/node_file.cc', 'src/node_http_parser.cc', 'src/node_javascript.cc', - 'src/node_main.cc', 'src/node_os.cc', 'src/node_v8.cc', 'src/node_v8_platform.cc', @@ -207,22 +206,6 @@ [ 'node_shared_openssl=="false"', { 'dependencies': [ './deps/openssl/openssl.gyp:openssl', - - # For tests - './deps/openssl/openssl.gyp:openssl-cli', - ], - # Do not let unused OpenSSL symbols to slip away - 'xcode_settings': { - 'OTHER_LDFLAGS': [ - '-Wl,-force_load,<(PRODUCT_DIR)/libopenssl.a', - ], - }, - 'conditions': [ - ['OS in "linux freebsd"', { - 'ldflags': [ - '-Wl,--whole-archive <(PRODUCT_DIR)/libopenssl.a -Wl,--no-whole-archive', - ], - }], ], }]] }, { @@ -389,12 +372,6 @@ ], }], ], - 'msvs_settings': { - 'VCManifestTool': { - 'EmbedManifest': 'true', - 'AdditionalManifestFiles': 'src/res/node.exe.extra.manifest' - } - }, }, # generate ETW header and resource files { diff --git a/src/debug-agent.h b/src/debug-agent.h index f18683a8287..e7aef96b9f3 100644 --- a/src/debug-agent.h +++ b/src/debug-agent.h @@ -22,6 +22,7 @@ #ifndef SRC_DEBUG_AGENT_H_ #define SRC_DEBUG_AGENT_H_ +#include "node.h" #include "util.h" #include "util-inl.h" #include "uv.h" @@ -66,8 +67,8 @@ class AgentMessage { class Agent { public: - explicit Agent(node::Environment* env); - ~Agent(); + NODE_EXTERN explicit Agent(node::Environment* env); + NODE_EXTERN ~Agent(); typedef void (*DispatchHandler)(node::Environment* env); diff --git a/src/node.cc b/src/node.cc index 02df0d8a5b2..5f8dc07b077 100644 --- a/src/node.cc +++ b/src/node.cc @@ -108,6 +108,9 @@ using v8::V8; using v8::Value; using v8::kExternalUint32Array; +bool g_standalone_mode = true; +bool g_upstream_node_mode = true; + static bool print_eval = false; static bool force_repl = false; static bool trace_deprecation = false; @@ -116,8 +119,6 @@ static bool abort_on_uncaught_exception = false; static const char* eval_string = nullptr; static unsigned int preload_module_count = 0; static const char** preload_modules = nullptr; -static bool use_debug_agent = false; -static bool debug_wait_connect = false; static int debug_port = 5858; static bool v8_is_profiling = false; static bool node_is_initialized = false; @@ -126,6 +127,10 @@ static node_module* modlist_builtin; static node_module* modlist_linked; static node_module* modlist_addon; +// Exposed for use from atom::NodeMain. +bool use_debug_agent = false; +bool debug_wait_connect = false; + #if defined(NODE_HAVE_I18N_SUPPORT) // Path to ICU data (for i18n / Intl) static const char* icu_data_dir = nullptr; @@ -793,7 +798,11 @@ Local UVException(Isolate* isolate, if (!msg || !msg[0]) msg = uv_strerror(errorno); - Local js_code = OneByteString(isolate, uv_err_name(errorno)); + const char* err_name = uv_err_name(errorno); + if (err_name == NULL) + err_name = "UnknownSystemError"; + + Local js_code = OneByteString(isolate, err_name); Local js_syscall = OneByteString(isolate, syscall); Local js_path; Local js_dest; @@ -1089,6 +1098,7 @@ Handle MakeCallback(Environment* env, env->tick_callback_function()->Call(process, 0, nullptr); CHECK_EQ(env->context(), env->isolate()->GetCurrentContext()); + if (!g_standalone_mode) try_catch.Reset(); if (try_catch.HasCaught()) { return Undefined(env->isolate()); } @@ -1115,6 +1125,7 @@ Handle MakeCallback(Environment* env, tick_info->set_in_tick(false); + if (!g_standalone_mode) try_catch.Reset(); if (try_catch.HasCaught()) { tick_info->set_last_threw(true); return Undefined(env->isolate()); @@ -2891,8 +2902,12 @@ static void RawDebug(const FunctionCallbackInfo& args) { void LoadEnvironment(Environment* env) { HandleScope handle_scope(env->isolate()); + if (g_upstream_node_mode) { // No indent to minimize diff. env->isolate()->SetFatalErrorHandler(node::OnFatalError); + } // g_upstream_node_mode + if (g_standalone_mode) { // No indent to minimize diff. env->isolate()->AddMessageListener(OnMessage); + } // g_standalone_mode // Compile, execute the src/node.js file. (Which was included as static C // string in node_natives.h. 'natve_node' is the string containing that @@ -3187,8 +3202,8 @@ static void DispatchMessagesDebugAgentCallback(Environment* env) { uv_async_send(&dispatch_debug_messages_async); } - -static void StartDebug(Environment* env, bool wait) { +// Called from atom::NodeMain. +void StartDebug(Environment* env, bool wait) { CHECK(!debugger_running); env->debugger_agent()->set_dispatch_handler( @@ -3531,6 +3546,7 @@ void Init(int* argc, // Initialize prog_start_time to get relative uptime. prog_start_time = static_cast(uv_now(uv_default_loop())); + if (g_upstream_node_mode) { // No indent to minimize diff. // Make inherited handles noninheritable. uv_disable_stdio_inheritance(); @@ -3595,12 +3611,15 @@ void Init(int* argc, const char expose_debug_as[] = "--expose_debug_as=v8debug"; V8::SetFlagsFromString(expose_debug_as, sizeof(expose_debug_as) - 1); } + } // g_upstream_node_mode +#if 0 V8::SetArrayBufferAllocator(&ArrayBufferAllocator::the_singleton); if (!use_debug_agent) { RegisterDebugSignalHandler(); } +#endif // We should set node_is_initialized here instead of in node::Start, // otherwise embedders using node::Init to initialize everything will not be diff --git a/src/node.h b/src/node.h index 28b40aa0721..7ab69998b20 100644 --- a/src/node.h +++ b/src/node.h @@ -151,6 +151,8 @@ typedef intptr_t ssize_t; namespace node { NODE_EXTERN extern bool no_deprecation; +NODE_EXTERN extern bool use_debug_agent; +NODE_EXTERN extern bool debug_wait_connect; NODE_EXTERN int Start(int argc, char *argv[]); NODE_EXTERN void Init(int* argc, @@ -184,6 +186,8 @@ NODE_EXTERN void EmitBeforeExit(Environment* env); NODE_EXTERN int EmitExit(Environment* env); NODE_EXTERN void RunAtExit(Environment* env); +NODE_EXTERN void StartDebug(Environment* env, bool wait); + /* Converts a unixtime to V8 Date */ #define NODE_UNIXTIME_V8(t) v8::Date::New(v8::Isolate::GetCurrent(), \ 1000 * static_cast(t)) @@ -369,14 +373,14 @@ extern "C" NODE_EXTERN void node_module_register(void* mod); #if defined(_MSC_VER) #pragma section(".CRT$XCU", read) #define NODE_C_CTOR(fn) \ - static void __cdecl fn(void); \ + void __cdecl fn(void); \ __declspec(dllexport, allocate(".CRT$XCU")) \ void (__cdecl*fn ## _)(void) = fn; \ - static void __cdecl fn(void) + void __cdecl fn(void) #else #define NODE_C_CTOR(fn) \ - static void fn(void) __attribute__((constructor)); \ - static void fn(void) + void fn(void) __attribute__((constructor)); \ + void fn(void) #endif #define NODE_MODULE_X(modname, regfunc, priv, flags) \ diff --git a/src/node.js b/src/node.js index 63465290a0c..6fa619cf7a6 100644 --- a/src/node.js +++ b/src/node.js @@ -21,12 +21,18 @@ process.EventEmitter = EventEmitter; // process.EventEmitter is deprecated + var isRenderer = process.argv[2] == '--type=renderer'; + // do this good and early, since it handles errors. startup.processFatal(); startup.globalVariables(); + if (!isRenderer) { // No indent to minimize diff. startup.globalTimeouts(); startup.globalConsole(); + } // not isRenderer + + startup.initAsarSupport(); startup.processAssert(); startup.processConfig(); @@ -34,6 +40,7 @@ startup.processPromises(); startup.processStdio(); startup.processKillAndExit(); + if (!isRenderer) { // No indent to minimize diff. startup.processSignalHandlers(); // Do not initialize channel in debugger agent, it deletes env variable @@ -42,6 +49,7 @@ startup.processChannel(); startup.processRawDebug(); + } // not isRenderer process.argv[0] = process.execPath; @@ -864,5 +872,9 @@ NativeModule._cache[this.id] = this; }; + startup.initAsarSupport = function() { + process.binding('atom_common_asar').initAsarSupport(process, NativeModule.require); + } + startup(); }); diff --git a/src/node_file.cc b/src/node_file.cc index 37dbb77f93e..9b404f28b64 100644 --- a/src/node_file.cc +++ b/src/node_file.cc @@ -449,6 +449,26 @@ static void Stat(const FunctionCallbackInfo& args) { } } +static void StatNoException(const FunctionCallbackInfo& args) { + Environment* env = Environment::GetCurrent(args.GetIsolate()); + HandleScope scope(env->isolate()); + + if (args.Length() < 1 || !args[0]->IsString()) { + args.GetReturnValue().Set(v8::Boolean::New(env->isolate(), false)); + return; + } + + String::Utf8Value path(args[0]); + + fs_req_wrap req_wrap; + int result = uv_fs_stat(uv_default_loop(), &req_wrap.req, *path, NULL); + if (result < 0) + args.GetReturnValue().Set(v8::Boolean::New(env->isolate(), false)); + else + args.GetReturnValue().Set( + BuildStatsObject(env, static_cast(SYNC_REQ.ptr))); +} + static void LStat(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); @@ -468,6 +488,26 @@ static void LStat(const FunctionCallbackInfo& args) { } } +static void LStatNoException(const FunctionCallbackInfo& args) { + Environment* env = Environment::GetCurrent(args.GetIsolate()); + HandleScope scope(env->isolate()); + + String::Utf8Value path(args[0]); + + if (args.Length() < 1 || !args[0]->IsString()) { + args.GetReturnValue().Set(v8::Boolean::New(env->isolate(), false)); + return; + } + + fs_req_wrap req_wrap; + int result = uv_fs_lstat(uv_default_loop(), &req_wrap.req, *path, NULL); + if (result < 0) + args.GetReturnValue().Set(v8::Boolean::New(env->isolate(), false)); + else + args.GetReturnValue().Set( + BuildStatsObject(env, static_cast(SYNC_REQ.ptr))); +} + static void FStat(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); @@ -1137,7 +1177,9 @@ void InitFs(Handle target, env->SetMethod(target, "mkdir", MKDir); env->SetMethod(target, "readdir", ReadDir); env->SetMethod(target, "stat", Stat); + env->SetMethod(target, "statNoException", StatNoException); env->SetMethod(target, "lstat", LStat); + env->SetMethod(target, "lstatNoException", LStatNoException); env->SetMethod(target, "fstat", FStat); env->SetMethod(target, "link", Link); env->SetMethod(target, "symlink", Symlink); diff --git a/src/node_internals.h b/src/node_internals.h index c99b2feeb0b..b7980e53a6a 100644 --- a/src/node_internals.h +++ b/src/node_internals.h @@ -17,6 +17,10 @@ namespace node { // Forward declaration class Environment; +// Whether node should open some low level hooks. +NODE_EXTERN extern bool g_standalone_mode; +NODE_EXTERN extern bool g_upstream_node_mode; + // If persistent.IsWeak() == false, then do not call persistent.Reset() // while the returned Local is still in scope, it will destroy the // reference to the object. @@ -148,20 +152,20 @@ inline MUST_USE_RESULT bool ParseArrayIndex(v8::Handle arg, return true; } -void ThrowError(v8::Isolate* isolate, const char* errmsg); -void ThrowTypeError(v8::Isolate* isolate, const char* errmsg); -void ThrowRangeError(v8::Isolate* isolate, const char* errmsg); -void ThrowErrnoException(v8::Isolate* isolate, - int errorno, - const char* syscall = nullptr, - const char* message = nullptr, - const char* path = nullptr); -void ThrowUVException(v8::Isolate* isolate, - int errorno, - const char* syscall = nullptr, - const char* message = nullptr, - const char* path = nullptr, - const char* dest = nullptr); +NODE_EXTERN void ThrowError(v8::Isolate* isolate, const char* errmsg); +NODE_EXTERN void ThrowTypeError(v8::Isolate* isolate, const char* errmsg); +NODE_EXTERN void ThrowRangeError(v8::Isolate* isolate, const char* errmsg); +NODE_EXTERN void ThrowErrnoException(v8::Isolate* isolate, + int errorno, + const char* syscall = nullptr, + const char* message = nullptr, + const char* path = nullptr); +NODE_EXTERN void ThrowUVException(v8::Isolate* isolate, + int errorno, + const char* syscall = nullptr, + const char* message = nullptr, + const char* path = nullptr, + const char* dest = nullptr); NODE_DEPRECATED("Use ThrowError(isolate)", inline void ThrowError(const char* errmsg) { diff --git a/src/smalloc.cc b/src/smalloc.cc index 57ea97f2aca..d251afc77d9 100644 --- a/src/smalloc.cc +++ b/src/smalloc.cc @@ -616,7 +616,9 @@ void Initialize(Handle exports, Uint32::NewFromUnsigned(env->isolate(), kMaxType)); HeapProfiler* heap_profiler = env->isolate()->GetHeapProfiler(); +#if 0 heap_profiler->SetWrapperClassInfoProvider(ALLOC_ID, WrapperInfo); +#endif } diff --git a/src/string_bytes.cc b/src/string_bytes.cc index 4f896ace3fb..70566a99015 100644 --- a/src/string_bytes.cc +++ b/src/string_bytes.cc @@ -258,13 +258,6 @@ bool StringBytes::GetExternalParts(Isolate* isolate, *data = ext->data(); *len = ext->length(); return true; - - } else if (str->IsExternal()) { - const String::ExternalStringResource* ext; - ext = str->GetExternalStringResource(); - *data = reinterpret_cast(ext->data()); - *len = ext->length() * sizeof(*ext->data()); - return true; } return false; diff --git a/src/uv.cc b/src/uv.cc index 2208ebde3c4..b0527c67655 100644 --- a/src/uv.cc +++ b/src/uv.cc @@ -22,6 +22,8 @@ void ErrName(const FunctionCallbackInfo& args) { if (err >= 0) return env->ThrowError("err >= 0"); const char* name = uv_err_name(err); + if (name == NULL) + name = "UnknownSystemError"; args.GetReturnValue().Set(OneByteString(env->isolate(), name)); }