Skip to content

Commit 8f2cfc9

Browse files
committed
Make use of JS rest and spread operators throughout the codebase. NFC
Following up on #21270. These operators were introduced way before our current default set of browser versions. Anyone targeting an browser so old as to not support these will already be on the transpilation path.
1 parent 21f2533 commit 8f2cfc9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+130
-144
lines changed

src/cpuprofiler.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -580,7 +580,7 @@ var emscriptenCpuProfiler = {
580580
var realf = 'real_' + f;
581581
glCtx[realf] = glCtx[f];
582582
var numArgs = this.webGLFunctionLength(f); // On Firefox & Chrome, could do "glCtx[realf].length", but that doesn't work on Edge, which always reports 0.
583-
// Accessing 'arguments' is super slow, so to avoid overhead, statically reason the number of arguments.
583+
// Accessing 'arguments'/'...' is super slow, so to avoid overhead, statically reason the number of arguments.
584584
switch (numArgs) {
585585
case 0: glCtx[f] = () => { this.enterSection(section); var ret = glCtx[realf](); this.endSection(section); return ret; }; break;
586586
case 1: glCtx[f] = (a1) => { this.enterSection(section); var ret = glCtx[realf](a1); this.endSection(section); return ret; }; break;

src/embind/embind.js

+19-23
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,12 @@ var LibraryEmbind = {
9898
if (undefined === proto[methodName].overloadTable) {
9999
var prevFunc = proto[methodName];
100100
// Inject an overload resolver function that routes to the appropriate overload based on the number of arguments.
101-
proto[methodName] = function() {
101+
proto[methodName] = function(...args) {
102102
// TODO This check can be removed in -O3 level "unsafe" optimizations.
103-
if (!proto[methodName].overloadTable.hasOwnProperty(arguments.length)) {
104-
throwBindingError(`Function '${humanName}' called with an invalid number of arguments (${arguments.length}) - expects one of (${proto[methodName].overloadTable})!`);
103+
if (!proto[methodName].overloadTable.hasOwnProperty(args.length)) {
104+
throwBindingError(`Function '${humanName}' called with an invalid number of arguments (${args.length}) - expects one of (${proto[methodName].overloadTable})!`);
105105
}
106-
return proto[methodName].overloadTable[arguments.length].apply(this, arguments);
106+
return proto[methodName].overloadTable[args.length].apply(this, args);
107107
};
108108
// Move the previous function into the overload table.
109109
proto[methodName].overloadTable = [];
@@ -818,9 +818,9 @@ var LibraryEmbind = {
818818
var argsWired = new Array(expectedArgCount);
819819
var invokerFuncArgs = [];
820820
var destructors = [];
821-
var invokerFn = function() {
822-
if (arguments.length !== expectedArgCount) {
823-
throwBindingError(`function ${humanName} called with ${arguments.length} arguments, expected ${expectedArgCount}`);
821+
var invokerFn = function(...args) {
822+
if (args.length !== expectedArgCount) {
823+
throwBindingError(`function ${humanName} called with ${args.length} arguments, expected ${expectedArgCount}`);
824824
}
825825
#if EMSCRIPTEN_TRACING
826826
Module.emscripten_trace_enter_context(`embind::${humanName}`);
@@ -834,11 +834,11 @@ var LibraryEmbind = {
834834
invokerFuncArgs[1] = thisWired;
835835
}
836836
for (var i = 0; i < expectedArgCount; ++i) {
837-
argsWired[i] = argTypes[i + 2]['toWireType'](destructors, arguments[i]);
837+
argsWired[i] = argTypes[i + 2]['toWireType'](destructors, args[i]);
838838
invokerFuncArgs.push(argsWired[i]);
839839
}
840840

841-
var rv = cppInvokerFunc.apply(null, invokerFuncArgs);
841+
var rv = cppInvokerFunc(...invokerFuncArgs);
842842

843843
function onDone(rv) {
844844
if (needsDestructorStack) {
@@ -896,11 +896,11 @@ var LibraryEmbind = {
896896

897897
#if EMBIND_AOT
898898
var signature = createJsInvokerSignature(argTypes, isClassMethodFunc, returns, isAsync);
899-
var invokerFn = InvokerFunctions[signature].apply(null, closureArgs);
899+
var invokerFn = InvokerFunctions[signature](...closureArgs);
900900
#else
901901
let [args, invokerFnBody] = createJsInvoker(argTypes, isClassMethodFunc, returns, isAsync);
902902
args.push(invokerFnBody);
903-
var invokerFn = newFunc(Function, args).apply(null, closureArgs);
903+
var invokerFn = newFunc(Function, args)(...closureArgs);
904904
#endif
905905
#endif
906906
return createNamedFunction(humanName, invokerFn);
@@ -1765,18 +1765,18 @@ var LibraryEmbind = {
17651765
basePrototype = ClassHandle.prototype;
17661766
}
17671767

1768-
var constructor = createNamedFunction(name, function() {
1768+
var constructor = createNamedFunction(name, function(...args) {
17691769
if (Object.getPrototypeOf(this) !== instancePrototype) {
17701770
throw new BindingError("Use 'new' to construct " + name);
17711771
}
17721772
if (undefined === registeredClass.constructor_body) {
17731773
throw new BindingError(name + " has no accessible constructor");
17741774
}
1775-
var body = registeredClass.constructor_body[arguments.length];
1775+
var body = registeredClass.constructor_body[args.length];
17761776
if (undefined === body) {
1777-
throw new BindingError(`Tried to invoke ctor of ${name} with invalid number of parameters (${arguments.length}) - expected (${Object.keys(registeredClass.constructor_body).toString()}) parameters instead!`);
1777+
throw new BindingError(`Tried to invoke ctor of ${name} with invalid number of parameters (${args.length}) - expected (${Object.keys(registeredClass.constructor_body).toString()}) parameters instead!`);
17781778
}
1779-
return body.apply(this, arguments);
1779+
return body.apply(this, args);
17801780
});
17811781

17821782
var instancePrototype = Object.create(basePrototype, {
@@ -2197,14 +2197,12 @@ var LibraryEmbind = {
21972197
wrapperType = requireRegisteredType(wrapperType, 'wrapper');
21982198
properties = Emval.toValue(properties);
21992199

2200-
var arraySlice = [].slice;
2201-
22022200
var registeredClass = wrapperType.registeredClass;
22032201
var wrapperPrototype = registeredClass.instancePrototype;
22042202
var baseClass = registeredClass.baseClass;
22052203
var baseClassPrototype = baseClass.instancePrototype;
22062204
var baseConstructor = registeredClass.baseClass.constructor;
2207-
var ctor = createNamedFunction(constructorName, function() {
2205+
var ctor = createNamedFunction(constructorName, function(...args) {
22082206
registeredClass.baseClass.pureVirtualFunctions.forEach(function(name) {
22092207
if (this[name] === baseClassPrototype[name]) {
22102208
throw new PureVirtualError(`Pure virtual function ${name} must be implemented in JavaScript`);
@@ -2214,19 +2212,17 @@ var LibraryEmbind = {
22142212
Object.defineProperty(this, '__parent', {
22152213
value: wrapperPrototype
22162214
});
2217-
this["__construct"].apply(this, arraySlice.call(arguments));
2215+
this["__construct"](...args);
22182216
});
22192217

22202218
// It's a little nasty that we're modifying the wrapper prototype here.
22212219

2222-
wrapperPrototype["__construct"] = function __construct() {
2220+
wrapperPrototype["__construct"] = function __construct(...args) {
22232221
if (this === wrapperPrototype) {
22242222
throwBindingError("Pass correct 'this' to __construct");
22252223
}
22262224

2227-
var inner = baseConstructor["implement"].apply(
2228-
undefined,
2229-
[this].concat(arraySlice.call(arguments)));
2225+
var inner = baseConstructor["implement"](this, ...args);
22302226
detachFinalizer(inner);
22312227
var $$ = inner.$$;
22322228
inner["notifyOnDestruction"]();

src/embind/emval.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ var LibraryEmVal = {
369369
"};\n";
370370

371371
params.push(functionBody);
372-
var invokerFunction = newFunc(Function, params).apply(null, args);
372+
var invokerFunction = newFunc(Function, params)(...args);
373373
#endif
374374
var functionName = `methodCaller<(${types.map(t => t.name).join(', ')}) => ${retType.name}>`;
375375
return emval_addMethodCaller(createNamedFunction(functionName, invokerFunction));

src/jsifier.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -238,9 +238,9 @@ ${argConvertions}
238238
if (LIBRARY_DEBUG && !isJsOnlySymbol(symbol)) {
239239
snippet = modifyJSFunction(snippet, (args, body, async) => `\
240240
function(${args}) {
241-
var ret = (function() { if (runtimeDebug) err("[library call:${mangled}: " + Array.prototype.slice.call(arguments).map(prettyPrint) + "]");
241+
var ret = (() => { if (runtimeDebug) err("[library call:${mangled}: " + Array.prototype.slice.call(arguments).map(prettyPrint) + "]");
242242
${body}
243-
}).apply(this, arguments);
243+
})();
244244
if (runtimeDebug && typeof ret != "undefined") err(" [ return:" + prettyPrint(ret));
245245
return ret;
246246
}`);
@@ -444,8 +444,8 @@ function(${args}) {
444444
if (ASSERTIONS) {
445445
assertion += `if (!${target} || ${target}.stub) abort("external symbol '${symbol}' is missing. perhaps a side module was not linked in? if this function was expected to arrive from a system library, try to build the MAIN_MODULE with EMCC_FORCE_STDLIBS=1 in the environment");\n`;
446446
}
447-
const functionBody = assertion + `return ${target}.apply(null, arguments);`;
448-
LibraryManager.library[symbol] = new Function(functionBody);
447+
const functionBody = assertion + `return ${target}(...args);`;
448+
LibraryManager.library[symbol] = new Function('...args', functionBody);
449449
isStub = true;
450450
}
451451
}

src/library.js

+6-12
Original file line numberDiff line numberDiff line change
@@ -2874,7 +2874,7 @@ addToLibrary({
28742874
#if ASSERTIONS
28752875
assert(ASM_CONSTS.hasOwnProperty(code), `No EM_ASM constant found at address ${code}. The loaded WebAssembly file is likely out of sync with the generated JavaScript.`);
28762876
#endif
2877-
return ASM_CONSTS[code].apply(null, args);
2877+
return ASM_CONSTS[code](...args);
28782878
},
28792879

28802880
emscripten_asm_const_int__deps: ['$runEmAsmFunction'],
@@ -2917,7 +2917,7 @@ addToLibrary({
29172917
#if ASSERTIONS
29182918
assert(ASM_CONSTS.hasOwnProperty(code), `No EM_ASM constant found at address ${code}. The loaded WebAssembly file is likely out of sync with the generated JavaScript.`);
29192919
#endif
2920-
return ASM_CONSTS[code].apply(null, args);
2920+
return ASM_CONSTS[code](...args);
29212921
},
29222922
emscripten_asm_const_int_sync_on_main_thread__deps: ['$runMainThreadEmAsm'],
29232923
emscripten_asm_const_int_sync_on_main_thread: (code, sigPtr, argbuf) => {
@@ -3100,7 +3100,7 @@ addToLibrary({
31003100
#endif
31013101
var f = Module['dynCall_' + sig];
31023102
#endif
3103-
return args && args.length ? f.apply(null, [ptr].concat(args)) : f.call(null, ptr);
3103+
return f(ptr, ...args);
31043104
},
31053105
$dynCall__deps: ['$dynCallLegacy', '$getWasmTableEntry'],
31063106
#endif
@@ -3113,16 +3113,10 @@ addToLibrary({
31133113
#if ASSERTIONS && !DYNCALLS
31143114
assert(sig.includes('j') || sig.includes('p'), 'getDynCaller should only be called with i64 sigs')
31153115
#endif
3116-
var argCache = [];
3117-
return function() {
3118-
argCache.length = 0;
3119-
Object.assign(argCache, arguments);
3120-
return dynCall(sig, ptr, argCache);
3121-
};
3116+
return (...args) => dynCall(sig, ptr, args);
31223117
},
31233118

3124-
$dynCall__docs: '/** @param {Object=} args */',
3125-
$dynCall: (sig, ptr, args) => {
3119+
$dynCall: (sig, ptr, args = []) => {
31263120
#if MEMORY64
31273121
// With MEMORY64 we have an additional step to convert `p` arguments to
31283122
// bigint. This is the runtime equivalent of the wrappers we create for wasm
@@ -3145,7 +3139,7 @@ addToLibrary({
31453139
#if ASSERTIONS
31463140
assert(getWasmTableEntry(ptr), `missing table entry in dynCall: ${ptr}`);
31473141
#endif
3148-
var rtn = getWasmTableEntry(ptr).apply(null, args);
3142+
var rtn = getWasmTableEntry(ptr)(...args);
31493143
#endif
31503144
#if MEMORY64
31513145
return sig[0] == 'p' ? Number(rtn) : rtn;

src/library_addfunction.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ addToLibrary({
117117
];
118118
// Write the overall length of the type section followed by the body
119119
uleb128Encode(typeSectionBody.length, bytes);
120-
bytes.push.apply(bytes, typeSectionBody);
120+
bytes.push(...typeSectionBody);
121121

122122
// The rest of the module is static
123123
bytes.push(

src/library_async.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,10 @@ addToLibrary({
6868
}
6969
#endif
7070
#if ASSERTIONS && ASYNCIFY != 2 // We cannot apply assertions with stack switching, as the imports must not be modified from suspender.suspendOnReturnedPromise TODO find a way
71-
imports[x] = function() {
71+
imports[x] = (...args) => {
7272
var originalAsyncifyState = Asyncify.state;
7373
try {
74-
return original.apply(null, arguments);
74+
return original(...args);
7575
} finally {
7676
// Only asyncify-declared imports are allowed to change the
7777
// state.
@@ -130,7 +130,7 @@ addToLibrary({
130130
original = Asyncify.makeAsyncFunction(original);
131131
}
132132
#endif
133-
ret[x] = function() {
133+
ret[x] = (...args) => {
134134
#if ASYNCIFY_DEBUG >= 2
135135
dbg(`ASYNCIFY: ${' '.repeat(Asyncify.exportCallStack.length} try ${x}`);
136136
#endif
@@ -143,9 +143,9 @@ addToLibrary({
143143
// can just call the function with no args at all since and the engine will produce zeros
144144
// for all arguments. However, for i64 arguments we get `undefined cannot be converted to
145145
// BigInt`.
146-
return original.apply(null, Asyncify.saveOrRestoreRewindArguments(x, arguments));
146+
return original(...Asyncify.saveOrRestoreRewindArguments(x, args));
147147
#else
148-
return original.apply(null, arguments);
148+
return original(...args);
149149
#endif
150150
#if ASYNCIFY == 1
151151
} finally {

src/library_ccall.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ addToLibrary({
7777
// Data for a previous async operation that was in flight before us.
7878
var previousAsync = Asyncify.currData;
7979
#endif
80-
var ret = func.apply(null, cArgs);
80+
var ret = func(...cArgs);
8181
function onDone(ret) {
8282
#if ASYNCIFY == 1
8383
runtimeKeepalivePop();

src/library_dylink.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -707,9 +707,9 @@ var LibraryDylink = {
707707
// when first called.
708708
if (!(prop in stubs)) {
709709
var resolved;
710-
stubs[prop] = function() {
710+
stubs[prop] = (...args) => {
711711
resolved ||= resolveSymbol(prop);
712-
return resolved.apply(null, arguments);
712+
return resolved(...args);
713713
};
714714
}
715715
return stubs[prop];

src/library_fs.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,7 @@ FS.staticInit();` +
513513

514514
mounts.push(m);
515515

516-
check.push.apply(check, m.mounts);
516+
check.push(...m.mounts);
517517
}
518518

519519
return mounts;
@@ -1784,9 +1784,9 @@ FS.staticInit();` +
17841784
var keys = Object.keys(node.stream_ops);
17851785
keys.forEach((key) => {
17861786
var fn = node.stream_ops[key];
1787-
stream_ops[key] = function forceLoadLazyFile() {
1787+
stream_ops[key] = (...args) => {
17881788
FS.forceLoadFile(node);
1789-
return fn.apply(null, arguments);
1789+
return fn(...args);
17901790
};
17911791
});
17921792
function writeChunks(stream, buffer, offset, length, position) {

src/library_glemu.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -3580,7 +3580,7 @@ var LibraryGLEmulation = {
35803580
_glEnableVertexAttribArray(vaa);
35813581
}
35823582
for (var vaa in info.vertexAttribPointers) {
3583-
_glVertexAttribPointer.apply(null, info.vertexAttribPointers[vaa]);
3583+
_glVertexAttribPointer(...info.vertexAttribPointers[vaa]);
35843584
}
35853585
for (var attrib in info.enabledClientStates) {
35863586
_glEnableClientState(attrib|0);

src/library_html5.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ var LibraryHTML5 = {
140140
var call = JSEvents.deferredCalls[i];
141141
JSEvents.deferredCalls.splice(i, 1);
142142
--i;
143-
call.targetFunction.apply(null, call.argsList);
143+
call.targetFunction(...call.argsList);
144144
}
145145
},
146146
#endif

src/library_idbfs.js

+3-5
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,8 @@ addToLibrary({
2121
},
2222
DB_VERSION: 21,
2323
DB_STORE_NAME: 'FILE_DATA',
24-
mount: function(mount) {
25-
// reuse all of the core MEMFS functionality
26-
return MEMFS.mount.apply(null, arguments);
27-
},
24+
// reuse all of the core MEMFS functionality
25+
mount: (...args) => MEMFS.mount(...args),
2826
syncfs: (mount, populate, callback) => {
2927
IDBFS.getLocalSet(mount, (err, local) => {
3028
if (err) return callback(err);
@@ -110,7 +108,7 @@ addToLibrary({
110108
}
111109

112110
if (FS.isDir(stat.mode)) {
113-
check.push.apply(check, FS.readdir(path).filter(isRealDir).map(toAbsolute(path)));
111+
check.push(...FS.readdir(path).filter(isRealDir).map(toAbsolute(path)));
114112
}
115113

116114
entries[path] = { 'timestamp': stat.mtime };

src/library_makeDynCall.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ addToLibrary({
3131

3232
var typeSection = [0x01 /* Type section code */];
3333
uleb128Encode(typeSectionBody.length, typeSection); // length of section in bytes
34-
typeSection.push.apply(typeSection, typeSectionBody);
34+
typeSection.push(...typeSectionBody);
3535
sections.push(typeSection);
3636

3737
var importSection = [
@@ -133,10 +133,10 @@ if (sig[0] === "j") {
133133

134134
var codeBody = [0x01]; // one code
135135
uleb128Encode(convert_code.length, codeBody);
136-
codeBody.push.apply(codeBody, convert_code);
136+
codeBody.push(...convert_code);
137137
var codeSection = [0x0A /* Code section code */];
138138
uleb128Encode(codeBody.length, codeSection);
139-
codeSection.push.apply(codeSection, codeBody);
139+
codeSection.push(...codeBody);
140140
sections.push(codeSection);
141141

142142
var bytes = new Uint8Array([].concat.apply([], sections));

src/library_math.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ addToLibrary({
2626
for (var i = 0; i < count; ++i) {
2727
args.push({{{ makeGetValue('varargs', `i * ${getNativeTypeSize('double')}`, 'double') }}});
2828
}
29-
return Math.hypot.apply(null, args);
29+
return Math.hypot(...args);
3030
},
3131
emscripten_math_sin: (x) => Math.sin(x),
3232
emscripten_math_sinh: (x) => Math.sinh(x),

src/library_nodefs.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ addToLibrary({
8787
}
8888
parts.push(node.mount.opts.root);
8989
parts.reverse();
90-
return PATH.join.apply(null, parts);
90+
return PATH.join(...parts);
9191
},
9292
// This maps the integer permission modes from http://linux.die.net/man/3/open
9393
// to node.js-specific file open permission strings at http://nodejs.org/api/fs.html#fs_fs_open_path_flags_mode_callback

0 commit comments

Comments
 (0)