Skip to content

Commit ed58065

Browse files
ExE-Bosstargos
authored andcommitted
lib: add bound apply variants of varargs primordials
Co-authored-by: Antoine du Hamel <duhamelantoine1995@gmail.com> PR-URL: #37005 Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com>
1 parent 67b58f6 commit ed58065

3 files changed

Lines changed: 60 additions & 10 deletions

File tree

‎lib/internal/per_context/primordials.js‎

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,36 @@ 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
constuncurryThis=bind.bind(call);
2626
primordials.uncurryThis=uncurryThis;
2727

28+
// `applyBind` is equivalent to `func => Function.prototype.apply.bind(func)`.
29+
// It is using `bind.bind(apply)` to avoid using `Function.prototype.bind`
30+
// and `Function.prototype.apply` after it may have been mutated by users.
31+
constapplyBind=bind.bind(apply);
32+
primordials.applyBind=applyBind;
33+
34+
// Methods that accept a variable number of arguments, and thus it's useful to
35+
// also create `${prefix}${key}Apply`, which uses `Function.prototype.apply`,
36+
// instead of `Function.prototype.call`, and thus doesn't require iterator
37+
// destructuring.
38+
constvarargsMethods=[
39+
// 'ArrayPrototypeConcat' is omitted, because it performs the spread
40+
// on its own for arrays and array-likes with a truthy
41+
// @@isConcatSpreadable symbol property.
42+
'ArrayOf',
43+
'ArrayPrototypePush',
44+
'ArrayPrototypeUnshift',
45+
// 'FunctionPrototypeCall' is omitted, since there's 'ReflectApply'
46+
// and 'FunctionPrototypeApply'.
47+
'MathHypot',
48+
'MathMax',
49+
'MathMin',
50+
'StringPrototypeConcat',
51+
'TypedArrayOf',
52+
];
53+
2854
functiongetNewKey(key){
2955
returntypeofkey==='symbol' ?
3056
`Symbol${key.description[7].toUpperCase()}${key.description.slice(8)}` :
@@ -51,7 +77,13 @@ function copyPropsRenamed(src, dest, prefix) {
5177
if('get'indesc){
5278
copyAccessor(dest,prefix,newKey,desc);
5379
}else{
54-
ReflectDefineProperty(dest,`${prefix}${newKey}`,desc);
80+
constname=`${prefix}${newKey}`;
81+
ReflectDefineProperty(dest,name,desc);
82+
if(varargsMethods.includes(name)){
83+
ReflectDefineProperty(dest,`${name}Apply`,{
84+
value: applyBind(desc.value,src),
85+
});
86+
}
5587
}
5688
}
5789
}
@@ -63,10 +95,18 @@ function copyPropsRenamedBound(src, dest, prefix) {
6395
if('get'indesc){
6496
copyAccessor(dest,prefix,newKey,desc);
6597
}else{
66-
if(typeofdesc.value==='function'){
67-
desc.value=desc.value.bind(src);
98+
const{ value }=desc;
99+
if(typeofvalue==='function'){
100+
desc.value=value.bind(src);
101+
}
102+
103+
constname=`${prefix}${newKey}`;
104+
ReflectDefineProperty(dest,name,desc);
105+
if(varargsMethods.includes(name)){
106+
ReflectDefineProperty(dest,`${name}Apply`,{
107+
value: applyBind(value,src),
108+
});
68109
}
69-
ReflectDefineProperty(dest,`${prefix}${newKey}`,desc);
70110
}
71111
}
72112
}
@@ -78,10 +118,18 @@ function copyPrototype(src, dest, prefix) {
78118
if('get'indesc){
79119
copyAccessor(dest,prefix,newKey,desc);
80120
}else{
81-
if(typeofdesc.value==='function'){
82-
desc.value=uncurryThis(desc.value);
121+
const{ value }=desc;
122+
if(typeofvalue==='function'){
123+
desc.value=uncurryThis(value);
124+
}
125+
126+
constname=`${prefix}${newKey}`;
127+
ReflectDefineProperty(dest,name,desc);
128+
if(varargsMethods.includes(name)){
129+
ReflectDefineProperty(dest,`${name}Apply`,{
130+
value: applyBind(value),
131+
});
83132
}
84-
ReflectDefineProperty(dest,`${prefix}${newKey}`,desc);
85133
}
86134
}
87135
}

‎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,
@@ -665,7 +666,7 @@ function getKeys(value, showHidden) {
665666
if(showHidden){
666667
keys=ObjectGetOwnPropertyNames(value);
667668
if(symbols.length!==0)
668-
ArrayPrototypePush(keys,...symbols);
669+
ArrayPrototypePushApply(keys,symbols);
669670
}else{
670671
// This might throw if `value` is a Module Namespace Object from an
671672
// unevaluated module, but we don't want to perform the actual type
@@ -681,7 +682,7 @@ function getKeys(value, showHidden) {
681682
}
682683
if(symbols.length!==0){
683684
constfilter=(key)=>ObjectPrototypePropertyIsEnumerable(value,key);
684-
ArrayPrototypePush(keys,...ArrayPrototypeFilter(symbols,filter));
685+
ArrayPrototypePushApply(keys,ArrayPrototypeFilter(symbols,filter));
685686
}
686687
}
687688
returnkeys;

‎lib/repl.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1313,6 +1313,7 @@ function complete(line, callback) {
13131313
if(!this.useGlobal){
13141314
// When the context is not `global`, builtins are not own
13151315
// properties of it.
1316+
// `globalBuiltins` is a `SafeSet`, not an Array-like.
13161317
ArrayPrototypePush(contextOwnNames, ...globalBuiltins);
13171318
}
13181319
ArrayPrototypePush(completionGroups,contextOwnNames);

0 commit comments

Comments
 (0)