lib: prefer call() over apply() if argument list is not array

PR-URL: https://github.com/nodejs/node/pull/60796
Reviewed-By: René <contact.9a5d6388@renegade334.me.uk>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
This commit is contained in:
Livia Medeiros 2025-11-23 16:45:46 +08:00 committed by GitHub
parent 7fd36886b4
commit 46dc5d7c9f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
23 changed files with 75 additions and 82 deletions

View File

@ -27,13 +27,13 @@ const {
ArrayPrototypePush,
ArrayPrototypeSlice,
Error,
FunctionPrototypeCall,
NumberIsNaN,
ObjectAssign,
ObjectDefineProperty,
ObjectIs,
ObjectKeys,
ObjectPrototypeIsPrototypeOf,
ReflectApply,
RegExpPrototypeExec,
String,
StringPrototypeIndexOf,
@ -544,7 +544,7 @@ function expectedException(actual, expected, message, fn) {
throwError = true;
} else {
// Check validation functions return value.
const res = ReflectApply(expected, {}, [actual]);
const res = FunctionPrototypeCall(expected, {}, actual);
if (res !== true) {
if (!message) {
generatedMessage = true;
@ -689,7 +689,7 @@ function hasMatchingError(actual, expected) {
if (ObjectPrototypeIsPrototypeOf(Error, expected)) {
return false;
}
return ReflectApply(expected, {}, [actual]) === true;
return FunctionPrototypeCall(expected, {}, actual) === true;
}
function expectsNoError(stackStartFn, actual, error, message) {

View File

@ -29,7 +29,6 @@ const {
FunctionPrototypeCall,
ObjectDefineProperty,
ObjectSetPrototypeOf,
ReflectApply,
SymbolAsyncDispose,
SymbolDispose,
} = primordials;
@ -436,7 +435,7 @@ Socket.prototype.connect = function(port, address, callback) {
return;
}
ReflectApply(_connect, this, [port, address, callback]);
FunctionPrototypeCall(_connect, this, port, address, callback);
};

View File

@ -29,6 +29,7 @@ const {
ArrayPrototypePush,
BigIntPrototypeToString,
Boolean,
FunctionPrototypeCall,
MathMax,
Number,
ObjectDefineProperties,
@ -366,7 +367,7 @@ function readFile(path, options, callback) {
}
if (context.isUserFd) {
process.nextTick(function tick(context) {
ReflectApply(readFileAfterOpen, { context }, [null, path]);
FunctionPrototypeCall(readFileAfterOpen, { context }, null, path);
}, context);
return;
}

View File

@ -805,8 +805,7 @@ function setupChannel(target, channel, serializationMode) {
obj = handleConversion[message.type];
// convert TCP object to native handle object
handle = ReflectApply(handleConversion[message.type].send,
target, [message, handle, options]);
handle = FunctionPrototypeCall(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.

View File

@ -3,6 +3,7 @@
const {
ArrayPrototypeJoin,
FunctionPrototype,
FunctionPrototypeCall,
ObjectAssign,
ReflectApply,
SafeMap,
@ -58,7 +59,7 @@ cluster._setupWorker = function() {
if (message.act === 'newconn')
onconnection(message, handle);
else if (message.act === 'disconnect')
ReflectApply(_disconnect, worker, [true]);
FunctionPrototypeCall(_disconnect, worker, true);
}
};
@ -287,7 +288,7 @@ function _disconnect(primaryInitiated) {
Worker.prototype.disconnect = function() {
if (this.state !== 'disconnecting' && this.state !== 'destroying') {
this.state = 'disconnecting';
ReflectApply(_disconnect, this, []);
FunctionPrototypeCall(_disconnect, this);
}
return this;

View File

@ -1,6 +1,7 @@
'use strict';
const {
FunctionPrototypeCall,
ObjectSetPrototypeOf,
ReflectApply,
} = primordials;
@ -16,7 +17,7 @@ function Worker(options) {
if (!(this instanceof Worker))
return new Worker(options);
ReflectApply(EventEmitter, this, []);
FunctionPrototypeCall(EventEmitter, this);
if (options === null || typeof options !== 'object')
options = kEmptyObject;

View File

@ -1,9 +1,9 @@
'use strict';
const {
FunctionPrototypeCall,
NumberIsInteger,
ObjectSetPrototypeOf,
ReflectApply,
} = primordials;
const {
@ -117,7 +117,7 @@ function createCipherBase(cipher, credential, options, isEncrypt, iv) {
this[kHandle] = new CipherBase(isEncrypt, cipher, credential, iv, authTagLength);
this._decoder = null;
ReflectApply(LazyTransform, this, [options]);
FunctionPrototypeCall(LazyTransform, this, options);
}
function createCipherWithIV(cipher, key, options, isEncrypt, iv) {
@ -125,7 +125,7 @@ function createCipherWithIV(cipher, key, options, isEncrypt, iv) {
const encoding = getStringOption(options, 'encoding');
key = prepareSecretKey(key, encoding);
iv = iv === null ? null : getArrayBufferOrView(iv, 'iv');
ReflectApply(createCipherBase, this, [cipher, key, options, isEncrypt, iv]);
FunctionPrototypeCall(createCipherBase, this, cipher, key, options, isEncrypt, iv);
}
// The Cipher class is part of the legacy Node.js crypto API. It exposes
@ -215,7 +215,7 @@ function Cipheriv(cipher, key, iv, options) {
if (!(this instanceof Cipheriv))
return new Cipheriv(cipher, key, iv, options);
ReflectApply(createCipherWithIV, this, [cipher, key, options, true, iv]);
FunctionPrototypeCall(createCipherWithIV, this, cipher, key, options, true, iv);
}
function addCipherPrototypeFunctions(constructor) {
@ -244,7 +244,7 @@ function Decipheriv(cipher, key, iv, options) {
if (!(this instanceof Decipheriv))
return new Decipheriv(cipher, key, iv, options);
ReflectApply(createCipherWithIV, this, [cipher, key, options, false, iv]);
FunctionPrototypeCall(createCipherWithIV, this, cipher, key, options, false, iv);
}
ObjectSetPrototypeOf(Decipheriv.prototype, LazyTransform.prototype);

View File

@ -1,8 +1,8 @@
'use strict';
const {
FunctionPrototypeCall,
ObjectSetPrototypeOf,
ReflectApply,
StringPrototypeReplace,
StringPrototypeToLowerCase,
Symbol,
@ -105,7 +105,7 @@ function Hash(algorithm, options) {
if (!isCopy && xofLen === undefined) {
maybeEmitDeprecationWarning(algorithm);
}
ReflectApply(LazyTransform, this, [options]);
FunctionPrototypeCall(LazyTransform, this, options);
}
ObjectSetPrototypeOf(Hash.prototype, LazyTransform.prototype);
@ -169,7 +169,7 @@ function Hmac(hmac, key, options) {
this[kState] = {
[kFinalized]: false,
};
ReflectApply(LazyTransform, this, [options]);
FunctionPrototypeCall(LazyTransform, this, options);
}
ObjectSetPrototypeOf(Hmac.prototype, LazyTransform.prototype);

View File

@ -3,7 +3,6 @@
const {
FunctionPrototypeCall,
ObjectSetPrototypeOf,
ReflectApply,
} = primordials;
const {
@ -59,7 +58,7 @@ function Sign(algorithm, options) {
this[kHandle] = new _Sign();
this[kHandle].init(algorithm);
ReflectApply(Writable, this, [options]);
FunctionPrototypeCall(Writable, this, options);
}
ObjectSetPrototypeOf(Sign.prototype, Writable.prototype);
@ -219,7 +218,7 @@ function Verify(algorithm, options) {
this[kHandle] = new _Verify();
this[kHandle].init(algorithm);
ReflectApply(Writable, this, [options]);
FunctionPrototypeCall(Writable, this, options);
}
ObjectSetPrototypeOf(Verify.prototype, Writable.prototype);

View File

@ -2,6 +2,7 @@
const {
ArrayPrototypeIncludes,
FunctionPrototypeCall,
JSONParse,
JSONStringify,
ObjectDefineProperties,
@ -84,7 +85,7 @@ async function digest(algorithm, data) {
algorithm = normalizeAlgorithm(algorithm, 'digest');
return await ReflectApply(asyncDigest, this, [algorithm, data]);
return await FunctionPrototypeCall(asyncDigest, this, algorithm, data);
}
function randomUUID() {
@ -377,10 +378,10 @@ async function deriveKey(
throw lazyDOMException('Unrecognized algorithm name', 'NotSupportedError');
}
return ReflectApply(
return FunctionPrototypeCall(
importKeySync,
this,
['raw-secret', bits, derivedKeyAlgorithm, extractable, keyUsages],
'raw-secret', bits, derivedKeyAlgorithm, extractable, keyUsages,
);
}
@ -889,10 +890,10 @@ async function importKey(
algorithm = normalizeAlgorithm(algorithm, 'importKey');
return ReflectApply(
return FunctionPrototypeCall(
importKeySync,
this,
[format, keyData, algorithm, extractable, keyUsages],
format, keyData, algorithm, extractable, keyUsages,
);
}
@ -926,7 +927,7 @@ async function wrapKey(format, key, wrappingKey, algorithm) {
} catch {
algorithm = normalizeAlgorithm(algorithm, 'encrypt');
}
let keyData = await ReflectApply(exportKey, this, [format, key]);
let keyData = await FunctionPrototypeCall(exportKey, this, format, key);
if (format === 'jwk') {
const ec = new TextEncoder();
@ -1023,10 +1024,10 @@ async function unwrapKey(
}
}
return ReflectApply(
return FunctionPrototypeCall(
importKeySync,
this,
[format, keyData, unwrappedKeyAlgo, extractable, keyUsages],
format, keyData, unwrappedKeyAlgo, extractable, keyUsages,
);
}
@ -1349,10 +1350,10 @@ async function encapsulateKey(encapsulationAlgorithm, encapsulationKey, sharedKe
throw lazyDOMException('Unrecognized algorithm name', 'NotSupportedError');
}
const sharedKey = ReflectApply(
const sharedKey = FunctionPrototypeCall(
importKeySync,
this,
['raw-secret', encapsulateBits.sharedKey, normalizedSharedKeyAlgorithm, extractable, usages],
'raw-secret', encapsulateBits.sharedKey, normalizedSharedKeyAlgorithm, extractable, usages,
);
const encapsulatedKey = {
@ -1469,10 +1470,10 @@ async function decapsulateKey(
throw lazyDOMException('Unrecognized algorithm name', 'NotSupportedError');
}
return ReflectApply(
return FunctionPrototypeCall(
importKeySync,
this,
['raw-secret', decapsulatedBits, normalizedSharedKeyAlgorithm, extractable, usages],
'raw-secret', decapsulatedBits, normalizedSharedKeyAlgorithm, extractable, usages,
);
}

View File

@ -2,8 +2,8 @@
const {
ArrayPrototypeMap,
FunctionPrototypeCall,
ObjectDefineProperty,
ReflectApply,
Symbol,
} = primordials;
@ -104,7 +104,7 @@ function resolve(hostname, rrtype, callback) {
}
if (typeof resolver === 'function') {
return ReflectApply(resolver, this, [hostname, callback]);
return FunctionPrototypeCall(resolver, this, hostname, callback);
}
throw new ERR_INVALID_ARG_VALUE('rrtype', rrtype);
}

View File

@ -1,9 +1,9 @@
'use strict';
const {
ArrayPrototypeMap,
FunctionPrototypeCall,
ObjectDefineProperty,
Promise,
ReflectApply,
Symbol,
} = primordials;
@ -358,7 +358,7 @@ function resolve(hostname, rrtype) {
resolver = resolveMap.A;
}
return ReflectApply(resolver, this, [hostname]);
return FunctionPrototypeCall(resolver, this, hostname);
}
// Promise-based resolver.

View File

@ -2,7 +2,7 @@
const {
DateNow,
FunctionPrototypeApply,
FunctionPrototypeCall,
NumberIsNaN,
ObjectDefineProperties,
ObjectSetPrototypeOf,
@ -129,7 +129,7 @@ class File extends Blob {
}
function TransferableFile(handle, length, type = '') {
FunctionPrototypeApply(TransferableBlob, this, [handle, length, type]);
FunctionPrototypeCall(TransferableBlob, this, handle, length, type);
ObjectSetPrototypeOf(this, File.prototype);
}

View File

@ -2,8 +2,8 @@
const {
ArrayPrototypePush,
FunctionPrototypeCall,
MathMin,
ReflectApply,
} = primordials;
const {
@ -112,7 +112,7 @@ class ReadFileContext {
close(err) {
if (this.isUserFd) {
process.nextTick(function tick(context) {
ReflectApply(readFileAfterClose, { context }, [null]);
FunctionPrototypeCall(readFileAfterClose, { context }, null);
}, this);
return;
}

View File

@ -3,6 +3,7 @@
const {
Array,
FunctionPrototypeBind,
FunctionPrototypeCall,
MathMin,
ObjectDefineProperty,
ObjectSetPrototypeOf,
@ -223,7 +224,7 @@ function ReadStream(path, options) {
}
}
ReflectApply(Readable, this, [options]);
FunctionPrototypeCall(Readable, this, options);
}
ObjectSetPrototypeOf(ReadStream.prototype, Readable.prototype);
ObjectSetPrototypeOf(ReadStream, Readable);
@ -386,7 +387,7 @@ function WriteStream(path, options) {
this.pos = this.start;
}
ReflectApply(Writable, this, [options]);
FunctionPrototypeCall(Writable, this, options);
if (options.encoding)
this.setDefaultEncoding(options.encoding);

View File

@ -1,8 +1,8 @@
'use strict';
const {
FunctionPrototypeCall,
ObjectSetPrototypeOf,
ReflectApply,
} = primordials;
const { kEmptyObject } = require('internal/util');
@ -10,7 +10,7 @@ const { Writable } = require('stream');
const { closeSync, writeSync } = require('fs');
function SyncWriteStream(fd, options) {
ReflectApply(Writable, this, [{ autoDestroy: true }]);
FunctionPrototypeCall(Writable, this, { autoDestroy: true });
options ||= kEmptyObject;

View File

@ -16,7 +16,6 @@ const {
ObjectDefineProperty,
ObjectIs,
ObjectSetPrototypeOf,
ReflectApply,
ReflectOwnKeys,
RegExpPrototypeSymbolReplace,
StringPrototypeEndsWith,
@ -494,8 +493,7 @@ const lazyDateFields = {
function BigIntStats(dev, mode, nlink, uid, gid, rdev, blksize,
ino, size, blocks,
atimeNs, mtimeNs, ctimeNs, birthtimeNs) {
ReflectApply(StatsBase, this, [dev, mode, nlink, uid, gid, rdev, blksize,
ino, size, blocks]);
FunctionPrototypeCall(StatsBase, this, dev, mode, nlink, uid, gid, rdev, blksize, ino, size, blocks);
this.atimeMs = atimeNs / kNsPerMsBigInt;
this.mtimeMs = mtimeNs / kNsPerMsBigInt;

View File

@ -36,6 +36,7 @@ const {
ArrayPrototypeUnshiftApply,
Boolean,
Error,
FunctionPrototypeCall,
JSONParse,
ObjectDefineProperty,
ObjectFreeze,
@ -47,7 +48,6 @@ const {
ObjectPrototypeHasOwnProperty,
ObjectSetPrototypeOf,
Proxy,
ReflectApply,
ReflectSet,
RegExpPrototypeExec,
SafeMap,
@ -1757,8 +1757,7 @@ Module.prototype._compile = function(content, filename, format) {
result = callAndPauseOnStart(compiledWrapper, thisValue, exports,
require, module, filename, dirname);
} else {
result = ReflectApply(compiledWrapper, thisValue,
[exports, require, module, filename, dirname]);
result = FunctionPrototypeCall(compiledWrapper, thisValue, exports, require, module, filename, dirname);
}
this[kIsExecuting] = false;
if (requireDepth === 0) { statCache = null; }

View File

@ -478,7 +478,7 @@ function buildAllowedFlags() {
forEach(callback, thisArg = undefined) {
ArrayPrototypeForEach(
this[kInternal].array,
(v) => ReflectApply(callback, thisArg, [v, v, this]),
(v) => FunctionPrototypeCall(callback, thisArg, v, v, this),
);
}

View File

@ -22,6 +22,7 @@
'use strict';
const {
FunctionPrototypeCall,
ObjectAssign,
ObjectDefineProperty,
ObjectSetPrototypeOf,
@ -564,7 +565,7 @@ function TLSSocket(socket, opts) {
// distinguishable from regular ones.
this.encrypted = true;
ReflectApply(net.Socket, this, [{
FunctionPrototypeCall(net.Socket, this, {
handle: this._wrapHandle(wrap, handle, wrapHasActiveWriteFromPrevOwner),
allowHalfOpen: socket ? socket.allowHalfOpen : tlsOptions.allowHalfOpen,
pauseOnCreate: tlsOptions.pauseOnConnect,
@ -572,7 +573,7 @@ function TLSSocket(socket, opts) {
highWaterMark: tlsOptions.highWaterMark,
onread: !socket ? tlsOptions.onread : null,
signal: tlsOptions.signal,
}]);
});
// Proxy for API compatibility
this.ssl = this._handle; // C++ TLSWrap object
@ -1371,7 +1372,7 @@ function Server(options, listener) {
}
// constructor call
ReflectApply(net.Server, this, [options, tlsConnectionListener]);
FunctionPrototypeCall(net.Server, this, options, tlsConnectionListener);
if (listener) {
this.on('secureConnection', listener);
@ -1560,8 +1561,7 @@ Server.prototype[EE.captureRejectionSymbol] = function(
sock.destroy(err);
break;
default:
ReflectApply(net.Server.prototype[SymbolFor('nodejs.rejection')], this,
[err, event, sock]);
FunctionPrototypeCall(net.Server.prototype[SymbolFor('nodejs.rejection')], this, err, event, sock);
}
};

View File

@ -1,7 +1,7 @@
'use strict';
const {
ReflectApply,
FunctionPrototypeCall,
Symbol,
} = primordials;
@ -216,16 +216,14 @@ function makeContextifyScript(code,
* @returns {any}
*/
function runScriptInThisContext(script, displayErrors, breakOnFirstLine) {
return ReflectApply(
return FunctionPrototypeCall(
runInContext,
script,
[
null, // sandbox - use current context
-1, // timeout
displayErrors, // displayErrors
false, // breakOnSigint
breakOnFirstLine, // breakOnFirstLine
],
null, // sandbox - use current context
-1, // timeout
displayErrors, // displayErrors
false, // breakOnSigint
breakOnFirstLine, // breakOnFirstLine
);
}

View File

@ -7,6 +7,7 @@ const {
ArrayPrototypeIndexOf,
ArrayPrototypeMap,
ArrayPrototypeSome,
FunctionPrototypeCall,
ObjectDefineProperty,
ObjectFreeze,
ObjectGetPrototypeOf,
@ -15,7 +16,6 @@ const {
PromisePrototypeThen,
PromiseReject,
PromiseResolve,
ReflectApply,
SafePromiseAllReturnArrayLike,
Symbol,
SymbolToStringTag,
@ -522,11 +522,7 @@ class SyntheticModule extends Module {
function importModuleDynamicallyWrap(importModuleDynamically) {
const importModuleDynamicallyWrapper = async (specifier, referrer, attributes, phase) => {
const phaseName = phaseEnumToPhaseName(phase);
const m = await ReflectApply(
importModuleDynamically,
this,
[specifier, referrer, attributes, phaseName],
);
const m = await FunctionPrototypeCall(importModuleDynamically, this, specifier, referrer, attributes, phaseName);
if (isModuleNamespaceObject(m)) {
if (phase === kSourcePhase) throw new ERR_VM_MODULE_NOT_MODULE();
return m;

View File

@ -57,6 +57,7 @@ const {
Boolean,
Error: MainContextError,
FunctionPrototypeBind,
FunctionPrototypeCall,
JSONStringify,
MathMaxApply,
NumberIsNaN,
@ -559,9 +560,9 @@ class REPLServer extends Interface {
};
if (self.useGlobal) {
result = ReflectApply(runInThisContext, script, [scriptOptions]);
result = FunctionPrototypeCall(runInThisContext, script, scriptOptions);
} else {
result = ReflectApply(runInContext, script, [context, scriptOptions]);
result = FunctionPrototypeCall(runInContext, script, context, scriptOptions);
}
} finally {
if (self.breakEvalOnSigint) {
@ -752,8 +753,7 @@ class REPLServer extends Interface {
self.clearBufferedCommand();
function completer(text, cb) {
ReflectApply(complete, self,
[text, self.editorMode ? self.completeOnEditorMode(cb) : cb]);
FunctionPrototypeCall(complete, self, text, self.editorMode ? self.completeOnEditorMode(cb) : cb);
}
self.resetContext();
@ -787,7 +787,7 @@ class REPLServer extends Interface {
function _parseREPLKeyword(keyword, rest) {
const cmd = this.commands[keyword];
if (cmd) {
ReflectApply(cmd.action, this, [rest]);
FunctionPrototypeCall(cmd.action, this, rest);
return true;
}
return false;
@ -853,7 +853,7 @@ class REPLServer extends Interface {
self.line = prefix;
self.cursor = prefix.length;
}
ReflectApply(_memory, self, [cmd]);
FunctionPrototypeCall(_memory, self, cmd);
return;
}
@ -869,7 +869,7 @@ class REPLServer extends Interface {
const matches = RegExpPrototypeExec(/^\.([^\s]+)\s*(.*)$/, trimmedCmd);
const keyword = matches?.[1];
const rest = matches?.[2];
if (ReflectApply(_parseREPLKeyword, self, [keyword, rest]) === true) {
if (FunctionPrototypeCall(_parseREPLKeyword, self, keyword, rest) === true) {
return;
}
if (!self[kBufferedCommandSymbol]) {
@ -887,7 +887,7 @@ class REPLServer extends Interface {
function finish(e, ret) {
debug('finish', e, ret);
ReflectApply(_memory, self, [cmd]);
FunctionPrototypeCall(_memory, self, cmd);
if (e && !self[kBufferedCommandSymbol] &&
StringPrototypeStartsWith(StringPrototypeTrim(cmd), 'npm ') &&
@ -1262,7 +1262,7 @@ function _memory(cmd) {
function _turnOnEditorMode(repl) {
repl.editorMode = true;
ReflectApply(Interface.prototype.setPrompt, repl, ['']);
FunctionPrototypeCall(Interface.prototype.setPrompt, repl, '');
}
function _turnOffEditorMode(repl) {