diff options
author | Jeremiah Senkpiel <fishrock123@rocketmail.com> | 2016-03-15 16:13:52 -0400 |
---|---|---|
committer | Jeremiah Senkpiel <fishrock123@rocketmail.com> | 2016-03-22 19:20:01 -0400 |
commit | 015cef25eb30b8ac447fa855dd434f4da327d884 (patch) | |
tree | d8ad529429cf89027a3198ff24f961cb562dfc1c /src | |
parent | 2c672891e11618b0ef401012d97524f43564cbb3 (diff) | |
download | android-node-v8-015cef25eb30b8ac447fa855dd434f4da327d884.tar.gz android-node-v8-015cef25eb30b8ac447fa855dd434f4da327d884.tar.bz2 android-node-v8-015cef25eb30b8ac447fa855dd434f4da327d884.zip |
lib,src: refactor src/node.js into internal files
PR-URL: https://github.com/nodejs/node/pull/5103
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/node.js | 601 |
1 files changed, 31 insertions, 570 deletions
diff --git a/src/node.js b/src/node.js index c58871e31d..0a688a1b0f 100644 --- a/src/node.js +++ b/src/node.js @@ -34,29 +34,30 @@ } }); - startup.setupProcessObject(); + setupProcessObject(); // do this good and early, since it handles errors. - startup.processFatal(); + setupProcessFatal(); - startup.globalVariables(); - startup.globalTimeouts(); - startup.globalConsole(); + setupGlobalVariables(); + setupGlobalTimeouts(); + setupGlobalConsole(); - startup.processAssert(); - startup.processConfig(); - startup.processNextTick(); - startup.processPromises(); - startup.processStdio(); - startup.processKillAndExit(); - startup.processSignalHandlers(); + const _process = NativeModule.require('internal/process'); + + _process.setup_hrtime(); + _process.setupConfig(NativeModule._source); + NativeModule.require('internal/process/next_tick').setup(); + NativeModule.require('internal/process/stdio').setup(); + _process.setupKillAndExit(); + _process.setupSignalHandlers(); // Do not initialize channel in debugger agent, it deletes env variable // and the main thread won't see it. if (process.argv[1] !== '--debug-agent') - startup.processChannel(); + _process.setupChannel(); - startup.processRawDebug(); + _process.setupRawDebug(); process.argv[0] = process.execPath; @@ -101,7 +102,7 @@ if (process._eval != null && !process._forceRepl) { // User passed '-e' or '--eval' arguments to Node without '-i' or // '--interactive' - startup.preloadModules(); + preloadModules(); evalScript('[eval]'); } else if (process.argv[1]) { // make process.argv[1] into a full path @@ -127,7 +128,8 @@ process.exit(0); } - startup.preloadModules(); + preloadModules(); + if (global.v8debug && process.execArgv.some(function(arg) { return arg.match(/^--debug-brk(=[0-9]*)?$/); @@ -153,7 +155,7 @@ } } else { - startup.preloadModules(); + preloadModules(); // If -i or --interactive were passed, or stdin is a TTY. if (process._forceRepl || NativeModule.require('tty').isatty(0)) { // REPL @@ -195,38 +197,16 @@ } } - startup.setupProcessObject = function() { - const _hrtime = process.hrtime; - const hrValues = new Uint32Array(3); - + function setupProcessObject() { process._setupProcessObject(pushValueToArray); function pushValueToArray() { for (var i = 0; i < arguments.length; i++) this.push(arguments[i]); } + } - process.hrtime = function hrtime(ar) { - _hrtime(hrValues); - - if (typeof ar !== 'undefined') { - if (Array.isArray(ar)) { - const sec = (hrValues[0] * 0x100000000 + hrValues[1]) - ar[0]; - const nsec = hrValues[2] - ar[1]; - return [nsec < 0 ? sec - 1 : sec, nsec < 0 ? nsec + 1e9 : nsec]; - } - - throw new TypeError('process.hrtime() only accepts an Array tuple'); - } - - return [ - hrValues[0] * 0x100000000 + hrValues[1], - hrValues[2] - ]; - }; - }; - - startup.globalVariables = function() { + function setupGlobalVariables() { global.process = process; global.global = global; const util = NativeModule.require('util'); @@ -253,9 +233,9 @@ global.Buffer = NativeModule.require('buffer').Buffer; process.domain = null; process._exiting = false; - }; + } - startup.globalTimeouts = function() { + function setupGlobalTimeouts() { const timers = NativeModule.require('timers'); global.clearImmediate = timers.clearImmediate; global.clearInterval = timers.clearInterval; @@ -263,25 +243,15 @@ global.setImmediate = timers.setImmediate; global.setInterval = timers.setInterval; global.setTimeout = timers.setTimeout; - }; + } - startup.globalConsole = function() { + function setupGlobalConsole() { global.__defineGetter__('console', function() { return NativeModule.require('console'); }); - }; - - - startup._lazyConstants = null; - - startup.lazyConstants = function() { - if (!startup._lazyConstants) { - startup._lazyConstants = process.binding('constants'); - } - return startup._lazyConstants; - }; + } - startup.processFatal = function() { + function setupProcessFatal() { process._fatalException = function(er) { var caught; @@ -311,242 +281,7 @@ return caught; }; - }; - - var assert; - startup.processAssert = function() { - assert = process.assert = function(x, msg) { - if (!x) throw new Error(msg || 'assertion error'); - }; - }; - - startup.processConfig = function() { - // used for `process.config`, but not a real module - var config = NativeModule._source.config; - delete NativeModule._source.config; - - // strip the gyp comment line at the beginning - config = config.split('\n') - .slice(1) - .join('\n') - .replace(/"/g, '\\"') - .replace(/'/g, '"'); - - process.config = JSON.parse(config, function(key, value) { - if (value === 'true') return true; - if (value === 'false') return false; - return value; - }); - }; - - var addPendingUnhandledRejection; - var hasBeenNotifiedProperty = new WeakMap(); - startup.processNextTick = function() { - var nextTickQueue = []; - var pendingUnhandledRejections = []; - var microtasksScheduled = false; - - // Used to run V8's micro task queue. - var _runMicrotasks = {}; - - // *Must* match Environment::TickInfo::Fields in src/env.h. - var kIndex = 0; - var kLength = 1; - - process.nextTick = nextTick; - // Needs to be accessible from beyond this scope. - process._tickCallback = _tickCallback; - process._tickDomainCallback = _tickDomainCallback; - - // This tickInfo thing is used so that the C++ code in src/node.cc - // can have easy access to our nextTick state, and avoid unnecessary - // calls into JS land. - const tickInfo = process._setupNextTick(_tickCallback, _runMicrotasks); - - _runMicrotasks = _runMicrotasks.runMicrotasks; - - function tickDone() { - if (tickInfo[kLength] !== 0) { - if (tickInfo[kLength] <= tickInfo[kIndex]) { - nextTickQueue = []; - tickInfo[kLength] = 0; - } else { - nextTickQueue.splice(0, tickInfo[kIndex]); - tickInfo[kLength] = nextTickQueue.length; - } - } - tickInfo[kIndex] = 0; - } - - function scheduleMicrotasks() { - if (microtasksScheduled) - return; - - nextTickQueue.push({ - callback: runMicrotasksCallback, - domain: null - }); - - tickInfo[kLength]++; - microtasksScheduled = true; - } - - function runMicrotasksCallback() { - microtasksScheduled = false; - _runMicrotasks(); - - if (tickInfo[kIndex] < tickInfo[kLength] || - emitPendingUnhandledRejections()) - scheduleMicrotasks(); - } - - function _combinedTickCallback(args, callback) { - if (args === undefined) { - callback(); - } else { - switch (args.length) { - case 1: - callback(args[0]); - break; - case 2: - callback(args[0], args[1]); - break; - case 3: - callback(args[0], args[1], args[2]); - break; - default: - callback.apply(null, args); - } - } - } - - // Run callbacks that have no domain. - // Using domains will cause this to be overridden. - function _tickCallback() { - var callback, args, tock; - - do { - while (tickInfo[kIndex] < tickInfo[kLength]) { - tock = nextTickQueue[tickInfo[kIndex]++]; - callback = tock.callback; - args = tock.args; - // Using separate callback execution functions allows direct - // callback invocation with small numbers of arguments to avoid the - // performance hit associated with using `fn.apply()` - _combinedTickCallback(args, callback); - if (1e4 < tickInfo[kIndex]) - tickDone(); - } - tickDone(); - _runMicrotasks(); - emitPendingUnhandledRejections(); - } while (tickInfo[kLength] !== 0); - } - - function _tickDomainCallback() { - var callback, domain, args, tock; - - do { - while (tickInfo[kIndex] < tickInfo[kLength]) { - tock = nextTickQueue[tickInfo[kIndex]++]; - callback = tock.callback; - domain = tock.domain; - args = tock.args; - if (domain) - domain.enter(); - // Using separate callback execution functions allows direct - // callback invocation with small numbers of arguments to avoid the - // performance hit associated with using `fn.apply()` - _combinedTickCallback(args, callback); - if (1e4 < tickInfo[kIndex]) - tickDone(); - if (domain) - domain.exit(); - } - tickDone(); - _runMicrotasks(); - emitPendingUnhandledRejections(); - } while (tickInfo[kLength] !== 0); - } - - function TickObject(c, args) { - this.callback = c; - this.domain = process.domain || null; - this.args = args; - } - - function nextTick(callback) { - if (typeof callback !== 'function') - throw new TypeError('callback is not a function'); - // on the way out, don't bother. it won't get fired anyway. - if (process._exiting) - return; - - var args; - if (arguments.length > 1) { - args = new Array(arguments.length - 1); - for (var i = 1; i < arguments.length; i++) - args[i - 1] = arguments[i]; - } - - nextTickQueue.push(new TickObject(callback, args)); - tickInfo[kLength]++; - } - - function emitPendingUnhandledRejections() { - var hadListeners = false; - while (pendingUnhandledRejections.length > 0) { - var promise = pendingUnhandledRejections.shift(); - var reason = pendingUnhandledRejections.shift(); - if (hasBeenNotifiedProperty.get(promise) === false) { - hasBeenNotifiedProperty.set(promise, true); - if (!process.emit('unhandledRejection', reason, promise)) { - // Nobody is listening. - // TODO(petkaantonov) Take some default action, see #830 - } else { - hadListeners = true; - } - } - } - return hadListeners; - } - - addPendingUnhandledRejection = function(promise, reason) { - pendingUnhandledRejections.push(promise, reason); - scheduleMicrotasks(); - }; - }; - - startup.processPromises = function() { - var promiseRejectEvent = process._promiseRejectEvent; - - function unhandledRejection(promise, reason) { - hasBeenNotifiedProperty.set(promise, false); - addPendingUnhandledRejection(promise, reason); - } - - function rejectionHandled(promise) { - var hasBeenNotified = hasBeenNotifiedProperty.get(promise); - if (hasBeenNotified !== undefined) { - hasBeenNotifiedProperty.delete(promise); - if (hasBeenNotified === true) { - process.nextTick(function() { - process.emit('rejectionHandled', promise); - }); - } - - } - } - - process._setupPromises(function(event, promise, reason) { - if (event === promiseRejectEvent.unhandled) - unhandledRejection(promise, reason); - else if (event === promiseRejectEvent.handled) - rejectionHandled(promise); - else - NativeModule.require('assert').fail('unexpected PromiseRejectEvent'); - }); - }; + } function evalScript(name) { var Module = NativeModule.require('module'); @@ -583,286 +318,12 @@ }); } - function createWritableStdioStream(fd) { - var stream; - var tty_wrap = process.binding('tty_wrap'); - - // Note stream._type is used for test-module-load-list.js - - switch (tty_wrap.guessHandleType(fd)) { - case 'TTY': - var tty = NativeModule.require('tty'); - stream = new tty.WriteStream(fd); - stream._type = 'tty'; - break; - - case 'FILE': - var fs = NativeModule.require('fs'); - stream = new fs.SyncWriteStream(fd, { autoClose: false }); - stream._type = 'fs'; - break; - - case 'PIPE': - case 'TCP': - var net = NativeModule.require('net'); - stream = new net.Socket({ - fd: fd, - readable: false, - writable: true - }); - stream._type = 'pipe'; - break; - - default: - // Probably an error on in uv_guess_handle() - throw new Error('Implement me. Unknown stream file type!'); - } - - // For supporting legacy API we put the FD here. - stream.fd = fd; - - stream._isStdio = true; - - return stream; - } - - startup.processStdio = function() { - var stdin, stdout, stderr; - - process.__defineGetter__('stdout', function() { - if (stdout) return stdout; - stdout = createWritableStdioStream(1); - stdout.destroy = stdout.destroySoon = function(er) { - er = er || new Error('process.stdout cannot be closed.'); - stdout.emit('error', er); - }; - if (stdout.isTTY) { - process.on('SIGWINCH', function() { - stdout._refreshSize(); - }); - } - return stdout; - }); - - process.__defineGetter__('stderr', function() { - if (stderr) return stderr; - stderr = createWritableStdioStream(2); - stderr.destroy = stderr.destroySoon = function(er) { - er = er || new Error('process.stderr cannot be closed.'); - stderr.emit('error', er); - }; - if (stderr.isTTY) { - process.on('SIGWINCH', function() { - stderr._refreshSize(); - }); - } - return stderr; - }); - - process.__defineGetter__('stdin', function() { - if (stdin) return stdin; - - var tty_wrap = process.binding('tty_wrap'); - var fd = 0; - - switch (tty_wrap.guessHandleType(fd)) { - case 'TTY': - var tty = NativeModule.require('tty'); - stdin = new tty.ReadStream(fd, { - highWaterMark: 0, - readable: true, - writable: false - }); - break; - - case 'FILE': - var fs = NativeModule.require('fs'); - stdin = new fs.ReadStream(null, { fd: fd, autoClose: false }); - break; - - case 'PIPE': - case 'TCP': - var net = NativeModule.require('net'); - - // It could be that process has been started with an IPC channel - // sitting on fd=0, in such case the pipe for this fd is already - // present and creating a new one will lead to the assertion failure - // in libuv. - if (process._channel && process._channel.fd === fd) { - stdin = new net.Socket({ - handle: process._channel, - readable: true, - writable: false - }); - } else { - stdin = new net.Socket({ - fd: fd, - readable: true, - writable: false - }); - } - // Make sure the stdin can't be `.end()`-ed - stdin._writableState.ended = true; - break; - - default: - // Probably an error on in uv_guess_handle() - throw new Error('Implement me. Unknown stdin file type!'); - } - - // For supporting legacy API we put the FD here. - stdin.fd = fd; - - // stdin starts out life in a paused state, but node doesn't - // know yet. Explicitly to readStop() it to put it in the - // not-reading state. - if (stdin._handle && stdin._handle.readStop) { - stdin._handle.reading = false; - stdin._readableState.reading = false; - stdin._handle.readStop(); - } - - // if the user calls stdin.pause(), then we need to stop reading - // immediately, so that the process can close down. - stdin.on('pause', function() { - if (!stdin._handle) - return; - stdin._readableState.reading = false; - stdin._handle.reading = false; - stdin._handle.readStop(); - }); - - return stdin; - }); - - process.openStdin = function() { - process.stdin.resume(); - return process.stdin; - }; - }; - - startup.processKillAndExit = function() { - - process.exit = function(code) { - if (code || code === 0) - process.exitCode = code; - - if (!process._exiting) { - process._exiting = true; - process.emit('exit', process.exitCode || 0); - } - process.reallyExit(process.exitCode || 0); - }; - - process.kill = function(pid, sig) { - var err; - - if (pid != (pid | 0)) { - throw new TypeError('invalid pid'); - } - - // preserve null signal - if (0 === sig) { - err = process._kill(pid, 0); - } else { - sig = sig || 'SIGTERM'; - if (startup.lazyConstants()[sig] && - sig.slice(0, 3) === 'SIG') { - err = process._kill(pid, startup.lazyConstants()[sig]); - } else { - throw new Error(`Unknown signal: ${sig}`); - } - } - - if (err) { - var errnoException = NativeModule.require('util')._errnoException; - throw errnoException(err, 'kill'); - } - - return true; - }; - }; - - startup.processSignalHandlers = function() { - // Load events module in order to access prototype elements on process like - // process.addListener. - var signalWraps = {}; - - function isSignal(event) { - return typeof event === 'string' && - event.slice(0, 3) === 'SIG' && - startup.lazyConstants().hasOwnProperty(event); - } - - // Detect presence of a listener for the special signal types - process.on('newListener', function(type, listener) { - if (isSignal(type) && - !signalWraps.hasOwnProperty(type)) { - var Signal = process.binding('signal_wrap').Signal; - var wrap = new Signal(); - - wrap.unref(); - - wrap.onsignal = function() { process.emit(type); }; - - var signum = startup.lazyConstants()[type]; - var err = wrap.start(signum); - if (err) { - wrap.close(); - var errnoException = NativeModule.require('util')._errnoException; - throw errnoException(err, 'uv_signal_start'); - } - - signalWraps[type] = wrap; - } - }); - - process.on('removeListener', function(type, listener) { - if (signalWraps.hasOwnProperty(type) && this.listenerCount(type) === 0) { - signalWraps[type].close(); - delete signalWraps[type]; - } - }); - }; - - - startup.processChannel = function() { - // If we were spawned with env NODE_CHANNEL_FD then load that up and - // start parsing data from that stream. - if (process.env.NODE_CHANNEL_FD) { - var fd = parseInt(process.env.NODE_CHANNEL_FD, 10); - assert(fd >= 0); - - // Make sure it's not accidentally inherited by child processes. - delete process.env.NODE_CHANNEL_FD; - - var cp = NativeModule.require('child_process'); - - // Load tcp_wrap to avoid situation where we might immediately receive - // a message. - // FIXME is this really necessary? - process.binding('tcp_wrap'); - - cp._forkChild(fd); - assert(process.send); - } - }; - - - startup.processRawDebug = function() { - var format = NativeModule.require('util').format; - var rawDebug = process._rawDebug; - process._rawDebug = function() { - rawDebug(format.apply(null, arguments)); - }; - }; - // Load preload modules - startup.preloadModules = function() { + function preloadModules() { if (process._preload_modules) { NativeModule.require('module')._preloadModules(process._preload_modules); } - }; + } // Below you find a minimal module system, which is used to load the node // core modules found in lib/*.js. All core modules are compiled into the |