Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions lib/_http_outgoing.js
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,8 @@ OutgoingMessage.prototype.uncork = function uncork() {
}
}
this._send(crlf_buf, null, callbacks.length ? (err) => {
for (const callback of callbacks) {
for (let i = 0; i < callbacks.length; i++) {
const callback = callbacks[i];
callback(err);
}
} : null);
Expand Down Expand Up @@ -675,7 +676,8 @@ OutgoingMessage.prototype.setHeaders = function setHeaders(headers) {
// set-cookie values in array and set them all at once.
const cookies = [];

for (const { 0: key, 1: value } of headers) {
for (let i = 0; i < headers.length; i++) {
const { 0: key, 1: value } = headers[i];
if (key === 'set-cookie') {
if (ArrayIsArray(value)) {
cookies.push(...value);
Expand Down
4 changes: 3 additions & 1 deletion lib/_http_server.js
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,9 @@ ServerResponse.prototype.writeEarlyHints = function writeEarlyHints(hints, cb) {

head += 'Link: ' + link + '\r\n';

for (const key of ObjectKeys(hints)) {
const hintKeys = ObjectKeys(hints);
for (let i = 0; i < hintKeys.length; i++) {
const key = hintKeys[i];
if (key !== 'link') {
head += key + ': ' + hints[key] + '\r\n';
}
Expand Down
9 changes: 6 additions & 3 deletions lib/assert.js
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,8 @@ assert.partialDeepStrictEqual = function partialDeepStrictEqual(

class Comparison {
constructor(obj, keys, actual) {
for (const key of keys) {
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
if (key in obj) {
if (actual !== undefined &&
typeof actual[key] === 'string' &&
Expand Down Expand Up @@ -433,7 +434,8 @@ function expectedException(actual, expected, message, fn) {
expected, 'may not be an empty object');
}
if (isDeepEqual === undefined) lazyLoadComparison();
for (const key of keys) {
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
if (typeof actual[key] === 'string' &&
isRegExp(expected[key]) &&
RegExpPrototypeExec(expected[key], actual[key]) !== null) {
Expand Down Expand Up @@ -722,7 +724,8 @@ assert.ifError = function ifError(err) {
);
// Filter all frames existing in err.stack.
let newFrames = StringPrototypeSplit(newErr.stack, '\n');
for (const errFrame of originalFrames) {
for (let i = 0; i < originalFrames.length; i++) {
const errFrame = originalFrames[i];
// Find the first occurrence of the frame.
const pos = ArrayPrototypeIndexOf(newFrames, errFrame);
if (pos !== -1) {
Expand Down
9 changes: 6 additions & 3 deletions lib/child_process.js
Original file line number Diff line number Diff line change
Expand Up @@ -554,8 +554,10 @@ function copyPermissionModelFlagsToEnv(env, key, args) {
}

const flagsToCopy = getPermissionModelFlagsToCopy();
for (const arg of process.execArgv) {
for (const flag of flagsToCopy) {
for (let i = 0; i < process.execArgv.length; i++) {
const arg = process.execArgv[i];
for (let j = 0; j < flagsToCopy.length; j++) {
const flag = flagsToCopy[j];
if (arg.startsWith(flag)) {
env[key] = `${env[key] ? env[key] + ' ' + arg : arg}`;
}
Expand Down Expand Up @@ -727,7 +729,8 @@ function normalizeSpawnArguments(file, args, options) {
);
}

for (const key of envKeys) {
for (let i = 0; i < envKeys.length; i++) {
const key = envKeys[i];
const value = env[key];
if (value !== undefined) {
validateArgumentNullCheck(key, `options.env['${key}']`);
Expand Down
4 changes: 3 additions & 1 deletion lib/dgram.js
Original file line number Diff line number Diff line change
Expand Up @@ -591,8 +591,10 @@ function clearQueue() {
state.queue = undefined;

// Flush the send queue.
for (const queueEntry of queue)
for (let i = 0; i < queue.length; i++) {
const queueEntry = queue[i];
queueEntry();
}
}

// valid combinations
Expand Down
5 changes: 4 additions & 1 deletion lib/diagnostics_channel.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict';

const {
ArrayFrom,
ArrayPrototypeAt,
ArrayPrototypeIndexOf,
ArrayPrototypePush,
Expand Down Expand Up @@ -162,7 +163,9 @@ class ActiveChannel {
return ReflectApply(fn, thisArg, args);
};

for (const entry of this._stores.entries()) {
const storeEntries = ArrayFrom(this._stores.entries());
for (let i = 0; i < storeEntries.length; i++) {
const entry = storeEntries[i];
const store = entry[0];
const transform = entry[1];
run = wrapStoreRun(store, data, run, transform);
Expand Down
1 change: 1 addition & 0 deletions lib/eslint.config_partial.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,7 @@ export default [
'node-core/lowercase-name-for-primitive': 'error',
'node-core/non-ascii-character': 'error',
'node-core/no-array-destructuring': 'error',
'node-core/no-unsafe-array-iteration': 'error',
'node-core/prefer-primordials': [
'error',
{ name: 'AggregateError' },
Expand Down
4 changes: 3 additions & 1 deletion lib/events.js
Original file line number Diff line number Diff line change
Expand Up @@ -751,7 +751,9 @@ EventEmitter.prototype.removeAllListeners =

// Emit removeListener for all listeners on all events
if (arguments.length === 0) {
for (const key of ReflectOwnKeys(events)) {
const eventKeys = ReflectOwnKeys(events);
for (let i = 0; i < eventKeys.length; i++) {
const key = eventKeys[i];
if (key === 'removeListener') continue;
this.removeAllListeners(key);
}
Expand Down
6 changes: 4 additions & 2 deletions lib/inspector.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict';

const {
ArrayFrom,
JSONParse,
JSONStringify,
SafeMap,
Expand Down Expand Up @@ -150,8 +151,9 @@ class Session extends EventEmitter {
return;
this.#connection.disconnect();
this.#connection = null;
const remainingCallbacks = this.#messageCallbacks.values();
for (const callback of remainingCallbacks) {
const remainingCallbacks = ArrayFrom(this.#messageCallbacks.values());
for (let i = 0; i < remainingCallbacks.length; i++) {
const callback = remainingCallbacks[i];
process.nextTick(callback, new ERR_INSPECTOR_CLOSED());
}
this.#messageCallbacks.clear();
Expand Down
5 changes: 4 additions & 1 deletion lib/internal/abort_controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
// in https://github.com/mysticatea/abort-controller (MIT license)

const {
ArrayFrom,
ArrayPrototypePush,
ObjectAssign,
ObjectDefineProperties,
Expand Down Expand Up @@ -296,7 +297,9 @@ class AbortSignal extends EventTarget {
} else if (!signal[kSourceSignals]) {
continue;
} else {
for (const sourceSignalWeakRef of signal[kSourceSignals]) {
const sourceSignalWeakRefs = ArrayFrom(signal[kSourceSignals]);
for (let i = 0; i < sourceSignalWeakRefs.length; i++) {
const sourceSignalWeakRef = sourceSignalWeakRefs[i];
Comment on lines +300 to +302
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's almost certainly less efficient, ArrayFrom iterate over the object, so we essentially double the number of iteration

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the loop should be converted to a callback, the second argument of ArrayFrom

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would just leave the for..of here tbh, but in any case, it should be a separate PR

const sourceSignal = sourceSignalWeakRef.deref();
if (!sourceSignal) {
continue;
Expand Down
8 changes: 6 additions & 2 deletions lib/internal/assert/utils.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict';

const {
ArrayFrom,
ArrayPrototypeShift,
Error,
ErrorCaptureStackTrace,
Expand Down Expand Up @@ -126,7 +127,9 @@ function parseCode(code, offset) {
let node;
let start;
// Parse the read code until the correct expression is found.
for (const token of tokenizer(code, { ecmaVersion: 'latest' })) {
const tokens = ArrayFrom(tokenizer(code, { ecmaVersion: 'latest' }));
for (let i = 0; i < tokens.length; i++) {
const token = tokens[i];
start = token.start;
if (start > offset) {
// No matching expression found. This could happen if the assert
Expand Down Expand Up @@ -222,7 +225,8 @@ function getErrMessage(message, fn) {
}
const frames = StringPrototypeSplit(message, '\n');
message = ArrayPrototypeShift(frames);
for (const frame of frames) {
for (let i = 0; i < frames.length; i++) {
const frame = frames[i];
let pos = 0;
while (pos < column && (frame[pos] === ' ' || frame[pos] === '\t')) {
pos++;
Expand Down
3 changes: 2 additions & 1 deletion lib/internal/blob.js
Original file line number Diff line number Diff line change
Expand Up @@ -499,7 +499,8 @@ function createBlobReaderStream(reader) {
},
cancel(reason) {
// Reject any currently pending pulls here.
for (const pending of this.pendingPulls) {
for (let i = 0; i < this.pendingPulls.length; i++) {
const pending = this.pendingPulls[i];
pending.reject(reason);
}
this.pendingPulls = [];
Expand Down
9 changes: 6 additions & 3 deletions lib/internal/blocklist.js
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,8 @@ class BlockList {
* ];
*/
#parseIPInfo(data) {
for (const item of data) {
for (let i = 0; i < data.length; i++) {
const item = data[i];
if (item.includes('IPv4')) {
const subnetMatch = item.match(
/Subnet: IPv4 (\d{1,3}(?:\.\d{1,3}){3})\/(\d{1,2})/,
Expand Down Expand Up @@ -241,7 +242,8 @@ class BlockList {
// The data argument must be a string, or an array of strings that
// is JSON parseable.
if (ArrayIsArray(data)) {
for (const n of data) {
for (let i = 0; i < data.length; i++) {
const n = data[i];
if (typeof n !== 'string') {
throw new ERR_INVALID_ARG_TYPE('data', ['string', 'string[]'], data);
}
Expand All @@ -253,7 +255,8 @@ class BlockList {
if (!ArrayIsArray(data)) {
throw new ERR_INVALID_ARG_TYPE('data', ['string', 'string[]'], data);
}
for (const n of data) {
for (let i = 0; i < data.length; i++) {
const n = data[i];
if (typeof n !== 'string') {
throw new ERR_INVALID_ARG_TYPE('data', ['string', 'string[]'], data);
}
Expand Down
5 changes: 4 additions & 1 deletion lib/internal/child_process.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict';

const {
ArrayFrom,
ArrayIsArray,
ArrayPrototypePush,
ArrayPrototypeReduce,
Expand Down Expand Up @@ -604,7 +605,9 @@ function setupChannel(target, channel, serializationMode) {
if (recvHandle)
pendingHandle = recvHandle;

for (const message of parseChannelMessages(channel, pool)) {
const messages = ArrayFrom(parseChannelMessages(channel, pool));
for (let i = 0; i < messages.length; i++) {
const message = messages[i];
// There will be at most one NODE_HANDLE message in every chunk we
// read because SCM_RIGHTS messages don't get coalesced. Make sure
// that we deliver the handle with the right message however.
Expand Down
4 changes: 3 additions & 1 deletion lib/internal/cli_table.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,10 @@ const table = (head, columns) => {
ArrayPrototypeJoin(divider, tableChars.rowMiddle) +
tableChars.rightMiddle + '\n';

for (const row of rows)
for (let i = 0; i < rows.length; i++) {
const row = rows[i];
result += `${renderRow(row, columnWidths)}\n`;
}

result += tableChars.bottomLeft +
ArrayPrototypeJoin(divider, tableChars.bottomMiddle) +
Expand Down
5 changes: 4 additions & 1 deletion lib/internal/cluster/child.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict';

const {
ArrayFrom,
ArrayPrototypeJoin,
FunctionPrototype,
ObjectAssign,
Expand Down Expand Up @@ -270,7 +271,9 @@ function _disconnect(primaryInitiated) {
}
}

for (const handle of handles.values()) {
const handleValues = ArrayFrom(handles.values());
for (let i = 0; i < handleValues.length; i++) {
const handle = handleValues[i];
waitingCount++;

if (handle[owner_symbol])
Expand Down
12 changes: 9 additions & 3 deletions lib/internal/cluster/primary.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict';

const {
ArrayFrom,
ArrayPrototypePush,
ArrayPrototypeSlice,
ArrayPrototypeSome,
Expand Down Expand Up @@ -96,7 +97,9 @@ cluster.setupPrimary = function(options) {
if (message.cmd !== 'NODE_DEBUG_ENABLED')
return;

for (const worker of ObjectValues(cluster.workers)) {
const workers = ObjectValues(cluster.workers);
for (let i = 0; i < workers.length; i++) {
const worker = workers[i];
if (worker.state === 'online' || worker.state === 'listening') {
process._debugProcess(worker.process.pid);
} else {
Expand Down Expand Up @@ -152,7 +155,9 @@ function removeWorker(worker) {
function removeHandlesForWorker(worker) {
assert(worker);

for (const { 0: key, 1: handle } of handles) {
const handleEntries = ArrayFrom(handles);
for (let i = 0; i < handleEntries.length; i++) {
const { 0: key, 1: handle } = handleEntries[i];
if (handle.remove(worker))
handles.delete(key);
}
Expand Down Expand Up @@ -226,7 +231,8 @@ cluster.disconnect = function(cb) {
if (workers.length === 0) {
process.nextTick(() => intercom.emit('disconnect'));
} else {
for (const worker of workers) {
for (let i = 0; i < workers.length; i++) {
const worker = workers[i];
if (worker.isConnected()) {
worker.disconnect();
}
Expand Down
23 changes: 17 additions & 6 deletions lib/internal/console/constructor.js
Original file line number Diff line number Diff line change
Expand Up @@ -566,7 +566,8 @@ const consoleMethods = {
length++;
}
} else {
for (const { 0: k, 1: v } of tabularData) {
for (let i = 0; i < tabularData.length; i++) {
const { 0: k, 1: v } = tabularData[i];
ArrayPrototypePush(keys, _inspect(k));
ArrayPrototypePush(values, _inspect(v));
length++;
Expand All @@ -589,7 +590,9 @@ const consoleMethods = {
if (setlike) {
const values = [];
let length = 0;
for (const v of tabularData) {
const tabularArray = ArrayFrom(tabularData);
for (let i = 0; i < tabularArray.length; i++) {
const v = tabularArray[i];
ArrayPrototypePush(values, _inspect(v));
length++;
}
Expand All @@ -610,7 +613,8 @@ const consoleMethods = {
valuesKeyArray[i] = _inspect(item);
} else {
const keys = properties || ObjectKeys(item);
for (const key of keys) {
for (let j = 0; j < keys.length; j++) {
const key = keys[j];
map[key] ??= [];
if ((primitive && properties) ||
!ObjectPrototypeHasOwnProperty(item, key))
Expand Down Expand Up @@ -643,8 +647,11 @@ const isArray = (v) => ArrayIsArray(v) || isTypedArray(v) || isBuffer(v);

function noop() {}

for (const method of ReflectOwnKeys(consoleMethods))
const methodKeys = ReflectOwnKeys(consoleMethods);
for (let i = 0; i < methodKeys.length; i++) {
const method = methodKeys[i];
Console.prototype[method] = consoleMethods[method];
}

Console.prototype.dirxml = Console.prototype.log;
Console.prototype.groupCollapsed = Console.prototype.group;
Expand All @@ -666,15 +673,19 @@ function initializeGlobalConsole(globalConsole) {
const vmConsoleKeys = ObjectKeys(consoleFromVM);
const originalKeys = new SafeSet(vmConsoleKeys.concat(nodeConsoleKeys));
const inspectorConsoleKeys = new SafeSet();
for (const key of ObjectKeys(globalConsole)) {
const globalConsoleKeys = ObjectKeys(globalConsole);
for (let i = 0; i < globalConsoleKeys.length; i++) {
const key = globalConsoleKeys[i];
if (!originalKeys.has(key)) {
inspectorConsoleKeys.add(key);
}
}
// During deserialization these should be reinstalled to console by
// V8 when the inspector client is created.
addSerializeCallback(() => {
for (const key of inspectorConsoleKeys) {
const keysArray = ArrayFrom(inspectorConsoleKeys);
for (let i = 0; i < keysArray.length; i++) {
const key = keysArray[i];
globalConsole[key] = undefined;
}
});
Expand Down
Loading