Skip to content

Commit 60dab86

Browse files
ExE-Bossaduh95
andcommitted
lib: add bound apply variants of varargs primordials
Co-authored-by: Antoine du Hamel <[email protected]>
1 parent e3e054d commit 60dab86

File tree

4 files changed

+55
-12
lines changed

4 files changed

+55
-12
lines changed

lib/internal/per_context/primordials.js

Lines changed: 48 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,28 @@ const {
2121
// `uncurryThis` is equivalent to `func => Function.prototype.call.bind(func)`.
2222
// It is using `bind.bind(call)` to avoid using `Function.prototype.bind`
2323
// and `Function.prototype.call` after it may have been mutated by users.
24-
const { bind, call } = Function.prototype;
24+
const { apply, bind, call } = Function.prototype;
2525
const uncurryThis = bind.bind(call);
2626
primordials.uncurryThis = uncurryThis;
2727

28+
const applyBind = bind.bind(apply);
29+
primordials.applyBind = applyBind;
30+
31+
// Methods that accept a variable number of arguments, and thus it's useful to
32+
// also create `${prefix}${key}Apply`, which uses `Function.prototype.apply`,
33+
// instead of `Function.prototype.call`, and thus doesn't require iterator
34+
// destructuring.
35+
const varargsMethods = [
36+
'ArrayPrototypePush',
37+
'ArrayPrototypeUnshift',
38+
'ArrayOf',
39+
'MathMax',
40+
'MathMin',
41+
'MathHypot',
42+
'StringPrototypeConcat',
43+
'TypedArrayOf',
44+
];
45+
2846
function getNewKey(key) {
2947
return typeof key === 'symbol' ?
3048
`Symbol${key.description[7].toUpperCase()}${key.description.slice(8)}` :
@@ -51,7 +69,13 @@ function copyPropsRenamed(src, dest, prefix) {
5169
if ('get' in desc) {
5270
copyAccessor(dest, prefix, newKey, desc);
5371
} else {
54-
ReflectDefineProperty(dest, `${prefix}${newKey}`, desc);
72+
const name = `${prefix}${newKey}`;
73+
ReflectDefineProperty(dest, name, desc);
74+
if (varargsMethods.includes(name)) {
75+
ReflectDefineProperty(dest, `${name}Apply`, {
76+
value: applyBind(desc.value, src),
77+
});
78+
}
5579
}
5680
}
5781
}
@@ -63,10 +87,18 @@ function copyPropsRenamedBound(src, dest, prefix) {
6387
if ('get' in desc) {
6488
copyAccessor(dest, prefix, newKey, desc);
6589
} else {
66-
if (typeof desc.value === 'function') {
67-
desc.value = desc.value.bind(src);
90+
const { value } = desc;
91+
if (typeof value === 'function') {
92+
desc.value = value.bind(src);
93+
}
94+
95+
const name = `${prefix}${newKey}`;
96+
ReflectDefineProperty(dest, name, desc);
97+
if (varargsMethods.includes(name)) {
98+
ReflectDefineProperty(dest, `${name}Apply`, {
99+
value: applyBind(value, src),
100+
});
68101
}
69-
ReflectDefineProperty(dest, `${prefix}${newKey}`, desc);
70102
}
71103
}
72104
}
@@ -78,10 +110,18 @@ function copyPrototype(src, dest, prefix) {
78110
if ('get' in desc) {
79111
copyAccessor(dest, prefix, newKey, desc);
80112
} else {
81-
if (typeof desc.value === 'function') {
82-
desc.value = uncurryThis(desc.value);
113+
const { value } = desc;
114+
if (typeof value === 'function') {
115+
desc.value = uncurryThis(value);
116+
}
117+
118+
const name = `${prefix}${newKey}`;
119+
ReflectDefineProperty(dest, name, desc);
120+
if (varargsMethods.includes(name)) {
121+
ReflectDefineProperty(dest, `${name}Apply`, {
122+
value: applyBind(value, src),
123+
});
83124
}
84-
ReflectDefineProperty(dest, `${prefix}${newKey}`, desc);
85125
}
86126
}
87127
}

lib/internal/process/per_thread.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const {
88
ArrayIsArray,
99
ArrayPrototypeMap,
1010
ArrayPrototypePush,
11+
ArrayPrototypePushApply,
1112
ArrayPrototypeSplice,
1213
BigUint64Array,
1314
Float64Array,
@@ -274,7 +275,7 @@ function buildAllowedFlags() {
274275
if (recursiveExpansion) {
275276
if (recursiveExpansion[0] === to)
276277
ArrayPrototypeSplice(recursiveExpansion, 0, 1);
277-
ArrayPrototypePush(expansion, ...recursiveExpansion);
278+
ArrayPrototypePushApply(expansion, recursiveExpansion);
278279
continue;
279280
}
280281
isAccepted = options.get(to).envVarSettings === kAllowedInEnvironment;

lib/internal/util/inspect.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ const {
66
ArrayPrototypeFilter,
77
ArrayPrototypeForEach,
88
ArrayPrototypePush,
9+
ArrayPrototypePushApply,
910
ArrayPrototypeSort,
1011
ArrayPrototypeUnshift,
1112
BigIntPrototypeValueOf,
@@ -664,7 +665,7 @@ function getKeys(value, showHidden) {
664665
if (showHidden) {
665666
keys = ObjectGetOwnPropertyNames(value);
666667
if (symbols.length !== 0)
667-
ArrayPrototypePush(keys, ...symbols);
668+
ArrayPrototypePushApply(keys, symbols);
668669
} else {
669670
// This might throw if `value` is a Module Namespace Object from an
670671
// unevaluated module, but we don't want to perform the actual type
@@ -680,7 +681,7 @@ function getKeys(value, showHidden) {
680681
}
681682
if (symbols.length !== 0) {
682683
const filter = (key) => ObjectPrototypePropertyIsEnumerable(value, key);
683-
ArrayPrototypePush(keys, ...ArrayPrototypeFilter(symbols, filter));
684+
ArrayPrototypePushApply(keys, ArrayPrototypeFilter(symbols, filter));
684685
}
685686
}
686687
return keys;

lib/repl.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ const {
5252
ArrayPrototypeMap,
5353
ArrayPrototypePop,
5454
ArrayPrototypePush,
55+
ArrayPrototypePushApply,
5556
ArrayPrototypeReverse,
5657
ArrayPrototypeShift,
5758
ArrayPrototypeSort,
@@ -1310,7 +1311,7 @@ function complete(line, callback) {
13101311
if (!this.useGlobal) {
13111312
// When the context is not `global`, builtins are not own
13121313
// properties of it.
1313-
ArrayPrototypePush(contextOwnNames, ...globalBuiltins);
1314+
ArrayPrototypePushApply(contextOwnNames, globalBuiltins);
13141315
}
13151316
ArrayPrototypePush(completionGroups, contextOwnNames);
13161317
if (filter !== '') addCommonWords(completionGroups);

0 commit comments

Comments
 (0)