2011-01-24 23:15:10 +01:00
|
|
|
// Hello, and welcome to hacking node.js!
|
|
|
|
//
|
2015-09-24 08:31:13 +05:30
|
|
|
// 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.
|
2018-03-04 04:55:45 +08:00
|
|
|
//
|
|
|
|
// Before this file is run, lib/internal/bootstrap_loaders.js gets run first
|
|
|
|
// to bootstrap the internal binding and module loaders, including
|
|
|
|
// process.binding(), process._linkedBinding(), internalBinding() and
|
|
|
|
// NativeModule. And then { internalBinding, NativeModule } will be passed
|
|
|
|
// into this bootstrapper to bootstrap Node.js core.
|
2014-11-22 16:59:48 +01:00
|
|
|
|
|
|
|
'use strict';
|
|
|
|
|
2018-03-04 04:55:45 +08:00
|
|
|
(function bootstrapNodeJSCore(process, { internalBinding, NativeModule }) {
|
2017-11-20 19:57:20 +01:00
|
|
|
const exceptionHandlerState = { captureFn: null };
|
2009-11-07 14:37:22 +01:00
|
|
|
|
2011-01-24 23:15:10 +01:00
|
|
|
function startup() {
|
2016-09-17 11:07:23 +02:00
|
|
|
const EventEmitter = NativeModule.require('events');
|
2012-05-22 11:06:05 +02:00
|
|
|
|
2016-10-26 15:21:36 -07:00
|
|
|
const origProcProto = Object.getPrototypeOf(process);
|
2017-08-09 08:58:10 -07:00
|
|
|
Object.setPrototypeOf(origProcProto, EventEmitter.prototype);
|
2016-02-04 10:53:17 +08:00
|
|
|
|
2013-03-05 12:17:48 -08:00
|
|
|
EventEmitter.call(process);
|
2012-05-22 11:06:05 +02:00
|
|
|
|
2016-03-15 16:13:52 -04:00
|
|
|
setupProcessObject();
|
2015-10-14 14:58:52 -06:00
|
|
|
|
2012-12-26 12:28:33 -08:00
|
|
|
// do this good and early, since it handles errors.
|
2016-03-15 16:13:52 -04:00
|
|
|
setupProcessFatal();
|
2012-12-26 12:28:33 -08:00
|
|
|
|
2017-11-24 00:13:44 +01:00
|
|
|
setupV8();
|
2016-10-24 11:24:21 -07:00
|
|
|
setupProcessICUVersions();
|
|
|
|
|
2016-03-15 16:13:52 -04:00
|
|
|
setupGlobalVariables();
|
2017-08-28 21:48:54 -03:00
|
|
|
|
|
|
|
const _process = NativeModule.require('internal/process');
|
|
|
|
_process.setupConfig(NativeModule._source);
|
2017-10-15 22:40:00 +02:00
|
|
|
_process.setupSignalHandlers();
|
2017-11-20 19:57:20 +01:00
|
|
|
_process.setupUncaughtExceptionCapture(exceptionHandlerState);
|
2017-08-28 21:48:54 -03:00
|
|
|
NativeModule.require('internal/process/warning').setup();
|
|
|
|
NativeModule.require('internal/process/next_tick').setup();
|
|
|
|
NativeModule.require('internal/process/stdio').setup();
|
|
|
|
|
2017-08-07 15:53:24 -07:00
|
|
|
const perf = process.binding('performance');
|
|
|
|
const {
|
|
|
|
NODE_PERFORMANCE_MILESTONE_BOOTSTRAP_COMPLETE,
|
|
|
|
NODE_PERFORMANCE_MILESTONE_THIRD_PARTY_MAIN_START,
|
|
|
|
NODE_PERFORMANCE_MILESTONE_THIRD_PARTY_MAIN_END,
|
|
|
|
NODE_PERFORMANCE_MILESTONE_CLUSTER_SETUP_START,
|
|
|
|
NODE_PERFORMANCE_MILESTONE_CLUSTER_SETUP_END,
|
|
|
|
NODE_PERFORMANCE_MILESTONE_MODULE_LOAD_START,
|
|
|
|
NODE_PERFORMANCE_MILESTONE_MODULE_LOAD_END,
|
|
|
|
NODE_PERFORMANCE_MILESTONE_PRELOAD_MODULE_LOAD_START,
|
|
|
|
NODE_PERFORMANCE_MILESTONE_PRELOAD_MODULE_LOAD_END
|
|
|
|
} = perf.constants;
|
2016-03-15 16:13:52 -04:00
|
|
|
|
|
|
|
_process.setup_hrtime();
|
2017-08-07 15:53:24 -07:00
|
|
|
_process.setup_performance();
|
2016-04-05 09:17:48 -04:00
|
|
|
_process.setup_cpuUsage();
|
2017-02-22 02:03:49 -05:00
|
|
|
_process.setupMemoryUsage();
|
2016-03-15 16:13:52 -04:00
|
|
|
_process.setupKillAndExit();
|
2017-01-10 09:21:30 +00:00
|
|
|
if (global.__coverage__)
|
|
|
|
NativeModule.require('internal/process/write-coverage').setup();
|
2010-11-21 14:20:22 -08:00
|
|
|
|
2017-07-17 16:47:12 -07:00
|
|
|
NativeModule.require('internal/trace_events_async_hooks').setup();
|
2017-07-17 16:51:26 +02:00
|
|
|
NativeModule.require('internal/inspector_async_hook').setup();
|
|
|
|
|
2018-01-22 16:39:25 +08:00
|
|
|
_process.setupChannel();
|
2016-03-15 16:13:52 -04:00
|
|
|
_process.setupRawDebug();
|
2013-08-21 15:36:50 -07:00
|
|
|
|
2017-10-27 21:23:59 +03:00
|
|
|
const browserGlobals = !process._noBrowserGlobals;
|
|
|
|
if (browserGlobals) {
|
|
|
|
setupGlobalTimeouts();
|
|
|
|
setupGlobalConsole();
|
2018-01-21 17:11:47 +01:00
|
|
|
setupGlobalURL();
|
2017-10-27 21:23:59 +03:00
|
|
|
}
|
|
|
|
|
2017-03-26 19:49:33 -07:00
|
|
|
// Ensure setURLConstructor() is called before the native
|
|
|
|
// URL::ToObject() method is used.
|
|
|
|
NativeModule.require('internal/url');
|
|
|
|
|
2018-02-03 09:52:29 -07:00
|
|
|
// On OpenBSD process.execPath will be relative unless we
|
|
|
|
// get the full path before process.execPath is used.
|
|
|
|
if (process.platform === 'openbsd') {
|
|
|
|
const { realpathSync } = NativeModule.require('fs');
|
|
|
|
process.execPath = realpathSync.native(process.execPath);
|
|
|
|
}
|
|
|
|
|
2016-07-13 20:18:22 -04:00
|
|
|
Object.defineProperty(process, 'argv0', {
|
|
|
|
enumerable: true,
|
|
|
|
configurable: false,
|
|
|
|
value: process.argv[0]
|
|
|
|
});
|
2015-03-18 22:11:14 +01:00
|
|
|
process.argv[0] = process.execPath;
|
2010-01-18 10:27:27 -08:00
|
|
|
|
2017-05-28 23:28:01 -04:00
|
|
|
// Handle `--debug*` deprecation and invalidation
|
|
|
|
if (process._invalidDebug) {
|
|
|
|
process.emitWarning(
|
|
|
|
'`node --debug` and `node --debug-brk` are invalid. ' +
|
|
|
|
'Please use `node --inspect` or `node --inspect-brk` instead.',
|
|
|
|
'DeprecationWarning', 'DEP0062', startup, true);
|
|
|
|
process.exit(9);
|
|
|
|
} else if (process._deprecatedDebugBrk) {
|
|
|
|
process.emitWarning(
|
|
|
|
'`node --inspect --debug-brk` is deprecated. ' +
|
|
|
|
'Please use `node --inspect-brk` instead.',
|
|
|
|
'DeprecationWarning', 'DEP0062', startup, true);
|
|
|
|
}
|
|
|
|
|
2017-06-05 19:44:56 -05:00
|
|
|
if (process.binding('config').experimentalModules) {
|
|
|
|
process.emitWarning(
|
|
|
|
'The ESM module loader is experimental.',
|
|
|
|
'ExperimentalWarning', undefined);
|
2017-12-24 16:26:24 +01:00
|
|
|
NativeModule.require('internal/process/modules').setup();
|
2017-06-05 19:44:56 -05:00
|
|
|
}
|
|
|
|
|
2018-01-27 22:01:32 +01:00
|
|
|
{
|
|
|
|
// Install legacy getters on the `util` binding for typechecking.
|
|
|
|
// TODO(addaleax): Turn into a full runtime deprecation.
|
|
|
|
const { pendingDeprecation } = process.binding('config');
|
|
|
|
const { deprecate } = NativeModule.require('internal/util');
|
|
|
|
const utilBinding = process.binding('util');
|
|
|
|
const types = internalBinding('types');
|
|
|
|
for (const name of [
|
|
|
|
'isArrayBuffer', 'isArrayBufferView', 'isAsyncFunction',
|
|
|
|
'isDataView', 'isDate', 'isExternal', 'isMap', 'isMapIterator',
|
|
|
|
'isNativeError', 'isPromise', 'isRegExp', 'isSet', 'isSetIterator',
|
|
|
|
'isTypedArray', 'isUint8Array', 'isAnyArrayBuffer'
|
|
|
|
]) {
|
|
|
|
utilBinding[name] = pendingDeprecation ?
|
|
|
|
deprecate(types[name],
|
|
|
|
'Accessing native typechecking bindings of Node ' +
|
|
|
|
'directly is deprecated. ' +
|
|
|
|
`Please use \`util.types.${name}\` instead.`,
|
2018-03-05 18:02:26 +00:00
|
|
|
'DEP0103') :
|
2018-01-27 22:01:32 +01:00
|
|
|
types[name];
|
|
|
|
}
|
|
|
|
}
|
2017-06-05 19:44:56 -05:00
|
|
|
|
2011-03-15 10:35:49 -07:00
|
|
|
// 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() {
|
2017-08-07 15:53:24 -07:00
|
|
|
perf.markMilestone(NODE_PERFORMANCE_MILESTONE_THIRD_PARTY_MAIN_START);
|
2011-03-15 10:35:49 -07:00
|
|
|
NativeModule.require('_third_party_main');
|
2017-08-07 15:53:24 -07:00
|
|
|
perf.markMilestone(NODE_PERFORMANCE_MILESTONE_THIRD_PARTY_MAIN_END);
|
2011-03-15 10:35:49 -07:00
|
|
|
});
|
|
|
|
|
2017-03-14 14:20:38 -07:00
|
|
|
} else if (process.argv[1] === 'inspect' || process.argv[1] === 'debug') {
|
|
|
|
if (process.argv[1] === 'debug') {
|
|
|
|
process.emitWarning(
|
|
|
|
'`node debug` is deprecated. Please use `node inspect` instead.',
|
|
|
|
'DeprecationWarning', 'DEP0068');
|
|
|
|
}
|
2011-03-15 10:35:49 -07:00
|
|
|
|
2016-12-20 18:01:28 +01:00
|
|
|
// Start the debugger agent
|
2017-03-15 12:42:33 -07:00
|
|
|
process.nextTick(function() {
|
2017-10-22 12:16:48 -07:00
|
|
|
NativeModule.require('internal/deps/node-inspect/lib/_inspect').start();
|
2017-03-15 12:42:33 -07:00
|
|
|
});
|
2016-12-20 18:01:28 +01:00
|
|
|
|
2015-11-25 06:08:58 -08:00
|
|
|
} else if (process.profProcess) {
|
|
|
|
NativeModule.require('internal/v8_prof_processor');
|
|
|
|
|
2015-02-17 14:37:37 -08:00
|
|
|
} else {
|
|
|
|
// There is user code to be run
|
2015-03-13 14:57:11 -07:00
|
|
|
|
2015-03-30 10:54:59 -07:00
|
|
|
// 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) {
|
2017-08-07 15:53:24 -07:00
|
|
|
perf.markMilestone(NODE_PERFORMANCE_MILESTONE_CLUSTER_SETUP_START);
|
2016-09-17 11:07:23 +02:00
|
|
|
const cluster = NativeModule.require('cluster');
|
2015-03-30 10:54:59 -07:00
|
|
|
cluster._setupWorker();
|
2017-08-07 15:53:24 -07:00
|
|
|
perf.markMilestone(NODE_PERFORMANCE_MILESTONE_CLUSTER_SETUP_END);
|
2015-03-30 10:54:59 -07:00
|
|
|
// Make sure it's not accidentally inherited by child processes.
|
|
|
|
delete process.env.NODE_UNIQUE_ID;
|
|
|
|
}
|
|
|
|
|
2016-03-10 21:44:54 -08:00
|
|
|
if (process._eval != null && !process._forceRepl) {
|
2017-08-07 15:53:24 -07:00
|
|
|
perf.markMilestone(NODE_PERFORMANCE_MILESTONE_MODULE_LOAD_START);
|
|
|
|
perf.markMilestone(NODE_PERFORMANCE_MILESTONE_MODULE_LOAD_END);
|
2016-03-10 21:44:54 -08:00
|
|
|
// User passed '-e' or '--eval' arguments to Node without '-i' or
|
|
|
|
// '--interactive'
|
2017-08-07 15:53:24 -07:00
|
|
|
|
|
|
|
perf.markMilestone(
|
|
|
|
NODE_PERFORMANCE_MILESTONE_PRELOAD_MODULE_LOAD_START);
|
2016-03-15 16:13:52 -04:00
|
|
|
preloadModules();
|
2017-08-07 15:53:24 -07:00
|
|
|
perf.markMilestone(NODE_PERFORMANCE_MILESTONE_PRELOAD_MODULE_LOAD_END);
|
2016-04-15 02:03:12 +02:00
|
|
|
|
|
|
|
const internalModule = NativeModule.require('internal/module');
|
|
|
|
internalModule.addBuiltinLibsToObject(global);
|
2017-04-18 22:46:49 +02:00
|
|
|
evalScript('[eval]');
|
2017-05-13 12:28:18 +04:30
|
|
|
} else if (process.argv[1] && process.argv[1] !== '-') {
|
2017-08-07 15:53:24 -07:00
|
|
|
perf.markMilestone(NODE_PERFORMANCE_MILESTONE_MODULE_LOAD_START);
|
2015-02-17 14:37:37 -08:00
|
|
|
// make process.argv[1] into a full path
|
2016-09-17 11:07:23 +02:00
|
|
|
const path = NativeModule.require('path');
|
2015-02-17 14:37:37 -08:00
|
|
|
process.argv[1] = path.resolve(process.argv[1]);
|
|
|
|
|
2016-09-17 11:07:23 +02:00
|
|
|
const Module = NativeModule.require('module');
|
2015-08-17 17:33:13 -04:00
|
|
|
|
|
|
|
// check if user passed `-c` or `--check` arguments to Node.
|
|
|
|
if (process._syntax_check_only != null) {
|
2016-09-17 11:07:23 +02:00
|
|
|
const fs = NativeModule.require('fs');
|
2015-08-17 17:33:13 -04:00
|
|
|
// read the source
|
2016-09-17 11:07:23 +02:00
|
|
|
const filename = Module._resolveFilename(process.argv[1]);
|
2018-02-08 13:01:33 -05:00
|
|
|
const source = fs.readFileSync(filename, 'utf-8');
|
2017-03-05 03:05:40 -05:00
|
|
|
checkScriptSyntax(source, filename);
|
2015-08-17 17:33:13 -04:00
|
|
|
process.exit(0);
|
|
|
|
}
|
2017-08-07 15:53:24 -07:00
|
|
|
perf.markMilestone(NODE_PERFORMANCE_MILESTONE_MODULE_LOAD_END);
|
|
|
|
perf.markMilestone(
|
|
|
|
NODE_PERFORMANCE_MILESTONE_PRELOAD_MODULE_LOAD_START);
|
2016-03-15 16:13:52 -04:00
|
|
|
preloadModules();
|
2017-08-07 15:53:24 -07:00
|
|
|
perf.markMilestone(
|
|
|
|
NODE_PERFORMANCE_MILESTONE_PRELOAD_MODULE_LOAD_END);
|
2017-04-18 22:46:49 +02:00
|
|
|
Module.runMain();
|
2011-03-15 10:50:24 -07:00
|
|
|
} else {
|
2017-08-07 15:53:24 -07:00
|
|
|
perf.markMilestone(NODE_PERFORMANCE_MILESTONE_MODULE_LOAD_START);
|
|
|
|
perf.markMilestone(NODE_PERFORMANCE_MILESTONE_MODULE_LOAD_END);
|
|
|
|
perf.markMilestone(
|
|
|
|
NODE_PERFORMANCE_MILESTONE_PRELOAD_MODULE_LOAD_START);
|
2016-03-15 16:13:52 -04:00
|
|
|
preloadModules();
|
2017-08-07 15:53:24 -07:00
|
|
|
perf.markMilestone(
|
|
|
|
NODE_PERFORMANCE_MILESTONE_PRELOAD_MODULE_LOAD_END);
|
2015-02-17 14:37:37 -08:00
|
|
|
// If -i or --interactive were passed, or stdin is a TTY.
|
|
|
|
if (process._forceRepl || NativeModule.require('tty').isatty(0)) {
|
|
|
|
// REPL
|
2016-09-17 11:07:23 +02:00
|
|
|
const cliRepl = NativeModule.require('internal/repl');
|
2015-05-04 08:56:14 -07:00
|
|
|
cliRepl.createInternalRepl(process.env, function(err, repl) {
|
2015-04-23 00:35:53 -07:00
|
|
|
if (err) {
|
|
|
|
throw err;
|
|
|
|
}
|
|
|
|
repl.on('exit', function() {
|
|
|
|
if (repl._flushing) {
|
|
|
|
repl.pause();
|
|
|
|
return repl.once('flushHistory', function() {
|
|
|
|
process.exit();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
process.exit();
|
|
|
|
});
|
2015-02-17 14:37:37 -08:00
|
|
|
});
|
2016-03-10 21:44:54 -08:00
|
|
|
|
|
|
|
if (process._eval != null) {
|
|
|
|
// User passed '-e' or '--eval'
|
|
|
|
evalScript('[eval]');
|
|
|
|
}
|
2015-02-17 14:37:37 -08:00
|
|
|
} else {
|
|
|
|
// Read all of stdin - execute it.
|
|
|
|
process.stdin.setEncoding('utf8');
|
|
|
|
|
2018-02-08 13:01:33 -05:00
|
|
|
let code = '';
|
2015-02-17 14:37:37 -08:00
|
|
|
process.stdin.on('data', function(d) {
|
|
|
|
code += d;
|
|
|
|
});
|
|
|
|
|
|
|
|
process.stdin.on('end', function() {
|
2017-03-05 03:05:40 -05:00
|
|
|
if (process._syntax_check_only != null) {
|
|
|
|
checkScriptSyntax(code, '[stdin]');
|
|
|
|
} else {
|
|
|
|
process._eval = code;
|
|
|
|
evalScript('[stdin]');
|
|
|
|
}
|
2015-02-17 14:37:37 -08:00
|
|
|
});
|
|
|
|
}
|
2011-03-15 10:50:24 -07:00
|
|
|
}
|
2010-09-01 05:01:38 -06:00
|
|
|
}
|
2017-08-07 15:53:24 -07:00
|
|
|
perf.markMilestone(NODE_PERFORMANCE_MILESTONE_BOOTSTRAP_COMPLETE);
|
2011-01-24 23:15:10 +01:00
|
|
|
}
|
2010-08-06 12:31:41 -07:00
|
|
|
|
2016-03-15 16:13:52 -04:00
|
|
|
function setupProcessObject() {
|
2015-11-10 02:58:51 -07:00
|
|
|
process._setupProcessObject(pushValueToArray);
|
2015-10-14 14:58:52 -06:00
|
|
|
|
2015-11-10 02:58:51 -07:00
|
|
|
function pushValueToArray() {
|
2015-10-14 14:58:52 -06:00
|
|
|
for (var i = 0; i < arguments.length; i++)
|
|
|
|
this.push(arguments[i]);
|
|
|
|
}
|
2016-03-15 16:13:52 -04:00
|
|
|
}
|
2015-11-11 00:15:15 -07:00
|
|
|
|
2016-03-15 16:13:52 -04:00
|
|
|
function setupGlobalVariables() {
|
2016-10-25 22:13:24 +02:00
|
|
|
Object.defineProperty(global, Symbol.toStringTag, {
|
|
|
|
value: 'global',
|
|
|
|
writable: false,
|
|
|
|
enumerable: false,
|
|
|
|
configurable: true
|
|
|
|
});
|
2011-01-24 23:15:10 +01:00
|
|
|
global.process = process;
|
2015-05-30 03:07:36 +08:00
|
|
|
const util = NativeModule.require('util');
|
|
|
|
|
2017-02-27 09:53:26 -08:00
|
|
|
function makeGetter(name) {
|
|
|
|
return util.deprecate(function() {
|
2015-05-30 03:07:36 +08:00
|
|
|
return this;
|
2016-12-04 12:47:01 -08:00
|
|
|
}, `'${name}' is deprecated, use 'global'`, 'DEP0016');
|
2017-02-27 09:53:26 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
function makeSetter(name) {
|
|
|
|
return util.deprecate(function(value) {
|
2015-05-30 03:07:36 +08:00
|
|
|
Object.defineProperty(this, name, {
|
|
|
|
configurable: true,
|
|
|
|
writable: true,
|
|
|
|
enumerable: true,
|
|
|
|
value: value
|
|
|
|
});
|
2016-12-04 12:47:01 -08:00
|
|
|
}, `'${name}' is deprecated, use 'global'`, 'DEP0016');
|
2017-02-27 09:53:26 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
Object.defineProperties(global, {
|
|
|
|
GLOBAL: {
|
|
|
|
configurable: true,
|
|
|
|
get: makeGetter('GLOBAL'),
|
|
|
|
set: makeSetter('GLOBAL')
|
|
|
|
},
|
|
|
|
root: {
|
|
|
|
configurable: true,
|
|
|
|
get: makeGetter('root'),
|
|
|
|
set: makeSetter('root')
|
|
|
|
}
|
2015-05-30 03:07:36 +08:00
|
|
|
});
|
|
|
|
|
2017-10-21 23:25:59 -07:00
|
|
|
// This, as side effect, removes `setupBufferJS` from the buffer binding,
|
|
|
|
// and exposes it on `internal/buffer`.
|
|
|
|
NativeModule.require('internal/buffer');
|
|
|
|
|
2011-01-24 23:15:10 +01:00
|
|
|
global.Buffer = NativeModule.require('buffer').Buffer;
|
2013-02-06 17:26:18 -08:00
|
|
|
process.domain = null;
|
|
|
|
process._exiting = false;
|
2016-03-15 16:13:52 -04:00
|
|
|
}
|
2010-11-16 15:44:06 +01:00
|
|
|
|
2016-03-15 16:13:52 -04:00
|
|
|
function setupGlobalTimeouts() {
|
2015-03-26 23:56:26 +01:00
|
|
|
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;
|
2016-03-15 16:13:52 -04:00
|
|
|
}
|
2010-08-06 12:31:41 -07:00
|
|
|
|
2016-03-15 16:13:52 -04:00
|
|
|
function setupGlobalConsole() {
|
2017-04-25 14:55:55 -07:00
|
|
|
const originalConsole = global.console;
|
2017-08-28 21:48:54 -03:00
|
|
|
const Module = NativeModule.require('module');
|
|
|
|
// Setup Node.js global.console
|
|
|
|
const wrappedConsole = NativeModule.require('console');
|
2016-05-14 22:29:19 -07:00
|
|
|
Object.defineProperty(global, 'console', {
|
|
|
|
configurable: true,
|
2017-12-16 04:29:40 -02:00
|
|
|
enumerable: false,
|
|
|
|
value: wrappedConsole
|
2011-07-27 16:36:03 -07:00
|
|
|
});
|
2017-08-28 21:48:54 -03:00
|
|
|
setupInspector(originalConsole, wrappedConsole, Module);
|
2016-03-15 16:13:52 -04:00
|
|
|
}
|
2010-08-06 12:31:41 -07:00
|
|
|
|
2018-01-21 17:11:47 +01:00
|
|
|
function setupGlobalURL() {
|
|
|
|
const { URL, URLSearchParams } = NativeModule.require('internal/url');
|
|
|
|
Object.defineProperties(global, {
|
|
|
|
URL: {
|
|
|
|
value: URL,
|
|
|
|
writable: true,
|
|
|
|
configurable: true,
|
|
|
|
enumerable: false
|
|
|
|
},
|
|
|
|
URLSearchParams: {
|
|
|
|
value: URLSearchParams,
|
|
|
|
writable: true,
|
|
|
|
configurable: true,
|
|
|
|
enumerable: false
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2017-08-28 21:48:54 -03:00
|
|
|
function setupInspector(originalConsole, wrappedConsole, Module) {
|
2017-09-25 09:10:53 +02:00
|
|
|
if (!process.config.variables.v8_enable_inspector) {
|
2017-08-28 21:48:54 -03:00
|
|
|
return;
|
2017-08-02 12:19:42 +08:00
|
|
|
}
|
2017-09-25 09:10:53 +02:00
|
|
|
const { addCommandLineAPI, consoleCall } = process.binding('inspector');
|
2017-08-28 21:48:54 -03:00
|
|
|
// Setup inspector command line API
|
|
|
|
const { makeRequireFunction } = NativeModule.require('internal/module');
|
|
|
|
const path = NativeModule.require('path');
|
|
|
|
const cwd = tryGetCwd(path);
|
|
|
|
|
|
|
|
const consoleAPIModule = new Module('<inspector console>');
|
|
|
|
consoleAPIModule.paths =
|
|
|
|
Module._nodeModulePaths(cwd).concat(Module.globalPaths);
|
|
|
|
addCommandLineAPI('require', makeRequireFunction(consoleAPIModule));
|
2016-09-17 11:07:23 +02:00
|
|
|
const config = {};
|
2017-04-25 14:55:55 -07:00
|
|
|
for (const key of Object.keys(wrappedConsole)) {
|
2017-08-28 21:48:54 -03:00
|
|
|
if (!originalConsole.hasOwnProperty(key))
|
2016-08-05 13:45:08 -07:00
|
|
|
continue;
|
2017-04-25 14:55:55 -07:00
|
|
|
// If global console has the same method as inspector console,
|
2016-08-05 13:45:08 -07:00
|
|
|
// then wrap these two methods into one. Native wrapper will preserve
|
|
|
|
// the original stack.
|
2017-08-28 21:48:54 -03:00
|
|
|
wrappedConsole[key] = consoleCall.bind(wrappedConsole,
|
|
|
|
originalConsole[key],
|
|
|
|
wrappedConsole[key],
|
|
|
|
config);
|
2016-08-05 13:45:08 -07:00
|
|
|
}
|
2017-08-28 21:48:54 -03:00
|
|
|
for (const key of Object.keys(originalConsole)) {
|
2017-04-25 14:55:55 -07:00
|
|
|
if (wrappedConsole.hasOwnProperty(key))
|
2016-08-05 13:45:08 -07:00
|
|
|
continue;
|
2017-08-28 21:48:54 -03:00
|
|
|
wrappedConsole[key] = originalConsole[key];
|
2016-08-05 13:45:08 -07:00
|
|
|
}
|
2016-09-28 13:20:54 -07:00
|
|
|
}
|
|
|
|
|
2017-12-23 10:39:52 -05:00
|
|
|
function noop() {}
|
|
|
|
|
2016-03-15 16:13:52 -04:00
|
|
|
function setupProcessFatal() {
|
2018-02-11 16:35:59 -05:00
|
|
|
const {
|
|
|
|
executionAsyncId,
|
|
|
|
clearDefaultTriggerAsyncId,
|
|
|
|
clearAsyncIdStack,
|
|
|
|
hasAsyncIdStack,
|
|
|
|
afterHooksExist,
|
|
|
|
emitAfter
|
|
|
|
} = NativeModule.require('internal/async_hooks');
|
2015-02-22 14:54:25 -08:00
|
|
|
|
2012-12-26 12:28:33 -08:00
|
|
|
process._fatalException = function(er) {
|
2018-02-11 16:35:59 -05:00
|
|
|
// It's possible that defaultTriggerAsyncId was set for a constructor
|
2017-11-22 13:54:38 +01:00
|
|
|
// call that threw and was never cleared. So clear it now.
|
2018-02-11 16:35:59 -05:00
|
|
|
clearDefaultTriggerAsyncId();
|
2017-03-10 06:17:42 -07:00
|
|
|
|
2017-11-20 19:57:20 +01:00
|
|
|
if (exceptionHandlerState.captureFn !== null) {
|
|
|
|
exceptionHandlerState.captureFn(er);
|
2017-12-23 10:39:52 -05:00
|
|
|
} else if (!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
|
2012-12-29 16:49:18 -08:00
|
|
|
try {
|
2013-02-06 17:26:18 -08:00
|
|
|
if (!process._exiting) {
|
|
|
|
process._exiting = true;
|
2013-09-06 17:47:56 -07:00
|
|
|
process.emit('exit', 1);
|
2013-02-06 17:26:18 -08:00
|
|
|
}
|
2012-12-29 16:49:18 -08:00
|
|
|
} catch (er) {
|
|
|
|
// nothing to be done about it at this point.
|
|
|
|
}
|
2018-02-26 15:46:50 +01:00
|
|
|
try {
|
|
|
|
const { kExpandStackSymbol } = NativeModule.require('internal/util');
|
|
|
|
if (typeof er[kExpandStackSymbol] === 'function')
|
|
|
|
er[kExpandStackSymbol]();
|
|
|
|
} catch (er) {}
|
2017-12-23 10:39:52 -05:00
|
|
|
return false;
|
|
|
|
}
|
2013-08-21 16:12:17 -07:00
|
|
|
|
2017-12-23 10:39:52 -05:00
|
|
|
// If we handled an error, then make sure any ticks get processed
|
|
|
|
// by ensuring that the next Immediate cycle isn't empty
|
|
|
|
NativeModule.require('timers').setImmediate(noop);
|
|
|
|
|
|
|
|
// Emit the after() hooks now that the exception has been handled.
|
2018-02-11 16:35:59 -05:00
|
|
|
if (afterHooksExist()) {
|
2017-12-23 10:39:52 -05:00
|
|
|
do {
|
2018-02-11 16:35:59 -05:00
|
|
|
emitAfter(executionAsyncId());
|
|
|
|
} while (hasAsyncIdStack());
|
2017-12-23 10:39:52 -05:00
|
|
|
// Or completely empty the id stack.
|
2013-08-21 16:12:17 -07:00
|
|
|
} else {
|
2017-12-23 10:39:52 -05:00
|
|
|
clearAsyncIdStack();
|
2013-08-21 16:12:17 -07:00
|
|
|
}
|
|
|
|
|
2017-12-23 10:39:52 -05:00
|
|
|
return true;
|
2012-12-26 12:28:33 -08:00
|
|
|
};
|
2016-03-15 16:13:52 -04:00
|
|
|
}
|
2011-01-12 22:05:45 +01:00
|
|
|
|
2017-11-24 00:13:44 +01:00
|
|
|
function setupV8() {
|
|
|
|
// Warm up the map and set iterator preview functions. V8 compiles
|
|
|
|
// functions lazily (unless --nolazy is set) so we need to do this
|
|
|
|
// before we turn off --allow_natives_syntax again.
|
|
|
|
const v8 = NativeModule.require('internal/v8');
|
|
|
|
v8.previewMapIterator(new Map().entries(), 1);
|
|
|
|
v8.previewSetIterator(new Set().entries(), 1);
|
|
|
|
// Disable --allow_natives_syntax again unless it was explicitly
|
|
|
|
// specified on the command line.
|
|
|
|
const re = /^--allow[-_]natives[-_]syntax$/;
|
|
|
|
if (!process.execArgv.some((s) => re.test(s)))
|
|
|
|
process.binding('v8').setFlagsFromString('--noallow_natives_syntax');
|
|
|
|
}
|
|
|
|
|
2016-10-24 11:24:21 -07:00
|
|
|
function setupProcessICUVersions() {
|
|
|
|
const icu = process.binding('config').hasIntl ?
|
|
|
|
process.binding('icu') : undefined;
|
|
|
|
if (!icu) return; // no Intl/ICU: nothing to add here.
|
|
|
|
// With no argument, getVersion() returns a comma separated list
|
|
|
|
// of possible types.
|
|
|
|
const versionTypes = icu.getVersion().split(',');
|
2017-02-27 09:53:26 -08:00
|
|
|
|
|
|
|
for (var n = 0; n < versionTypes.length; n++) {
|
2018-02-08 13:01:33 -05:00
|
|
|
const name = versionTypes[n];
|
2017-05-26 01:38:29 +08:00
|
|
|
const version = icu.getVersion(name);
|
2016-10-24 11:24:21 -07:00
|
|
|
Object.defineProperty(process.versions, name, {
|
2017-05-26 01:38:29 +08:00
|
|
|
writable: false,
|
2016-10-24 11:24:21 -07:00
|
|
|
enumerable: true,
|
2017-05-26 01:38:29 +08:00
|
|
|
value: version
|
2016-10-24 11:24:21 -07:00
|
|
|
});
|
2017-02-27 09:53:26 -08:00
|
|
|
}
|
2016-10-24 11:24:21 -07:00
|
|
|
}
|
|
|
|
|
2016-04-07 10:04:47 -04:00
|
|
|
function tryGetCwd(path) {
|
2015-03-18 22:11:14 +01:00
|
|
|
try {
|
2016-08-11 10:47:58 +08:00
|
|
|
return process.cwd();
|
|
|
|
} catch (ex) {
|
|
|
|
// 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?
|
|
|
|
return path.dirname(process.execPath);
|
2015-03-18 22:11:14 +01:00
|
|
|
}
|
2016-04-07 10:04:47 -04:00
|
|
|
}
|
|
|
|
|
2017-08-01 15:28:51 -07:00
|
|
|
function wrapForBreakOnFirstLine(source) {
|
|
|
|
if (!process._breakFirstLine)
|
|
|
|
return source;
|
|
|
|
const fn = `function() {\n\n${source};\n\n}`;
|
|
|
|
return `process.binding('inspector').callAndPauseOnStart(${fn}, {})`;
|
|
|
|
}
|
|
|
|
|
2016-04-07 10:04:47 -04:00
|
|
|
function evalScript(name) {
|
|
|
|
const Module = NativeModule.require('module');
|
|
|
|
const path = NativeModule.require('path');
|
|
|
|
const cwd = tryGetCwd(path);
|
2012-04-24 01:34:17 -07:00
|
|
|
|
2016-04-07 10:04:47 -04:00
|
|
|
const module = new Module(name);
|
2012-04-24 01:34:17 -07:00
|
|
|
module.filename = path.join(cwd, name);
|
|
|
|
module.paths = Module._nodeModulePaths(cwd);
|
2017-08-01 15:28:51 -07:00
|
|
|
const body = wrapForBreakOnFirstLine(process._eval);
|
2016-04-07 10:04:47 -04:00
|
|
|
const 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`;
|
2017-03-21 11:30:59 +01:00
|
|
|
const result = module._compile(script, `${name}-wrapper`);
|
|
|
|
if (process._print_eval) console.log(result);
|
2017-03-26 16:01:31 +01:00
|
|
|
// Handle any nextTicks added in the first tick of the program.
|
2017-03-21 11:30:59 +01:00
|
|
|
process._tickCallback();
|
2012-04-24 01:34:17 -07:00
|
|
|
}
|
|
|
|
|
2015-05-14 00:00:57 +09:00
|
|
|
// Load preload modules
|
2016-03-15 16:13:52 -04:00
|
|
|
function preloadModules() {
|
2015-05-14 00:00:57 +09:00
|
|
|
if (process._preload_modules) {
|
2015-05-27 10:11:30 -07:00
|
|
|
NativeModule.require('module')._preloadModules(process._preload_modules);
|
2015-05-14 00:00:57 +09:00
|
|
|
}
|
2016-03-15 16:13:52 -04:00
|
|
|
}
|
2015-05-14 00:00:57 +09:00
|
|
|
|
2017-03-05 03:05:40 -05:00
|
|
|
function checkScriptSyntax(source, filename) {
|
|
|
|
const Module = NativeModule.require('module');
|
|
|
|
const vm = NativeModule.require('vm');
|
|
|
|
const internalModule = NativeModule.require('internal/module');
|
|
|
|
|
2017-04-04 11:58:15 +02:00
|
|
|
// remove Shebang
|
|
|
|
source = internalModule.stripShebang(source);
|
|
|
|
// remove BOM
|
|
|
|
source = internalModule.stripBOM(source);
|
2017-03-05 03:05:40 -05:00
|
|
|
// wrap it
|
|
|
|
source = Module.wrap(source);
|
|
|
|
// compile the script, this will throw if it fails
|
2017-07-10 20:55:21 -04:00
|
|
|
new vm.Script(source, { displayErrors: true, filename });
|
2017-03-05 03:05:40 -05:00
|
|
|
}
|
|
|
|
|
2011-01-24 23:15:10 +01:00
|
|
|
startup();
|
2010-03-11 22:05:09 -08:00
|
|
|
});
|