Skip to content

Commit 4ca1bd8

Browse files
Lxxyxdanielleadams
authored andcommitted
child_process: refactor to use more primordials
PR-URL: #36269 Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
1 parent ab084c1 commit 4ca1bd8

File tree

2 files changed

+81
-54
lines changed

2 files changed

+81
-54
lines changed

lib/child_process.js

+48-29
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,25 @@
2323

2424
const {
2525
ArrayIsArray,
26+
ArrayPrototypeFilter,
27+
ArrayPrototypeIncludes,
28+
ArrayPrototypeJoin,
29+
ArrayPrototypeLastIndexOf,
30+
ArrayPrototypePush,
31+
ArrayPrototypeSlice,
32+
ArrayPrototypeSort,
33+
ArrayPrototypeSplice,
34+
ArrayPrototypeUnshift,
2635
Error,
2736
NumberIsInteger,
2837
ObjectAssign,
2938
ObjectDefineProperty,
3039
ObjectPrototypeHasOwnProperty,
3140
Promise,
32-
Set,
41+
RegExpPrototypeTest,
42+
SafeSet,
43+
StringPrototypeSlice,
44+
StringPrototypeToUpperCase,
3345
} = primordials;
3446

3547
const {
@@ -94,15 +106,15 @@ function fork(modulePath /* , args, options */) {
94106
execArgv = options.execArgv || process.execArgv;
95107

96108
if (execArgv === process.execArgv && process._eval != null) {
97-
const index = execArgv.lastIndexOf(process._eval);
109+
const index = ArrayPrototypeLastIndexOf(execArgv, process._eval);
98110
if (index > 0) {
99111
// Remove the -e switch to avoid fork bombing ourselves.
100-
execArgv = execArgv.slice();
101-
execArgv.splice(index - 1, 2);
112+
execArgv = ArrayPrototypeSlice(execArgv);
113+
ArrayPrototypeSplice(execArgv, index - 1, 2);
102114
}
103115
}
104116

105-
args = execArgv.concat([modulePath], args);
117+
args = [...execArgv, modulePath, ...args];
106118

107119
if (typeof options.stdio === 'string') {
108120
options.stdio = stdioStringToArray(options.stdio, 'ipc');
@@ -112,7 +124,7 @@ function fork(modulePath /* , args, options */) {
112124
options.stdio = stdioStringToArray(
113125
options.silent ? 'pipe' : 'inherit',
114126
'ipc');
115-
} else if (!options.stdio.includes('ipc')) {
127+
} else if (!ArrayPrototypeIncludes(options.stdio, 'ipc')) {
116128
throw new ERR_CHILD_PROCESS_IPC_REQUIRED('options.stdio');
117129
}
118130

@@ -282,7 +294,7 @@ function execFile(file /* , args, options, callback */) {
282294
child.stdout &&
283295
child.stdout.readableEncoding
284296
)) {
285-
stdout = _stdout.join('');
297+
stdout = ArrayPrototypeJoin(_stdout, '');
286298
} else {
287299
stdout = Buffer.concat(_stdout);
288300
}
@@ -291,7 +303,7 @@ function execFile(file /* , args, options, callback */) {
291303
child.stderr &&
292304
child.stderr.readableEncoding
293305
)) {
294-
stderr = _stderr.join('');
306+
stderr = ArrayPrototypeJoin(_stderr, '');
295307
} else {
296308
stderr = Buffer.concat(_stderr);
297309
}
@@ -302,7 +314,7 @@ function execFile(file /* , args, options, callback */) {
302314
}
303315

304316
if (args.length !== 0)
305-
cmd += ` ${args.join(' ')}`;
317+
cmd += ` ${ArrayPrototypeJoin(args, ' ')}`;
306318

307319
if (!ex) {
308320
// eslint-disable-next-line no-restricted-syntax
@@ -360,16 +372,18 @@ function execFile(file /* , args, options, callback */) {
360372
const length = encoding ?
361373
Buffer.byteLength(chunk, encoding) :
362374
chunk.length;
375+
const slice = encoding ? StringPrototypeSlice :
376+
(buf, ...args) => buf.slice(...args);
363377
stdoutLen += length;
364378

365379
if (stdoutLen > options.maxBuffer) {
366380
const truncatedLen = options.maxBuffer - (stdoutLen - length);
367-
_stdout.push(chunk.slice(0, truncatedLen));
381+
ArrayPrototypePush(_stdout, slice(chunk, 0, truncatedLen));
368382

369383
ex = new ERR_CHILD_PROCESS_STDIO_MAXBUFFER('stdout');
370384
kill();
371385
} else {
372-
_stdout.push(chunk);
386+
ArrayPrototypePush(_stdout, chunk);
373387
}
374388
});
375389
}
@@ -387,7 +401,8 @@ function execFile(file /* , args, options, callback */) {
387401

388402
if (stderrLen > options.maxBuffer) {
389403
const truncatedLen = options.maxBuffer - (stderrLen - length);
390-
_stderr.push(chunk.slice(0, truncatedLen));
404+
ArrayPrototypePush(_stderr,
405+
chunk.slice(0, truncatedLen));
391406

392407
ex = new ERR_CHILD_PROCESS_STDIO_MAXBUFFER('stderr');
393408
kill();
@@ -415,7 +430,7 @@ function normalizeSpawnArguments(file, args, options) {
415430
throw new ERR_INVALID_ARG_VALUE('file', file, 'cannot be empty');
416431

417432
if (ArrayIsArray(args)) {
418-
args = args.slice(0);
433+
args = ArrayPrototypeSlice(args);
419434
} else if (args == null) {
420435
args = [];
421436
} else if (typeof args !== 'object') {
@@ -484,15 +499,15 @@ function normalizeSpawnArguments(file, args, options) {
484499
}
485500

486501
if (options.shell) {
487-
const command = [file].concat(args).join(' ');
502+
const command = ArrayPrototypeJoin([file, ...args], ' ');
488503
// Set the shell, switches, and commands.
489504
if (process.platform === 'win32') {
490505
if (typeof options.shell === 'string')
491506
file = options.shell;
492507
else
493508
file = process.env.comspec || 'cmd.exe';
494509
// '/d /s /c' is used only for cmd.exe.
495-
if (/^(?:.*\\)?cmd(?:\.exe)?$/i.test(file)) {
510+
if (RegExpPrototypeTest(/^(?:.*\\)?cmd(?:\.exe)?$/i, file)) {
496511
args = ['/d', '/s', '/c', `"${command}"`];
497512
windowsVerbatimArguments = true;
498513
} else {
@@ -510,9 +525,9 @@ function normalizeSpawnArguments(file, args, options) {
510525
}
511526

512527
if (typeof options.argv0 === 'string') {
513-
args.unshift(options.argv0);
528+
ArrayPrototypeUnshift(args, options.argv0);
514529
} else {
515-
args.unshift(file);
530+
ArrayPrototypeUnshift(args, file);
516531
}
517532

518533
const env = options.env || process.env;
@@ -528,27 +543,30 @@ function normalizeSpawnArguments(file, args, options) {
528543
let envKeys = [];
529544
// Prototype values are intentionally included.
530545
for (const key in env) {
531-
envKeys.push(key);
546+
ArrayPrototypePush(envKeys, key);
532547
}
533548

534549
if (process.platform === 'win32') {
535550
// On Windows env keys are case insensitive. Filter out duplicates,
536551
// keeping only the first one (in lexicographic order)
537-
const sawKey = new Set();
538-
envKeys = envKeys.sort().filter((key) => {
539-
const uppercaseKey = key.toUpperCase();
540-
if (sawKey.has(uppercaseKey)) {
541-
return false;
552+
const sawKey = new SafeSet();
553+
envKeys = ArrayPrototypeFilter(
554+
ArrayPrototypeSort(envKeys),
555+
(key) => {
556+
const uppercaseKey = StringPrototypeToUpperCase(key);
557+
if (sawKey.has(uppercaseKey)) {
558+
return false;
559+
}
560+
sawKey.add(uppercaseKey);
561+
return true;
542562
}
543-
sawKey.add(uppercaseKey);
544-
return true;
545-
});
563+
);
546564
}
547565

548566
for (const key of envKeys) {
549567
const value = env[key];
550568
if (value !== undefined) {
551-
envPairs.push(`${key}=${value}`);
569+
ArrayPrototypePush(envPairs, `${key}=${value}`);
552570
}
553571
}
554572

@@ -629,7 +647,7 @@ function checkExecSyncError(ret, args, cmd) {
629647
err = ret.error;
630648
} else if (ret.status !== 0) {
631649
let msg = 'Command failed: ';
632-
msg += cmd || args.join(' ');
650+
msg += cmd || ArrayPrototypeJoin(args, ' ');
633651
if (ret.stderr && ret.stderr.length > 0)
634652
msg += `\n${ret.stderr.toString()}`;
635653
// eslint-disable-next-line no-restricted-syntax
@@ -646,7 +664,8 @@ function execFileSync(command, args, options) {
646664
options = normalizeSpawnArguments(command, args, options);
647665

648666
const inheritStderr = !options.stdio;
649-
const ret = spawnSync(options.file, options.args.slice(1), options);
667+
const ret = spawnSync(options.file,
668+
ArrayPrototypeSlice(options.args, 1), options);
650669

651670
if (inheritStderr && ret.stderr)
652671
process.stderr.write(ret.stderr);

0 commit comments

Comments
 (0)