summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorZijian Liu <Lxxyxzj@gmail.com>2020-11-26 03:32:46 +0800
committerNode.js GitHub Bot <github-bot@iojs.org>2020-12-03 21:57:17 +0000
commitf7dd330ba0e7bfa97fad50000a5499faffcd6320 (patch)
tree82aa20d7e1c2a50cf1cebf3af8003b355f792951 /lib
parenta897a25d1d5d8983d915b6cd9aedfdd72a603805 (diff)
downloadios-node-v8-f7dd330ba0e7bfa97fad50000a5499faffcd6320.tar.gz
ios-node-v8-f7dd330ba0e7bfa97fad50000a5499faffcd6320.tar.bz2
ios-node-v8-f7dd330ba0e7bfa97fad50000a5499faffcd6320.zip
child_process: refactor to use more primordials
PR-URL: https://github.com/nodejs/node/pull/36269 Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/child_process.js77
-rw-r--r--lib/internal/child_process.js58
2 files changed, 81 insertions, 54 deletions
diff --git a/lib/child_process.js b/lib/child_process.js
index 24c5e809ad..a39710b34a 100644
--- a/lib/child_process.js
+++ b/lib/child_process.js
@@ -23,13 +23,25 @@
const {
ArrayIsArray,
+ ArrayPrototypeFilter,
+ ArrayPrototypeIncludes,
+ ArrayPrototypeJoin,
+ ArrayPrototypeLastIndexOf,
+ ArrayPrototypePush,
+ ArrayPrototypeSlice,
+ ArrayPrototypeSort,
+ ArrayPrototypeSplice,
+ ArrayPrototypeUnshift,
Error,
NumberIsInteger,
ObjectAssign,
ObjectDefineProperty,
ObjectPrototypeHasOwnProperty,
Promise,
- Set,
+ RegExpPrototypeTest,
+ SafeSet,
+ StringPrototypeSlice,
+ StringPrototypeToUpperCase,
} = primordials;
const {
@@ -94,15 +106,15 @@ function fork(modulePath /* , args, options */) {
execArgv = options.execArgv || process.execArgv;
if (execArgv === process.execArgv && process._eval != null) {
- const index = execArgv.lastIndexOf(process._eval);
+ const index = ArrayPrototypeLastIndexOf(execArgv, process._eval);
if (index > 0) {
// Remove the -e switch to avoid fork bombing ourselves.
- execArgv = execArgv.slice();
- execArgv.splice(index - 1, 2);
+ execArgv = ArrayPrototypeSlice(execArgv);
+ ArrayPrototypeSplice(execArgv, index - 1, 2);
}
}
- args = execArgv.concat([modulePath], args);
+ args = [...execArgv, modulePath, ...args];
if (typeof options.stdio === 'string') {
options.stdio = stdioStringToArray(options.stdio, 'ipc');
@@ -112,7 +124,7 @@ function fork(modulePath /* , args, options */) {
options.stdio = stdioStringToArray(
options.silent ? 'pipe' : 'inherit',
'ipc');
- } else if (!options.stdio.includes('ipc')) {
+ } else if (!ArrayPrototypeIncludes(options.stdio, 'ipc')) {
throw new ERR_CHILD_PROCESS_IPC_REQUIRED('options.stdio');
}
@@ -282,7 +294,7 @@ function execFile(file /* , args, options, callback */) {
child.stdout &&
child.stdout.readableEncoding
)) {
- stdout = _stdout.join('');
+ stdout = ArrayPrototypeJoin(_stdout, '');
} else {
stdout = Buffer.concat(_stdout);
}
@@ -291,7 +303,7 @@ function execFile(file /* , args, options, callback */) {
child.stderr &&
child.stderr.readableEncoding
)) {
- stderr = _stderr.join('');
+ stderr = ArrayPrototypeJoin(_stderr, '');
} else {
stderr = Buffer.concat(_stderr);
}
@@ -302,7 +314,7 @@ function execFile(file /* , args, options, callback */) {
}
if (args.length !== 0)
- cmd += ` ${args.join(' ')}`;
+ cmd += ` ${ArrayPrototypeJoin(args, ' ')}`;
if (!ex) {
// eslint-disable-next-line no-restricted-syntax
@@ -360,16 +372,18 @@ function execFile(file /* , args, options, callback */) {
const length = encoding ?
Buffer.byteLength(chunk, encoding) :
chunk.length;
+ const slice = encoding ? StringPrototypeSlice :
+ (buf, ...args) => buf.slice(...args);
stdoutLen += length;
if (stdoutLen > options.maxBuffer) {
const truncatedLen = options.maxBuffer - (stdoutLen - length);
- _stdout.push(chunk.slice(0, truncatedLen));
+ ArrayPrototypePush(_stdout, slice(chunk, 0, truncatedLen));
ex = new ERR_CHILD_PROCESS_STDIO_MAXBUFFER('stdout');
kill();
} else {
- _stdout.push(chunk);
+ ArrayPrototypePush(_stdout, chunk);
}
});
}
@@ -387,7 +401,8 @@ function execFile(file /* , args, options, callback */) {
if (stderrLen > options.maxBuffer) {
const truncatedLen = options.maxBuffer - (stderrLen - length);
- _stderr.push(chunk.slice(0, truncatedLen));
+ ArrayPrototypePush(_stderr,
+ chunk.slice(0, truncatedLen));
ex = new ERR_CHILD_PROCESS_STDIO_MAXBUFFER('stderr');
kill();
@@ -415,7 +430,7 @@ function normalizeSpawnArguments(file, args, options) {
throw new ERR_INVALID_ARG_VALUE('file', file, 'cannot be empty');
if (ArrayIsArray(args)) {
- args = args.slice(0);
+ args = ArrayPrototypeSlice(args);
} else if (args == null) {
args = [];
} else if (typeof args !== 'object') {
@@ -484,7 +499,7 @@ function normalizeSpawnArguments(file, args, options) {
}
if (options.shell) {
- const command = [file].concat(args).join(' ');
+ const command = ArrayPrototypeJoin([file, ...args], ' ');
// Set the shell, switches, and commands.
if (process.platform === 'win32') {
if (typeof options.shell === 'string')
@@ -492,7 +507,7 @@ function normalizeSpawnArguments(file, args, options) {
else
file = process.env.comspec || 'cmd.exe';
// '/d /s /c' is used only for cmd.exe.
- if (/^(?:.*\\)?cmd(?:\.exe)?$/i.test(file)) {
+ if (RegExpPrototypeTest(/^(?:.*\\)?cmd(?:\.exe)?$/i, file)) {
args = ['/d', '/s', '/c', `"${command}"`];
windowsVerbatimArguments = true;
} else {
@@ -510,9 +525,9 @@ function normalizeSpawnArguments(file, args, options) {
}
if (typeof options.argv0 === 'string') {
- args.unshift(options.argv0);
+ ArrayPrototypeUnshift(args, options.argv0);
} else {
- args.unshift(file);
+ ArrayPrototypeUnshift(args, file);
}
const env = options.env || process.env;
@@ -528,27 +543,30 @@ function normalizeSpawnArguments(file, args, options) {
let envKeys = [];
// Prototype values are intentionally included.
for (const key in env) {
- envKeys.push(key);
+ ArrayPrototypePush(envKeys, key);
}
if (process.platform === 'win32') {
// On Windows env keys are case insensitive. Filter out duplicates,
// keeping only the first one (in lexicographic order)
- const sawKey = new Set();
- envKeys = envKeys.sort().filter((key) => {
- const uppercaseKey = key.toUpperCase();
- if (sawKey.has(uppercaseKey)) {
- return false;
+ const sawKey = new SafeSet();
+ envKeys = ArrayPrototypeFilter(
+ ArrayPrototypeSort(envKeys),
+ (key) => {
+ const uppercaseKey = StringPrototypeToUpperCase(key);
+ if (sawKey.has(uppercaseKey)) {
+ return false;
+ }
+ sawKey.add(uppercaseKey);
+ return true;
}
- sawKey.add(uppercaseKey);
- return true;
- });
+ );
}
for (const key of envKeys) {
const value = env[key];
if (value !== undefined) {
- envPairs.push(`${key}=${value}`);
+ ArrayPrototypePush(envPairs, `${key}=${value}`);
}
}
@@ -629,7 +647,7 @@ function checkExecSyncError(ret, args, cmd) {
err = ret.error;
} else if (ret.status !== 0) {
let msg = 'Command failed: ';
- msg += cmd || args.join(' ');
+ msg += cmd || ArrayPrototypeJoin(args, ' ');
if (ret.stderr && ret.stderr.length > 0)
msg += `\n${ret.stderr.toString()}`;
// eslint-disable-next-line no-restricted-syntax
@@ -646,7 +664,8 @@ function execFileSync(command, args, options) {
options = normalizeSpawnArguments(command, args, options);
const inheritStderr = !options.stdio;
- const ret = spawnSync(options.file, options.args.slice(1), options);
+ const ret = spawnSync(options.file,
+ ArrayPrototypeSlice(options.args, 1), options);
if (inheritStderr && ret.stderr)
process.stderr.write(ret.stderr);
diff --git a/lib/internal/child_process.js b/lib/internal/child_process.js
index 76e67317b9..8dd85d287f 100644
--- a/lib/internal/child_process.js
+++ b/lib/internal/child_process.js
@@ -2,8 +2,15 @@
const {
ArrayIsArray,
+ ArrayPrototypePush,
+ ArrayPrototypeReduce,
+ ArrayPrototypeSlice,
+ FunctionPrototype,
+ FunctionPrototypeCall,
ObjectDefineProperty,
ObjectSetPrototypeOf,
+ ReflectApply,
+ StringPrototypeSlice,
Symbol,
Uint8Array,
} = primordials;
@@ -224,19 +231,19 @@ function stdioStringToArray(stdio, channel) {
switch (stdio) {
case 'ignore':
- case 'pipe': options.push(stdio, stdio, stdio); break;
- case 'inherit': options.push(0, 1, 2); break;
+ case 'pipe': ArrayPrototypePush(options, stdio, stdio, stdio); break;
+ case 'inherit': ArrayPrototypePush(options, 0, 1, 2); break;
default:
throw new ERR_INVALID_ARG_VALUE('stdio', stdio);
}
- if (channel) options.push(channel);
+ if (channel) ArrayPrototypePush(options, channel);
return options;
}
function ChildProcess() {
- EventEmitter.call(this);
+ FunctionPrototypeCall(EventEmitter, this);
this._closesNeeded = 1;
this._closesGot = 0;
@@ -271,7 +278,7 @@ function ChildProcess() {
if (this.spawnfile)
err.path = this.spawnfile;
- err.spawnargs = this.spawnargs.slice(1);
+ err.spawnargs = ArrayPrototypeSlice(this.spawnargs, 1);
this.emit('error', err);
} else {
this.emit('exit', this.exitCode, this.signalCode);
@@ -361,8 +368,9 @@ ChildProcess.prototype.spawn = function(options) {
options.envPairs);
}
- options.envPairs.push(`NODE_CHANNEL_FD=${ipcFd}`);
- options.envPairs.push(`NODE_CHANNEL_SERIALIZATION_MODE=${serialization}`);
+ ArrayPrototypePush(options.envPairs, `NODE_CHANNEL_FD=${ipcFd}`);
+ ArrayPrototypePush(options.envPairs,
+ `NODE_CHANNEL_SERIALIZATION_MODE=${serialization}`);
}
validateString(options.file, 'options.file');
@@ -454,7 +462,8 @@ ChildProcess.prototype.spawn = function(options) {
this.stdio = [];
for (i = 0; i < stdio.length; i++)
- this.stdio.push(stdio[i].socket === undefined ? null : stdio[i].socket);
+ ArrayPrototypePush(this.stdio,
+ stdio[i].socket === undefined ? null : stdio[i].socket);
// Add .send() method and start listening for IPC data
if (ipc !== undefined) setupChannel(this, ipc, serialization);
@@ -768,7 +777,7 @@ function setupChannel(target, channel, serializationMode) {
// Queue-up message and handle if we haven't received ACK yet.
if (this._handleQueue) {
- this._handleQueue.push({
+ ArrayPrototypePush(this._handleQueue, {
callback: callback,
handle: handle,
options: options,
@@ -780,10 +789,8 @@ function setupChannel(target, channel, serializationMode) {
obj = handleConversion[message.type];
// convert TCP object to native handle object
- handle = handleConversion[message.type].send.call(target,
- message,
- handle,
- options);
+ handle = ReflectApply(handleConversion[message.type].send,
+ target, [message, handle, options]);
// If handle was sent twice, or it is impossible to get native handle
// out of it - just send a text without the handle.
@@ -798,7 +805,7 @@ function setupChannel(target, channel, serializationMode) {
!(message && (message.cmd === 'NODE_HANDLE_ACK' ||
message.cmd === 'NODE_HANDLE_NACK'))) {
// Queue request anyway to avoid out-of-order messages.
- this._handleQueue.push({
+ ArrayPrototypePush(this._handleQueue, {
callback: callback,
handle: null,
options: options,
@@ -929,10 +936,11 @@ function isInternal(message) {
typeof message === 'object' &&
typeof message.cmd === 'string' &&
message.cmd.length > INTERNAL_PREFIX.length &&
- message.cmd.slice(0, INTERNAL_PREFIX.length) === INTERNAL_PREFIX);
+ StringPrototypeSlice(message.cmd, 0, INTERNAL_PREFIX.length) ===
+ INTERNAL_PREFIX);
}
-function nop() { }
+const nop = FunctionPrototype;
function getValidStdio(stdio, sync) {
let ipc;
@@ -949,11 +957,11 @@ function getValidStdio(stdio, sync) {
// Don't concat() a new Array() because it would be sparse, and
// stdio.reduce() would skip the sparse elements of stdio.
// See https://stackoverflow.com/a/5501711/3561
- while (stdio.length < 3) stdio.push(undefined);
+ while (stdio.length < 3) ArrayPrototypePush(stdio, undefined);
// Translate stdio into C++-readable form
// (i.e. PipeWraps or fds)
- stdio = stdio.reduce((acc, stdio, i) => {
+ stdio = ArrayPrototypeReduce(stdio, (acc, stdio, i) => {
function cleanup() {
for (let i = 0; i < acc.length; i++) {
if ((acc[i].type === 'pipe' || acc[i].type === 'ipc') && acc[i].handle)
@@ -967,7 +975,7 @@ function getValidStdio(stdio, sync) {
}
if (stdio === 'ignore') {
- acc.push({ type: 'ignore' });
+ ArrayPrototypePush(acc, { type: 'ignore' });
} else if (stdio === 'pipe' || (typeof stdio === 'number' && stdio < 0)) {
const a = {
type: 'pipe',
@@ -978,7 +986,7 @@ function getValidStdio(stdio, sync) {
if (!sync)
a.handle = new Pipe(PipeConstants.SOCKET);
- acc.push(a);
+ ArrayPrototypePush(acc, a);
} else if (stdio === 'ipc') {
if (sync || ipc !== undefined) {
// Cleanup previously created pipes
@@ -992,18 +1000,18 @@ function getValidStdio(stdio, sync) {
ipc = new Pipe(PipeConstants.IPC);
ipcFd = i;
- acc.push({
+ ArrayPrototypePush(acc, {
type: 'pipe',
handle: ipc,
ipc: true
});
} else if (stdio === 'inherit') {
- acc.push({
+ ArrayPrototypePush(acc, {
type: 'inherit',
fd: i
});
} else if (typeof stdio === 'number' || typeof stdio.fd === 'number') {
- acc.push({
+ ArrayPrototypePush(acc, {
type: 'fd',
fd: typeof stdio === 'number' ? stdio : stdio.fd
});
@@ -1013,7 +1021,7 @@ function getValidStdio(stdio, sync) {
stdio :
getHandleWrapType(stdio.handle) ? stdio.handle : stdio._handle;
- acc.push({
+ ArrayPrototypePush(acc, {
type: 'wrap',
wrapType: getHandleWrapType(handle),
handle: handle,
@@ -1073,7 +1081,7 @@ function spawnSync(options) {
if (result.error) {
result.error = errnoException(result.error, 'spawnSync ' + options.file);
result.error.path = options.file;
- result.error.spawnargs = options.args.slice(1);
+ result.error.spawnargs = ArrayPrototypeSlice(options.args, 1);
}
return result;