diff options
author | Jeremiah Senkpiel <fishrock123@rocketmail.com> | 2016-03-15 16:23:39 -0400 |
---|---|---|
committer | Jeremiah Senkpiel <fishrock123@rocketmail.com> | 2016-03-22 19:21:15 -0400 |
commit | 4bf2acaa1ee0e8b9504b1b1f3ba8047c66a05480 (patch) | |
tree | 2ff78635bef0a25183166bea22de429f6e5e7c9d /lib | |
parent | 015cef25eb30b8ac447fa855dd434f4da327d884 (diff) | |
download | android-node-v8-4bf2acaa1ee0e8b9504b1b1f3ba8047c66a05480.tar.gz android-node-v8-4bf2acaa1ee0e8b9504b1b1f3ba8047c66a05480.tar.bz2 android-node-v8-4bf2acaa1ee0e8b9504b1b1f3ba8047c66a05480.zip |
lib,src: move src/node.js to lib/internal/node.js
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 'lib')
-rw-r--r-- | lib/internal/node.js | 433 |
1 files changed, 433 insertions, 0 deletions
diff --git a/lib/internal/node.js b/lib/internal/node.js new file mode 100644 index 0000000000..0a688a1b0f --- /dev/null +++ b/lib/internal/node.js @@ -0,0 +1,433 @@ +// Hello, and welcome to hacking node.js! +// +// This file is invoked by node::LoadEnvironment in src/node.cc, and is +// responsible for bootstrapping the node.js core. As special caution is given +// to the performance of the startup process, many dependencies are invoked +// lazily. + +'use strict'; + +(function(process) { + this.global = this; + + function startup() { + var EventEmitter = NativeModule.require('events'); + process._eventsCount = 0; + + Object.setPrototypeOf(process, Object.create(EventEmitter.prototype, { + constructor: { + value: process.constructor + } + })); + + EventEmitter.call(process); + + let eeWarned = false; + Object.defineProperty(process, 'EventEmitter', { + get() { + const internalUtil = NativeModule.require('internal/util'); + eeWarned = internalUtil.printDeprecationMessage( + "process.EventEmitter is deprecated. Use require('events') instead.", + eeWarned + ); + return EventEmitter; + } + }); + + setupProcessObject(); + + // do this good and early, since it handles errors. + setupProcessFatal(); + + setupGlobalVariables(); + setupGlobalTimeouts(); + setupGlobalConsole(); + + 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') + _process.setupChannel(); + + _process.setupRawDebug(); + + process.argv[0] = process.execPath; + + // There are various modes that Node can run in. The most common two + // are running from a script and running the REPL - but there are a few + // others like the debugger or running --eval arguments. Here we decide + // which mode we run in. + + if (NativeModule.exists('_third_party_main')) { + // To allow people to extend Node in different ways, this hook allows + // one to drop a file lib/_third_party_main.js into the build + // directory which will be executed instead of Node's normal loading. + process.nextTick(function() { + NativeModule.require('_third_party_main'); + }); + + } else if (process.argv[1] == 'debug') { + // Start the debugger agent + NativeModule.require('_debugger').start(); + + } else if (process.argv[1] == '--debug-agent') { + // Start the debugger agent + NativeModule.require('_debug_agent').start(); + + } else if (process.profProcess) { + NativeModule.require('internal/v8_prof_processor'); + + } else { + // There is user code to be run + + // If this is a worker in cluster mode, start up the communication + // channel. This needs to be done before any user code gets executed + // (including preload modules). + if (process.argv[1] && process.env.NODE_UNIQUE_ID) { + var cluster = NativeModule.require('cluster'); + cluster._setupWorker(); + + // Make sure it's not accidentally inherited by child processes. + delete process.env.NODE_UNIQUE_ID; + } + + if (process._eval != null && !process._forceRepl) { + // User passed '-e' or '--eval' arguments to Node without '-i' or + // '--interactive' + preloadModules(); + evalScript('[eval]'); + } else if (process.argv[1]) { + // make process.argv[1] into a full path + var path = NativeModule.require('path'); + process.argv[1] = path.resolve(process.argv[1]); + + var Module = NativeModule.require('module'); + + // check if user passed `-c` or `--check` arguments to Node. + if (process._syntax_check_only != null) { + var vm = NativeModule.require('vm'); + var fs = NativeModule.require('fs'); + var internalModule = NativeModule.require('internal/module'); + // read the source + var filename = Module._resolveFilename(process.argv[1]); + var source = fs.readFileSync(filename, 'utf-8'); + // remove shebang and BOM + source = internalModule.stripBOM(source.replace(/^\#\!.*/, '')); + // wrap it + source = Module.wrap(source); + // compile the script, this will throw if it fails + new vm.Script(source, {filename: filename, displayErrors: true}); + process.exit(0); + } + + preloadModules(); + + if (global.v8debug && + process.execArgv.some(function(arg) { + return arg.match(/^--debug-brk(=[0-9]*)?$/); + })) { + + // XXX Fix this terrible hack! + // + // Give the client program a few ticks to connect. + // Otherwise, there's a race condition where `node debug foo.js` + // will not be able to connect in time to catch the first + // breakpoint message on line 1. + // + // A better fix would be to somehow get a message from the + // global.v8debug object about a connection, and runMain when + // that occurs. --isaacs + + var debugTimeout = +process.env.NODE_DEBUG_TIMEOUT || 50; + setTimeout(Module.runMain, debugTimeout); + + } else { + // Main entry point into most programs: + Module.runMain(); + } + + } else { + preloadModules(); + // If -i or --interactive were passed, or stdin is a TTY. + if (process._forceRepl || NativeModule.require('tty').isatty(0)) { + // REPL + var cliRepl = NativeModule.require('internal/repl'); + cliRepl.createInternalRepl(process.env, function(err, repl) { + if (err) { + throw err; + } + repl.on('exit', function() { + if (repl._flushing) { + repl.pause(); + return repl.once('flushHistory', function() { + process.exit(); + }); + } + process.exit(); + }); + }); + + if (process._eval != null) { + // User passed '-e' or '--eval' + evalScript('[eval]'); + } + } else { + // Read all of stdin - execute it. + process.stdin.setEncoding('utf8'); + + var code = ''; + process.stdin.on('data', function(d) { + code += d; + }); + + process.stdin.on('end', function() { + process._eval = code; + evalScript('[stdin]'); + }); + } + } + } + } + + function setupProcessObject() { + process._setupProcessObject(pushValueToArray); + + function pushValueToArray() { + for (var i = 0; i < arguments.length; i++) + this.push(arguments[i]); + } + } + + function setupGlobalVariables() { + global.process = process; + global.global = global; + const util = NativeModule.require('util'); + + // Deprecate GLOBAL and root + ['GLOBAL', 'root'].forEach(function(name) { + // getter + const get = util.deprecate(function() { + return this; + }, `'${name}' is deprecated, use 'global'`); + // setter + const set = util.deprecate(function(value) { + Object.defineProperty(this, name, { + configurable: true, + writable: true, + enumerable: true, + value: value + }); + }, `'${name}' is deprecated, use 'global'`); + // define property + Object.defineProperty(global, name, { get, set, configurable: true }); + }); + + global.Buffer = NativeModule.require('buffer').Buffer; + process.domain = null; + process._exiting = false; + } + + function setupGlobalTimeouts() { + const timers = NativeModule.require('timers'); + global.clearImmediate = timers.clearImmediate; + global.clearInterval = timers.clearInterval; + global.clearTimeout = timers.clearTimeout; + global.setImmediate = timers.setImmediate; + global.setInterval = timers.setInterval; + global.setTimeout = timers.setTimeout; + } + + function setupGlobalConsole() { + global.__defineGetter__('console', function() { + return NativeModule.require('console'); + }); + } + + function setupProcessFatal() { + + process._fatalException = function(er) { + var caught; + + if (process.domain && process.domain._errorHandler) + caught = process.domain._errorHandler(er) || caught; + + if (!caught) + caught = process.emit('uncaughtException', er); + + // If someone handled it, then great. otherwise, die in C++ land + // since that means that we'll exit the process, emit the 'exit' event + if (!caught) { + try { + if (!process._exiting) { + process._exiting = true; + process.emit('exit', 1); + } + } catch (er) { + // nothing to be done about it at this point. + } + + // if we handled an error, then make sure any ticks get processed + } else { + NativeModule.require('timers').setImmediate(process._tickCallback); + } + + return caught; + }; + } + + function evalScript(name) { + var Module = NativeModule.require('module'); + var path = NativeModule.require('path'); + + try { + var cwd = process.cwd(); + } catch (e) { + // getcwd(3) can fail if the current working directory has been deleted. + // Fall back to the directory name of the (absolute) executable path. + // It's not really correct but what are the alternatives? + cwd = path.dirname(process.execPath); + } + + var module = new Module(name); + module.filename = path.join(cwd, name); + module.paths = Module._nodeModulePaths(cwd); + var script = process._eval; + var body = script; + script = `global.__filename = ${JSON.stringify(name)};\n` + + 'global.exports = exports;\n' + + 'global.module = module;\n' + + 'global.__dirname = __dirname;\n' + + 'global.require = require;\n' + + 'return require("vm").runInThisContext(' + + `${JSON.stringify(body)}, { filename: ` + + `${JSON.stringify(name)}, displayErrors: true });\n`; + // Defer evaluation for a tick. This is a workaround for deferred + // events not firing when evaluating scripts from the command line, + // see https://github.com/nodejs/node/issues/1600. + process.nextTick(function() { + var result = module._compile(script, `${name}-wrapper`); + if (process._print_eval) console.log(result); + }); + } + + // Load preload modules + 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 + // node binary, so they can be loaded faster. + + var ContextifyScript = process.binding('contextify').ContextifyScript; + function runInThisContext(code, options) { + var script = new ContextifyScript(code, options); + return script.runInThisContext(); + } + + function NativeModule(id) { + this.filename = `${id}.js`; + this.id = id; + this.exports = {}; + this.loaded = false; + } + + NativeModule._source = process.binding('natives'); + NativeModule._cache = {}; + + NativeModule.require = function(id) { + if (id == 'native_module') { + return NativeModule; + } + + var cached = NativeModule.getCached(id); + if (cached) { + return cached.exports; + } + + if (!NativeModule.exists(id)) { + throw new Error(`No such native module ${id}`); + } + + process.moduleLoadList.push(`NativeModule ${id}`); + + var nativeModule = new NativeModule(id); + + nativeModule.cache(); + nativeModule.compile(); + + return nativeModule.exports; + }; + + NativeModule.getCached = function(id) { + return NativeModule._cache[id]; + }; + + NativeModule.exists = function(id) { + return NativeModule._source.hasOwnProperty(id); + }; + + const EXPOSE_INTERNALS = process.execArgv.some(function(arg) { + return arg.match(/^--expose[-_]internals$/); + }); + + if (EXPOSE_INTERNALS) { + NativeModule.nonInternalExists = NativeModule.exists; + + NativeModule.isInternal = function(id) { + return false; + }; + } else { + NativeModule.nonInternalExists = function(id) { + return NativeModule.exists(id) && !NativeModule.isInternal(id); + }; + + NativeModule.isInternal = function(id) { + return id.startsWith('internal/'); + }; + } + + + NativeModule.getSource = function(id) { + return NativeModule._source[id]; + }; + + NativeModule.wrap = function(script) { + return NativeModule.wrapper[0] + script + NativeModule.wrapper[1]; + }; + + NativeModule.wrapper = [ + '(function (exports, require, module, __filename, __dirname) { ', + '\n});' + ]; + + NativeModule.prototype.compile = function() { + var source = NativeModule.getSource(this.id); + source = NativeModule.wrap(source); + + var fn = runInThisContext(source, { + filename: this.filename, + lineOffset: 0, + displayErrors: true + }); + fn(this.exports, NativeModule.require, this, this.filename); + + this.loaded = true; + }; + + NativeModule.prototype.cache = function() { + NativeModule._cache[this.id] = this; + }; + + startup(); +}); |