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>
This commit is contained in:
Родитель
2c672891e1
Коммит
015cef25eb
|
@ -0,0 +1,186 @@
|
|||
'use strict';
|
||||
|
||||
var _lazyConstants = null;
|
||||
|
||||
function lazyConstants() {
|
||||
if (!_lazyConstants) {
|
||||
_lazyConstants = process.binding('constants');
|
||||
}
|
||||
return _lazyConstants;
|
||||
}
|
||||
|
||||
exports.setup_hrtime = setup_hrtime;
|
||||
exports.setupConfig = setupConfig;
|
||||
exports.setupKillAndExit = setupKillAndExit;
|
||||
exports.setupSignalHandlers = setupSignalHandlers;
|
||||
exports.setupChannel = setupChannel;
|
||||
exports.setupRawDebug = setupRawDebug;
|
||||
|
||||
|
||||
const assert = process.assert = function(x, msg) {
|
||||
if (!x) throw new Error(msg || 'assertion error');
|
||||
};
|
||||
|
||||
|
||||
function setup_hrtime() {
|
||||
const _hrtime = process.hrtime;
|
||||
const hrValues = new Uint32Array(3);
|
||||
|
||||
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]
|
||||
];
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
function setupConfig(_source) {
|
||||
// NativeModule._source
|
||||
// used for `process.config`, but not a real module
|
||||
var config = _source.config;
|
||||
delete _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;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function setupKillAndExit() {
|
||||
|
||||
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 (lazyConstants()[sig] &&
|
||||
sig.slice(0, 3) === 'SIG') {
|
||||
err = process._kill(pid, lazyConstants()[sig]);
|
||||
} else {
|
||||
throw new Error(`Unknown signal: ${sig}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (err) {
|
||||
var errnoException = require('util')._errnoException;
|
||||
throw errnoException(err, 'kill');
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
function setupSignalHandlers() {
|
||||
// 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' &&
|
||||
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 = lazyConstants()[type];
|
||||
var err = wrap.start(signum);
|
||||
if (err) {
|
||||
wrap.close();
|
||||
var errnoException = 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];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function setupChannel() {
|
||||
// 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 = 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function setupRawDebug() {
|
||||
var format = require('util').format;
|
||||
var rawDebug = process._rawDebug;
|
||||
process._rawDebug = function() {
|
||||
rawDebug(format.apply(null, arguments));
|
||||
};
|
||||
}
|
|
@ -0,0 +1,157 @@
|
|||
'use strict';
|
||||
|
||||
exports.setup = setupNextTick;
|
||||
|
||||
function setupNextTick() {
|
||||
const promises = require('internal/process/promises');
|
||||
const emitPendingUnhandledRejections = promises.setup(scheduleMicrotasks);
|
||||
var nextTickQueue = [];
|
||||
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]++;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
'use strict';
|
||||
|
||||
const promiseRejectEvent = process._promiseRejectEvent;
|
||||
const hasBeenNotifiedProperty = new WeakMap();
|
||||
const pendingUnhandledRejections = [];
|
||||
|
||||
exports.setup = setupPromises;
|
||||
|
||||
function setupPromises(scheduleMicrotasks) {
|
||||
process._setupPromises(function(event, promise, reason) {
|
||||
if (event === promiseRejectEvent.unhandled)
|
||||
unhandledRejection(promise, reason);
|
||||
else if (event === promiseRejectEvent.handled)
|
||||
rejectionHandled(promise);
|
||||
else
|
||||
require('assert').fail('unexpected 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);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
function addPendingUnhandledRejection(promise, reason) {
|
||||
pendingUnhandledRejections.push(promise, reason);
|
||||
scheduleMicrotasks();
|
||||
}
|
||||
|
||||
return emitPendingUnhandledRejections;
|
||||
}
|
|
@ -0,0 +1,161 @@
|
|||
'use strict';
|
||||
|
||||
exports.setup = setupStdio;
|
||||
|
||||
function setupStdio() {
|
||||
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 = require('tty');
|
||||
stdin = new tty.ReadStream(fd, {
|
||||
highWaterMark: 0,
|
||||
readable: true,
|
||||
writable: false
|
||||
});
|
||||
break;
|
||||
|
||||
case 'FILE':
|
||||
var fs = require('fs');
|
||||
stdin = new fs.ReadStream(null, { fd: fd, autoClose: false });
|
||||
break;
|
||||
|
||||
case 'PIPE':
|
||||
case 'TCP':
|
||||
var net = 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;
|
||||
};
|
||||
}
|
||||
|
||||
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 = require('tty');
|
||||
stream = new tty.WriteStream(fd);
|
||||
stream._type = 'tty';
|
||||
break;
|
||||
|
||||
case 'FILE':
|
||||
var fs = require('fs');
|
||||
stream = new fs.SyncWriteStream(fd, { autoClose: false });
|
||||
stream._type = 'fs';
|
||||
break;
|
||||
|
||||
case 'PIPE':
|
||||
case 'TCP':
|
||||
var net = 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;
|
||||
}
|
4
node.gyp
4
node.gyp
|
@ -75,6 +75,10 @@
|
|||
'lib/internal/linkedlist.js',
|
||||
'lib/internal/net.js',
|
||||
'lib/internal/module.js',
|
||||
'lib/internal/process/next_tick.js',
|
||||
'lib/internal/process/promises.js',
|
||||
'lib/internal/process/stdio.js',
|
||||
'lib/internal/process.js',
|
||||
'lib/internal/readline.js',
|
||||
'lib/internal/repl.js',
|
||||
'lib/internal/socket_list.js',
|
||||
|
|
601
src/node.js
601
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
|
||||
|
|
|
@ -7,8 +7,8 @@ SyntaxError: Strict mode code may not include a with statement
|
|||
at Object.<anonymous> ([eval]-wrapper:*:*)
|
||||
at Module._compile (module.js:*:*)
|
||||
at node.js:*:*
|
||||
at _combinedTickCallback (node.js:*:*)
|
||||
at process._tickCallback (node.js:*:*)
|
||||
at _combinedTickCallback (internal/process/next_tick.js:*:*)
|
||||
at process._tickCallback (internal/process/next_tick.js:*:*)
|
||||
42
|
||||
42
|
||||
[eval]:1
|
||||
|
@ -20,8 +20,8 @@ Error: hello
|
|||
at Object.<anonymous> ([eval]-wrapper:*:*)
|
||||
at Module._compile (module.js:*:*)
|
||||
at node.js:*:*
|
||||
at _combinedTickCallback (node.js:*:*)
|
||||
at process._tickCallback (node.js:*:*)
|
||||
at _combinedTickCallback (internal/process/next_tick.js:*:*)
|
||||
at process._tickCallback (internal/process/next_tick.js:*:*)
|
||||
[eval]:1
|
||||
throw new Error("hello")
|
||||
^
|
||||
|
@ -31,8 +31,8 @@ Error: hello
|
|||
at Object.<anonymous> ([eval]-wrapper:*:*)
|
||||
at Module._compile (module.js:*:*)
|
||||
at node.js:*:*
|
||||
at _combinedTickCallback (node.js:*:*)
|
||||
at process._tickCallback (node.js:*:*)
|
||||
at _combinedTickCallback (internal/process/next_tick.js:*:*)
|
||||
at process._tickCallback (internal/process/next_tick.js:*:*)
|
||||
100
|
||||
[eval]:1
|
||||
var x = 100; y = x;
|
||||
|
@ -43,8 +43,8 @@ ReferenceError: y is not defined
|
|||
at Object.<anonymous> ([eval]-wrapper:*:*)
|
||||
at Module._compile (module.js:*:*)
|
||||
at node.js:*:*
|
||||
at _combinedTickCallback (node.js:*:*)
|
||||
at process._tickCallback (node.js:*:*)
|
||||
at _combinedTickCallback (internal/process/next_tick.js:*:*)
|
||||
at process._tickCallback (internal/process/next_tick.js:*:*)
|
||||
[eval]:1
|
||||
var ______________________________________________; throw 10
|
||||
^
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
^
|
||||
ReferenceError: undefined_reference_error_maker is not defined
|
||||
at *test*message*nexttick_throw.js:*:*
|
||||
at _combinedTickCallback (node.js:*:*)
|
||||
at process._tickCallback (node.js:*:*)
|
||||
at _combinedTickCallback (internal/process/next_tick.js:*:*)
|
||||
at process._tickCallback (internal/process/next_tick.js:*:*)
|
||||
at Function.Module.runMain (module.js:*:*)
|
||||
at startup (node.js:*:*)
|
||||
at node.js:*:*
|
||||
|
|
|
@ -8,8 +8,8 @@ SyntaxError: Strict mode code may not include a with statement
|
|||
at Object.<anonymous> ([stdin]-wrapper:*:*)
|
||||
at Module._compile (module.js:*:*)
|
||||
at node.js:*:*
|
||||
at _combinedTickCallback (node.js:*:*)
|
||||
at process._tickCallback (node.js:*:*)
|
||||
at _combinedTickCallback (internal/process/next_tick.js:*:*)
|
||||
at process._tickCallback (internal/process/next_tick.js:*:*)
|
||||
42
|
||||
42
|
||||
|
||||
|
@ -22,8 +22,8 @@ Error: hello
|
|||
at Object.<anonymous> ([stdin]-wrapper:*:*)
|
||||
at Module._compile (module.js:*:*)
|
||||
at node.js:*:*
|
||||
at _combinedTickCallback (node.js:*:*)
|
||||
at process._tickCallback (node.js:*:*)
|
||||
at _combinedTickCallback (internal/process/next_tick.js:*:*)
|
||||
at process._tickCallback (internal/process/next_tick.js:*:*)
|
||||
|
||||
[stdin]:1
|
||||
throw new Error("hello")
|
||||
|
@ -34,8 +34,8 @@ Error: hello
|
|||
at Object.<anonymous> ([stdin]-wrapper:*:*)
|
||||
at Module._compile (module.js:*:*)
|
||||
at node.js:*:*
|
||||
at _combinedTickCallback (node.js:*:*)
|
||||
at process._tickCallback (node.js:*:*)
|
||||
at _combinedTickCallback (internal/process/next_tick.js:*:*)
|
||||
at process._tickCallback (internal/process/next_tick.js:*:*)
|
||||
100
|
||||
|
||||
[stdin]:1
|
||||
|
@ -47,8 +47,8 @@ ReferenceError: y is not defined
|
|||
at Object.<anonymous> ([stdin]-wrapper:*:*)
|
||||
at Module._compile (module.js:*:*)
|
||||
at node.js:*:*
|
||||
at _combinedTickCallback (node.js:*:*)
|
||||
at process._tickCallback (node.js:*:*)
|
||||
at _combinedTickCallback (internal/process/next_tick.js:*:*)
|
||||
at process._tickCallback (internal/process/next_tick.js:*:*)
|
||||
|
||||
[stdin]:1
|
||||
var ______________________________________________; throw 10
|
||||
|
|
Загрузка…
Ссылка в новой задаче