Skip to content

Commit ecdff81

Browse files
aduh95nodejs-github-bot
authored andcommittedDec 28, 2020
util: refactor to use more primordials
PR-URL: nodejs#36265 Reviewed-By: Rich Trott <[email protected]> Reviewed-By: Michaël Zasso <[email protected]>
1 parent d146b25 commit ecdff81

File tree

6 files changed

+162
-97
lines changed

6 files changed

+162
-97
lines changed
 

‎lib/internal/util.js

+33-22
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@
33
const {
44
ArrayFrom,
55
ArrayIsArray,
6+
ArrayPrototypePop,
7+
ArrayPrototypePush,
8+
ArrayPrototypeSlice,
9+
ArrayPrototypeSort,
610
Error,
7-
Map,
811
ObjectCreate,
912
ObjectDefineProperties,
1013
ObjectDefineProperty,
@@ -13,8 +16,14 @@ const {
1316
ObjectGetPrototypeOf,
1417
ObjectSetPrototypeOf,
1518
Promise,
19+
ReflectApply,
1620
ReflectConstruct,
17-
Set,
21+
RegExpPrototypeTest,
22+
SafeMap,
23+
SafeSet,
24+
StringPrototypeReplace,
25+
StringPrototypeToLowerCase,
26+
StringPrototypeToUpperCase,
1827
Symbol,
1928
SymbolFor,
2029
} = primordials;
@@ -40,12 +49,12 @@ const { isNativeError } = internalBinding('types');
4049

4150
const noCrypto = !process.versions.openssl;
4251

43-
const experimentalWarnings = new Set();
52+
const experimentalWarnings = new SafeSet();
4453

4554
const colorRegExp = /\u001b\[\d\d?m/g; // eslint-disable-line no-control-regex
4655

4756
function removeColors(str) {
48-
return str.replace(colorRegExp, '');
57+
return StringPrototypeReplace(str, colorRegExp, '');
4958
}
5059

5160
function isError(e) {
@@ -57,7 +66,7 @@ function isError(e) {
5766

5867
// Keep a list of deprecation codes that have been warned on so we only warn on
5968
// each one once.
60-
const codesWarned = new Set();
69+
const codesWarned = new SafeSet();
6170

6271
// Mark that a method should not be used.
6372
// Returns a modified function which warns once by default.
@@ -86,7 +95,7 @@ function deprecate(fn, msg, code) {
8695
if (new.target) {
8796
return ReflectConstruct(fn, args, new.target);
8897
}
89-
return fn.apply(this, args);
98+
return ReflectApply(fn, this, args);
9099
}
91100

92101
// The wrapper will keep the same prototype as fn to maintain prototype chain
@@ -132,12 +141,13 @@ function slowCases(enc) {
132141
case 4:
133142
if (enc === 'UTF8') return 'utf8';
134143
if (enc === 'ucs2' || enc === 'UCS2') return 'utf16le';
135-
enc = `${enc}`.toLowerCase();
144+
enc = StringPrototypeToLowerCase(`${enc}`);
136145
if (enc === 'utf8') return 'utf8';
137146
if (enc === 'ucs2') return 'utf16le';
138147
break;
139148
case 3:
140-
if (enc === 'hex' || enc === 'HEX' || `${enc}`.toLowerCase() === 'hex')
149+
if (enc === 'hex' || enc === 'HEX' ||
150+
StringPrototypeToLowerCase(`${enc}`) === 'hex')
141151
return 'hex';
142152
break;
143153
case 5:
@@ -146,7 +156,7 @@ function slowCases(enc) {
146156
if (enc === 'UTF-8') return 'utf8';
147157
if (enc === 'ASCII') return 'ascii';
148158
if (enc === 'UCS-2') return 'utf16le';
149-
enc = `${enc}`.toLowerCase();
159+
enc = StringPrototypeToLowerCase(`${enc}`);
150160
if (enc === 'utf-8') return 'utf8';
151161
if (enc === 'ascii') return 'ascii';
152162
if (enc === 'ucs-2') return 'utf16le';
@@ -156,18 +166,18 @@ function slowCases(enc) {
156166
if (enc === 'latin1' || enc === 'binary') return 'latin1';
157167
if (enc === 'BASE64') return 'base64';
158168
if (enc === 'LATIN1' || enc === 'BINARY') return 'latin1';
159-
enc = `${enc}`.toLowerCase();
169+
enc = StringPrototypeToLowerCase(`${enc}`);
160170
if (enc === 'base64') return 'base64';
161171
if (enc === 'latin1' || enc === 'binary') return 'latin1';
162172
break;
163173
case 7:
164174
if (enc === 'utf16le' || enc === 'UTF16LE' ||
165-
`${enc}`.toLowerCase() === 'utf16le')
175+
StringPrototypeToLowerCase(`${enc}`) === 'utf16le')
166176
return 'utf16le';
167177
break;
168178
case 8:
169179
if (enc === 'utf-16le' || enc === 'UTF-16LE' ||
170-
`${enc}`.toLowerCase() === 'utf-16le')
180+
StringPrototypeToLowerCase(`${enc}`) === 'utf-16le')
171181
return 'utf16le';
172182
break;
173183
default:
@@ -184,25 +194,25 @@ function emitExperimentalWarning(feature) {
184194
}
185195

186196
function filterDuplicateStrings(items, low) {
187-
const map = new Map();
197+
const map = new SafeMap();
188198
for (let i = 0; i < items.length; i++) {
189199
const item = items[i];
190-
const key = item.toLowerCase();
200+
const key = StringPrototypeToLowerCase(item);
191201
if (low) {
192202
map.set(key, key);
193203
} else {
194204
map.set(key, item);
195205
}
196206
}
197-
return ArrayFrom(map.values()).sort();
207+
return ArrayPrototypeSort(ArrayFrom(map.values()));
198208
}
199209

200210
function cachedResult(fn) {
201211
let result;
202212
return () => {
203213
if (result === undefined)
204214
result = fn();
205-
return result.slice();
215+
return ArrayPrototypeSlice(result);
206216
};
207217
}
208218

@@ -244,7 +254,7 @@ function convertToValidSignal(signal) {
244254
return signal;
245255

246256
if (typeof signal === 'string') {
247-
const signalName = signals[signal.toUpperCase()];
257+
const signalName = signals[StringPrototypeToUpperCase(signal)];
248258
if (signalName) return signalName;
249259
}
250260

@@ -294,7 +304,7 @@ function promisify(original) {
294304

295305
function fn(...args) {
296306
return new Promise((resolve, reject) => {
297-
original.call(this, ...args, (err, ...values) => {
307+
ArrayPrototypePush(args, (err, ...values) => {
298308
if (err) {
299309
return reject(err);
300310
}
@@ -307,6 +317,7 @@ function promisify(original) {
307317
resolve(values[0]);
308318
}
309319
});
320+
ReflectApply(original, this, args);
310321
});
311322
}
312323

@@ -343,7 +354,7 @@ function join(output, separator) {
343354
function spliceOne(list, index) {
344355
for (; index + 1 < list.length; index++)
345356
list[index] = list[index + 1];
346-
list.pop();
357+
ArrayPrototypePop(list);
347358
}
348359

349360
const kNodeModulesRE = /^(.*)[\\/]node_modules[\\/]/;
@@ -376,9 +387,9 @@ function isInsideNodeModules() {
376387
const filename = frame.getFileName();
377388
// If a filename does not start with / or contain \,
378389
// it's likely from Node.js core.
379-
if (!/^\/|\\/.test(filename))
390+
if (!RegExpPrototypeTest(/^\/|\\/, filename))
380391
continue;
381-
return kNodeModulesRE.test(filename);
392+
return RegExpPrototypeTest(kNodeModulesRE, filename);
382393
}
383394
}
384395
return false;
@@ -389,7 +400,7 @@ function once(callback) {
389400
return function(...args) {
390401
if (called) return;
391402
called = true;
392-
callback.apply(this, args);
403+
ReflectApply(callback, this, args);
393404
};
394405
}
395406

‎lib/internal/util/comparisons.js

+20-14
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@
22

33
const {
44
ArrayIsArray,
5+
ArrayPrototypeFilter,
6+
ArrayPrototypePush,
57
BigIntPrototypeValueOf,
68
BooleanPrototypeValueOf,
79
DatePrototypeGetTime,
810
Error,
9-
Map,
1011
NumberIsNaN,
1112
NumberPrototypeValueOf,
1213
ObjectGetOwnPropertySymbols,
@@ -16,10 +17,11 @@ const {
1617
ObjectPrototypeHasOwnProperty,
1718
ObjectPrototypePropertyIsEnumerable,
1819
ObjectPrototypeToString,
19-
Set,
20+
SafeMap,
21+
SafeSet,
2022
StringPrototypeValueOf,
2123
SymbolPrototypeValueOf,
22-
SymbolToStringTag,
24+
TypedArrayPrototypeGetSymbolToStringTag,
2325
Uint8Array,
2426
} = primordials;
2527

@@ -126,7 +128,7 @@ function isEqualBoxedPrimitive(val1, val2) {
126128

127129
function isIdenticalTypedArrayType(a, b) {
128130
// Fast path to reduce type checks in the common case.
129-
const check = types[`is${a[SymbolToStringTag]}`];
131+
const check = types[`is${TypedArrayPrototypeGetSymbolToStringTag(a)}`];
130132
if (check !== undefined && check(a)) {
131133
return check(b);
132134
}
@@ -150,8 +152,9 @@ function isIdenticalTypedArrayType(a, b) {
150152
}
151153
/* c8 ignore next 4 */
152154
assert.fail(
153-
`Unknown TypedArray type checking ${a[SymbolToStringTag]} ${a}\n` +
154-
`and ${b[SymbolToStringTag]} ${b}`
155+
'Unknown TypedArray type checking ' +
156+
`${TypedArrayPrototypeGetSymbolToStringTag(a)} ${a}\n` +
157+
`and ${TypedArrayPrototypeGetSymbolToStringTag(b)} ${b}`
155158
);
156159
}
157160

@@ -291,7 +294,10 @@ function innerDeepEqual(val1, val2, strict, memos) {
291294
}
292295

293296
function getEnumerables(val, keys) {
294-
return keys.filter((k) => ObjectPrototypePropertyIsEnumerable(val, k));
297+
return ArrayPrototypeFilter(
298+
keys,
299+
(k) => ObjectPrototypePropertyIsEnumerable(val, k)
300+
);
295301
}
296302

297303
function keyCheck(val1, val2, strict, memos, iterationType, aKeys) {
@@ -330,7 +336,7 @@ function keyCheck(val1, val2, strict, memos, iterationType, aKeys) {
330336
if (!ObjectPrototypePropertyIsEnumerable(val2, key)) {
331337
return false;
332338
}
333-
aKeys.push(key);
339+
ArrayPrototypePush(aKeys, key);
334340
count++;
335341
} else if (ObjectPrototypePropertyIsEnumerable(val2, key)) {
336342
return false;
@@ -360,8 +366,8 @@ function keyCheck(val1, val2, strict, memos, iterationType, aKeys) {
360366
// Use memos to handle cycles.
361367
if (memos === undefined) {
362368
memos = {
363-
val1: new Map(),
364-
val2: new Map(),
369+
val1: new SafeMap(),
370+
val2: new SafeMap(),
365371
position: 0
366372
};
367373
} else {
@@ -458,7 +464,7 @@ function setEquiv(a, b, strict, memo) {
458464
// to check this improves the worst case scenario instead.
459465
if (typeof val === 'object' && val !== null) {
460466
if (set === null) {
461-
set = new Set();
467+
set = new SafeSet();
462468
}
463469
// If the specified value doesn't exist in the second set its an not null
464470
// object (or non strict only: a not matching primitive) we'll need to go
@@ -475,7 +481,7 @@ function setEquiv(a, b, strict, memo) {
475481
}
476482

477483
if (set === null) {
478-
set = new Set();
484+
set = new SafeSet();
479485
}
480486
set.add(val);
481487
}
@@ -521,7 +527,7 @@ function mapEquiv(a, b, strict, memo) {
521527
for (const [key, item1] of a) {
522528
if (typeof key === 'object' && key !== null) {
523529
if (set === null) {
524-
set = new Set();
530+
set = new SafeSet();
525531
}
526532
set.add(key);
527533
} else {
@@ -537,7 +543,7 @@ function mapEquiv(a, b, strict, memo) {
537543
if (!mapMightHaveLoosePrim(a, b, key, item1, memo))
538544
return false;
539545
if (set === null) {
540-
set = new Set();
546+
set = new SafeSet();
541547
}
542548
set.add(key);
543549
}

‎lib/internal/util/debuglog.js

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
'use strict';
22

33
const {
4+
FunctionPrototype,
45
FunctionPrototypeBind,
56
ObjectCreate,
67
ObjectDefineProperty,
78
RegExp,
89
RegExpPrototypeTest,
910
SafeArrayIterator,
10-
StringPrototypeToUpperCase
11+
StringPrototypeToLowerCase,
12+
StringPrototypeToUpperCase,
1113
} = primordials;
1214

1315
const { inspect, format, formatWithOptions } = require('internal/util/inspect');
@@ -37,13 +39,13 @@ function initializeDebugEnv(debugEnv) {
3739
function emitWarningIfNeeded(set) {
3840
if ('HTTP' === set || 'HTTP2' === set) {
3941
process.emitWarning('Setting the NODE_DEBUG environment variable ' +
40-
'to \'' + set.toLowerCase() + '\' can expose sensitive ' +
42+
'to \'' + StringPrototypeToLowerCase(set) + '\' can expose sensitive ' +
4143
'data (such as passwords, tokens and authentication headers) ' +
4244
'in the resulting log.');
4345
}
4446
}
4547

46-
function noop() {}
48+
const noop = FunctionPrototype;
4749

4850
function debuglogImpl(enabled, set) {
4951
if (debugImpls[set] === undefined) {

‎lib/internal/util/inspect.js

+74-46
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
const {
44
Array,
55
ArrayIsArray,
6+
ArrayPrototypeFilter,
7+
ArrayPrototypePush,
8+
ArrayPrototypeSort,
9+
ArrayPrototypeUnshift,
610
BigIntPrototypeValueOf,
711
BooleanPrototypeValueOf,
812
DatePrototypeGetTime,
@@ -12,7 +16,6 @@ const {
1216
FunctionPrototypeCall,
1317
FunctionPrototypeToString,
1418
JSONStringify,
15-
Map,
1619
MapPrototypeGetSize,
1720
MapPrototypeEntries,
1821
MathFloor,
@@ -39,14 +42,27 @@ const {
3942
ObjectPrototypePropertyIsEnumerable,
4043
ObjectSeal,
4144
ObjectSetPrototypeOf,
42-
ReflectApply,
4345
RegExp,
46+
RegExpPrototypeTest,
4447
RegExpPrototypeToString,
4548
SafeStringIterator,
46-
Set,
49+
SafeMap,
50+
SafeSet,
4751
SetPrototypeGetSize,
4852
SetPrototypeValues,
4953
String,
54+
StringPrototypeCharCodeAt,
55+
StringPrototypeCodePointAt,
56+
StringPrototypeIncludes,
57+
StringPrototypeNormalize,
58+
StringPrototypePadEnd,
59+
StringPrototypePadStart,
60+
StringPrototypeRepeat,
61+
StringPrototypeReplace,
62+
StringPrototypeSlice,
63+
StringPrototypeSplit,
64+
StringPrototypeToLowerCase,
65+
StringPrototypeTrim,
5066
StringPrototypeValueOf,
5167
SymbolPrototypeToString,
5268
SymbolPrototypeValueOf,
@@ -120,8 +136,11 @@ const { NativeModule } = require('internal/bootstrap/loaders');
120136

121137
let hexSlice;
122138

123-
const builtInObjects = new Set(
124-
ObjectGetOwnPropertyNames(global).filter((e) => /^[A-Z][a-zA-Z0-9]+$/.test(e))
139+
const builtInObjects = new SafeSet(
140+
ArrayPrototypeFilter(
141+
ObjectGetOwnPropertyNames(global),
142+
(e) => RegExpPrototypeTest(/^[A-Z][a-zA-Z0-9]+$/, e)
143+
)
125144
);
126145

127146
// https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot
@@ -430,7 +449,7 @@ function addQuotes(str, quotes) {
430449
return `'${str}'`;
431450
}
432451

433-
const escapeFn = (str) => meta[str.charCodeAt(0)];
452+
const escapeFn = (str) => meta[StringPrototypeCharCodeAt(str)];
434453

435454
// Escape control characters, single quotes and the backslash.
436455
// This is similar to JSON stringify escaping.
@@ -458,10 +477,10 @@ function strEscape(str) {
458477
}
459478

460479
// Some magic numbers that worked out fine while benchmarking with v8 6.0
461-
if (str.length < 5000 && !escapeTest.test(str))
480+
if (str.length < 5000 && !RegExpPrototypeTest(escapeTest, str))
462481
return addQuotes(str, singleQuote);
463482
if (str.length > 100) {
464-
str = str.replace(escapeReplace, escapeFn);
483+
str = StringPrototypeReplace(str, escapeReplace, escapeFn);
465484
return addQuotes(str, singleQuote);
466485
}
467486

@@ -477,14 +496,14 @@ function strEscape(str) {
477496
if (last === i) {
478497
result += meta[point];
479498
} else {
480-
result += `${str.slice(last, i)}${meta[point]}`;
499+
result += `${StringPrototypeSlice(str, last, i)}${meta[point]}`;
481500
}
482501
last = i + 1;
483502
}
484503
}
485504

486505
if (last !== lastIndex) {
487-
result += str.slice(last);
506+
result += StringPrototypeSlice(str, last);
488507
}
489508
return addQuotes(result, singleQuote);
490509
}
@@ -588,7 +607,7 @@ function addPrototypeProperties(ctx, main, obj, recurseTimes, output) {
588607
}
589608

590609
if (depth === 0) {
591-
keySet = new Set();
610+
keySet = new SafeSet();
592611
} else {
593612
keys.forEach((key) => keySet.add(key));
594613
}
@@ -661,7 +680,7 @@ function getKeys(value, showHidden) {
661680
}
662681
if (symbols.length !== 0) {
663682
const filter = (key) => ObjectPrototypePropertyIsEnumerable(value, key);
664-
keys.push(...symbols.filter(filter));
683+
ArrayPrototypePush(keys, ...ArrayPrototypeFilter(symbols, filter));
665684
}
666685
}
667686
return keys;
@@ -751,7 +770,8 @@ function formatValue(ctx, value, recurseTimes, typedArray) {
751770
if (ctx.seen.includes(value)) {
752771
let index = 1;
753772
if (ctx.circular === undefined) {
754-
ctx.circular = new Map([[value, index]]);
773+
ctx.circular = new SafeMap();
774+
ctx.circular.set(value, index);
755775
} else {
756776
index = ctx.circular.get(value);
757777
if (index === undefined) {
@@ -924,11 +944,11 @@ function formatRaw(ctx, value, recurseTimes, typedArray) {
924944
`{ byteLength: ${formatNumber(ctx.stylize, value.byteLength)} }`;
925945
}
926946
braces[0] = `${prefix}{`;
927-
keys.unshift('byteLength');
947+
ArrayPrototypeUnshift(keys, 'byteLength');
928948
} else if (isDataView(value)) {
929949
braces[0] = `${getPrefix(constructor, tag, 'DataView')}{`;
930950
// .buffer goes last, it's not a primitive like the others.
931-
keys.unshift('byteLength', 'byteOffset', 'buffer');
951+
ArrayPrototypeUnshift(keys, 'byteLength', 'byteOffset', 'buffer');
932952
} else if (isPromise(value)) {
933953
braces[0] = `${getPrefix(constructor, tag, 'Promise')}{`;
934954
formatter = formatPromise;
@@ -1072,7 +1092,7 @@ function getBoxedBase(value, ctx, keys, constructor, tag) {
10721092
}
10731093
if (keys.length !== 0 || ctx.stylize === stylizeNoColor)
10741094
return base;
1075-
return ctx.stylize(base, type.toLowerCase());
1095+
return ctx.stylize(base, StringPrototypeToLowerCase(type));
10761096
}
10771097

10781098
function getClassBase(value, constructor, tag) {
@@ -1287,11 +1307,11 @@ function groupArrayElements(ctx, output, value) {
12871307
lineMaxLength += separatorSpace;
12881308
maxLineLength[i] = lineMaxLength;
12891309
}
1290-
let order = 'padStart';
1310+
let order = StringPrototypePadStart;
12911311
if (value !== undefined) {
12921312
for (let i = 0; i < output.length; i++) {
12931313
if (typeof value[i] !== 'number' && typeof value[i] !== 'bigint') {
1294-
order = 'padEnd';
1314+
order = StringPrototypePadEnd;
12951315
break;
12961316
}
12971317
}
@@ -1307,21 +1327,21 @@ function groupArrayElements(ctx, output, value) {
13071327
// done line by line as some lines might contain more colors than
13081328
// others.
13091329
const padding = maxLineLength[j - i] + output[j].length - dataLen[j];
1310-
str += `${output[j]}, `[order](padding, ' ');
1330+
str += order(`${output[j]}, `, padding, ' ');
13111331
}
1312-
if (order === 'padStart') {
1332+
if (order === StringPrototypePadStart) {
13131333
const padding = maxLineLength[j - i] +
13141334
output[j].length -
13151335
dataLen[j] -
13161336
separatorSpace;
1317-
str += output[j].padStart(padding, ' ');
1337+
str += StringPrototypePadStart(output[j], padding, ' ');
13181338
} else {
13191339
str += output[j];
13201340
}
1321-
tmp.push(str);
1341+
ArrayPrototypePush(tmp, str);
13221342
}
13231343
if (ctx.maxArrayLength < output.length) {
1324-
tmp.push(output[outputLength]);
1344+
ArrayPrototypePush(tmp, output[outputLength]);
13251345
}
13261346
output = tmp;
13271347
}
@@ -1458,8 +1478,9 @@ function formatArrayBuffer(ctx, value) {
14581478
}
14591479
if (hexSlice === undefined)
14601480
hexSlice = uncurryThis(require('buffer').Buffer.prototype.hexSlice);
1461-
let str = hexSlice(buffer, 0, MathMin(ctx.maxArrayLength, buffer.length))
1462-
.replace(/(.{2})/g, '$1 ').trim();
1481+
let str = StringPrototypeTrim(StringPrototypeReplace(
1482+
hexSlice(buffer, 0, MathMin(ctx.maxArrayLength, buffer.length)),
1483+
/(.{2})/g, '$1 '));
14631484
const remaining = buffer.length - ctx.maxArrayLength;
14641485
if (remaining > 0)
14651486
str += ` ... ${remaining} more byte${remaining > 1 ? 's' : ''}`;
@@ -1508,7 +1529,7 @@ function formatTypedArray(value, length, ctx, ignored, recurseTimes) {
15081529
'buffer'
15091530
]) {
15101531
const str = formatValue(ctx, value[key], recurseTimes, true);
1511-
output.push(`[${key}]: ${str}`);
1532+
ArrayPrototypePush(output, `[${key}]: ${str}`);
15121533
}
15131534
ctx.indentationLvl -= 2;
15141535
}
@@ -1519,7 +1540,7 @@ function formatSet(value, ctx, ignored, recurseTimes) {
15191540
const output = [];
15201541
ctx.indentationLvl += 2;
15211542
for (const v of value) {
1522-
output.push(formatValue(ctx, v, recurseTimes));
1543+
ArrayPrototypePush(output, formatValue(ctx, v, recurseTimes));
15231544
}
15241545
ctx.indentationLvl -= 2;
15251546
return output;
@@ -1539,7 +1560,7 @@ function formatMap(value, ctx, ignored, recurseTimes) {
15391560
function formatSetIterInner(ctx, recurseTimes, entries, state) {
15401561
const maxArrayLength = MathMax(ctx.maxArrayLength, 0);
15411562
const maxLength = MathMin(maxArrayLength, entries.length);
1542-
let output = new Array(maxLength);
1563+
const output = new Array(maxLength);
15431564
ctx.indentationLvl += 2;
15441565
for (let i = 0; i < maxLength; i++) {
15451566
output[i] = formatValue(ctx, entries[i], recurseTimes);
@@ -1549,11 +1570,12 @@ function formatSetIterInner(ctx, recurseTimes, entries, state) {
15491570
// Sort all entries to have a halfway reliable output (if more entries than
15501571
// retrieved ones exist, we can not reliably return the same output) if the
15511572
// output is not sorted anyway.
1552-
output = output.sort();
1573+
ArrayPrototypeSort(output);
15531574
}
15541575
const remaining = entries.length - maxLength;
15551576
if (remaining > 0) {
1556-
output.push(`... ${remaining} more item${remaining > 1 ? 's' : ''}`);
1577+
ArrayPrototypePush(output,
1578+
`... ${remaining} more item${remaining > 1 ? 's' : ''}`);
15571579
}
15581580
return output;
15591581
}
@@ -1661,7 +1683,7 @@ function formatProperty(ctx, value, recurseTimes, key, type, desc,
16611683
(ctx.getters === 'get' && desc.set === undefined) ||
16621684
(ctx.getters === 'set' && desc.set !== undefined))) {
16631685
try {
1664-
const tmp = ReflectApply(desc.get, original, []);
1686+
const tmp = FunctionPrototypeCall(desc.get, original);
16651687
ctx.indentationLvl += 2;
16661688
if (tmp === null) {
16671689
str = `${s(`[${label}:`, sp)} ${s('null', 'null')}${s(']', sp)}`;
@@ -1688,11 +1710,16 @@ function formatProperty(ctx, value, recurseTimes, key, type, desc,
16881710
return str;
16891711
}
16901712
if (typeof key === 'symbol') {
1691-
const tmp = key.toString().replace(strEscapeSequencesReplacer, escapeFn);
1713+
const tmp = StringPrototypeReplace(
1714+
SymbolPrototypeToString(key),
1715+
strEscapeSequencesReplacer, escapeFn
1716+
);
16921717
name = `[${ctx.stylize(tmp, 'symbol')}]`;
16931718
} else if (desc.enumerable === false) {
1694-
name = `[${key.replace(strEscapeSequencesReplacer, escapeFn)}]`;
1695-
} else if (keyStrRegExp.test(key)) {
1719+
const tmp = StringPrototypeReplace(key,
1720+
strEscapeSequencesReplacer, escapeFn);
1721+
name = `[${tmp}]`;
1722+
} else if (RegExpPrototypeTest(keyStrRegExp, key)) {
16961723
name = ctx.stylize(key, 'name');
16971724
} else {
16981725
name = ctx.stylize(strEscape(key), 'string');
@@ -1721,7 +1748,7 @@ function isBelowBreakLength(ctx, output, start, base) {
17211748
}
17221749
}
17231750
// Do not line up properties on the same line if `base` contains line breaks.
1724-
return base === '' || !base.includes('\n');
1751+
return base === '' || !StringPrototypeIncludes(base, '\n');
17251752
}
17261753

17271754
function reduceToSingleString(
@@ -1764,7 +1791,7 @@ function reduceToSingleString(
17641791
}
17651792
}
17661793
// Line up each entry on an individual line.
1767-
const indentation = `\n${' '.repeat(ctx.indentationLvl)}`;
1794+
const indentation = `\n${StringPrototypeRepeat(' ', ctx.indentationLvl)}`;
17681795
return `${base ? `${base} ` : ''}${braces[0]}${indentation} ` +
17691796
`${join(output, `,${indentation} `)}${indentation}${braces[1]}`;
17701797
}
@@ -1774,7 +1801,7 @@ function reduceToSingleString(
17741801
return `${braces[0]}${base ? ` ${base}` : ''} ${join(output, ', ')} ` +
17751802
braces[1];
17761803
}
1777-
const indentation = ' '.repeat(ctx.indentationLvl);
1804+
const indentation = StringPrototypeRepeat(' ', ctx.indentationLvl);
17781805
// If the opening "brace" is too large, like in the case of "Set {",
17791806
// we need to force the first item to be on the next line or the
17801807
// items will not line up correctly.
@@ -1816,7 +1843,8 @@ function hasBuiltInToString(value) {
18161843
builtInObjects.has(descriptor.value.name);
18171844
}
18181845

1819-
const firstErrorLine = (error) => error.message.split('\n')[0];
1846+
const firstErrorLine = (error) =>
1847+
StringPrototypeSplit(error.message, '\n', 1)[0];
18201848
let CIRCULAR_ERROR_MESSAGE;
18211849
function tryStringify(arg) {
18221850
try {
@@ -1864,8 +1892,8 @@ function formatWithOptionsInternal(inspectOptions, ...args) {
18641892
let lastPos = 0;
18651893

18661894
for (let i = 0; i < first.length - 1; i++) {
1867-
if (first.charCodeAt(i) === 37) { // '%'
1868-
const nextChar = first.charCodeAt(++i);
1895+
if (StringPrototypeCharCodeAt(first, i) === 37) { // '%'
1896+
const nextChar = StringPrototypeCharCodeAt(first, ++i);
18691897
if (a + 1 !== args.length) {
18701898
switch (nextChar) {
18711899
case 115: // 's'
@@ -1936,19 +1964,19 @@ function formatWithOptionsInternal(inspectOptions, ...args) {
19361964
tempStr = '';
19371965
break;
19381966
case 37: // '%'
1939-
str += first.slice(lastPos, i);
1967+
str += StringPrototypeSlice(first, lastPos, i);
19401968
lastPos = i + 1;
19411969
continue;
19421970
default: // Any other character is not a correct placeholder
19431971
continue;
19441972
}
19451973
if (lastPos !== i - 1) {
1946-
str += first.slice(lastPos, i - 1);
1974+
str += StringPrototypeSlice(first, lastPos, i - 1);
19471975
}
19481976
str += tempStr;
19491977
lastPos = i + 1;
19501978
} else if (nextChar === 37) {
1951-
str += first.slice(lastPos, i);
1979+
str += StringPrototypeSlice(first, lastPos, i);
19521980
lastPos = i + 1;
19531981
}
19541982
}
@@ -1957,7 +1985,7 @@ function formatWithOptionsInternal(inspectOptions, ...args) {
19571985
a++;
19581986
join = ' ';
19591987
if (lastPos < first.length) {
1960-
str += first.slice(lastPos);
1988+
str += StringPrototypeSlice(first, lastPos);
19611989
}
19621990
}
19631991
}
@@ -2005,9 +2033,9 @@ if (internalBinding('config').hasIntl) {
20052033

20062034
if (removeControlChars)
20072035
str = stripVTControlCharacters(str);
2008-
str = str.normalize('NFC');
2036+
str = StringPrototypeNormalize(str, 'NFC');
20092037
for (const char of new SafeStringIterator(str)) {
2010-
const code = char.codePointAt(0);
2038+
const code = StringPrototypeCodePointAt(char, 0);
20112039
if (isFullWidthCodePoint(code)) {
20122040
width += 2;
20132041
} else if (!isZeroWidthCodePoint(code)) {

‎lib/internal/util/inspector.js

+12-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
'use strict';
22

33
const {
4+
ArrayPrototypeConcat,
5+
FunctionPrototypeBind,
46
ObjectDefineProperty,
57
ObjectKeys,
68
} = primordials;
@@ -27,8 +29,10 @@ function installConsoleExtensions(commandLineApi) {
2729
const { makeRequireFunction } = require('internal/modules/cjs/helpers');
2830
const consoleAPIModule = new CJSModule('<inspector console>');
2931
const cwd = tryGetCwd();
30-
consoleAPIModule.paths =
31-
CJSModule._nodeModulePaths(cwd).concat(CJSModule.globalPaths);
32+
consoleAPIModule.paths = ArrayPrototypeConcat(
33+
CJSModule._nodeModulePaths(cwd),
34+
CJSModule.globalPaths
35+
);
3236
commandLineApi.require = makeRequireFunction(consoleAPIModule);
3337
}
3438

@@ -40,9 +44,12 @@ function wrapConsole(consoleFromNode, consoleFromVM) {
4044
// then wrap these two methods into one. Native wrapper will preserve
4145
// the original stack.
4246
if (consoleFromNode.hasOwnProperty(key)) {
43-
consoleFromNode[key] = consoleCall.bind(consoleFromNode,
44-
consoleFromVM[key],
45-
consoleFromNode[key]);
47+
consoleFromNode[key] = FunctionPrototypeBind(
48+
consoleCall,
49+
consoleFromNode,
50+
consoleFromVM[key],
51+
consoleFromNode[key]
52+
);
4653
ObjectDefineProperty(consoleFromNode[key], 'name', {
4754
value: key
4855
});

‎lib/util.js

+18-7
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,16 @@
2323

2424
const {
2525
ArrayIsArray,
26+
ArrayPrototypeJoin,
27+
ArrayPrototypePop,
2628
Date,
29+
DatePrototypeGetDate,
30+
DatePrototypeGetHours,
31+
DatePrototypeGetMinutes,
32+
DatePrototypeGetMonth,
33+
DatePrototypeGetSeconds,
2734
Error,
35+
FunctionPrototypeBind,
2836
NumberIsSafeInteger,
2937
ObjectDefineProperties,
3038
ObjectDefineProperty,
@@ -33,6 +41,7 @@ const {
3341
ObjectPrototypeToString,
3442
ObjectSetPrototypeOf,
3543
ReflectApply,
44+
StringPrototypePadStart,
3645
} = primordials;
3746

3847
const {
@@ -110,7 +119,7 @@ function isPrimitive(arg) {
110119
}
111120

112121
function pad(n) {
113-
return n.toString().padStart(2, '0');
122+
return StringPrototypePadStart(n.toString(), 2, '0');
114123
}
115124

116125
const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
@@ -119,10 +128,12 @@ const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
119128
// 26 Feb 16:19:34
120129
function timestamp() {
121130
const d = new Date();
122-
const time = [pad(d.getHours()),
123-
pad(d.getMinutes()),
124-
pad(d.getSeconds())].join(':');
125-
return [d.getDate(), months[d.getMonth()], time].join(' ');
131+
const t = ArrayPrototypeJoin([
132+
pad(DatePrototypeGetHours(d)),
133+
pad(DatePrototypeGetMinutes(d)),
134+
pad(DatePrototypeGetSeconds(d)),
135+
], ':');
136+
return `${DatePrototypeGetDate(d)} ${months[DatePrototypeGetMonth(d)]} ${t}`;
126137
}
127138

128139
let console;
@@ -201,11 +212,11 @@ function callbackify(original) {
201212
// the promise is actually somehow related to the callback's execution
202213
// and that the callback throwing will reject the promise.
203214
function callbackified(...args) {
204-
const maybeCb = args.pop();
215+
const maybeCb = ArrayPrototypePop(args);
205216
if (typeof maybeCb !== 'function') {
206217
throw new ERR_INVALID_ARG_TYPE('last argument', 'Function', maybeCb);
207218
}
208-
const cb = (...args) => { ReflectApply(maybeCb, this, args); };
219+
const cb = FunctionPrototypeBind(maybeCb, this);
209220
// In true node style we process the callback on `nextTick` with all the
210221
// implications (stack, `uncaughtException`, `async_hooks`)
211222
ReflectApply(original, this, args)

0 commit comments

Comments
 (0)
Please sign in to comment.