Skip to content

Commit 54acead

Browse files
committed
Make use of JS rest and spread operators throughout the codebase. NFC
Following up on emscripten-core#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 c47d060 commit 54acead

Some content is hidden

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

51 files changed

+121
-132
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-21
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,19 @@ var LibraryEmbind = {
22142212
Object.defineProperty(this, '__parent', {
22152213
value: wrapperPrototype
22162214
});
2217-
this["__construct"].apply(this, arraySlice.call(arguments));
2215+
this["__construct"].apply(this, 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

22272225
var inner = baseConstructor["implement"].apply(
22282226
undefined,
2229-
[this].concat(arraySlice.call(arguments)));
2227+
[this].concat(args));
22302228
detachFinalizer(inner);
22312229
var $$ = inner.$$;
22322230
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

+3-3
Original file line numberDiff line numberDiff line change
@@ -237,9 +237,9 @@ ${argConvertions}
237237
if (LIBRARY_DEBUG && !isJsOnlySymbol(symbol)) {
238238
snippet = modifyJSFunction(snippet, (args, body, async) => `\
239239
function(${args}) {
240-
var ret = (function() { if (runtimeDebug) err("[library call:${mangled}: " + Array.prototype.slice.call(arguments).map(prettyPrint) + "]");
240+
var ret = (function(...args) { if (runtimeDebug) err("[library call:${mangled}: " + args.map(prettyPrint) + "]");
241241
${body}
242-
}).apply(this, arguments);
242+
}).call(this, ${args});
243243
if (runtimeDebug && typeof ret != "undefined") err(" [ return:" + prettyPrint(ret));
244244
return ret;
245245
}`);
@@ -443,7 +443,7 @@ function(${args}) {
443443
if (ASSERTIONS) {
444444
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`;
445445
}
446-
const functionBody = assertion + `return ${target}.apply(null, arguments);`;
446+
const functionBody = assertion + `return ${target}(...arguments);`;
447447
LibraryManager.library[symbol] = new Function(functionBody);
448448
isStub = true;
449449
}

src/library.js

+6-11
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,15 +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 */',
3119+
$dynCall__docs: '/** @param {!Array} args */',
31253120
$dynCall: (sig, ptr, args) => {
31263121
#if MEMORY64
31273122
// With MEMORY64 we have an additional step to convert `p` arguments to
@@ -3145,7 +3140,7 @@ addToLibrary({
31453140
#if ASSERTIONS
31463141
assert(getWasmTableEntry(ptr), `missing table entry in dynCall: ${ptr}`);
31473142
#endif
3148-
var rtn = getWasmTableEntry(ptr).apply(null, args);
3143+
var rtn = getWasmTableEntry(ptr)(...args);
31493144
#endif
31503145
#if MEMORY64
31513146
return sig[0] == 'p' ? Number(rtn) : rtn;

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -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

+2-4
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);

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

src/library_nodepath.js

+3-6
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,17 @@ addToLibrary({
1717
normalize: (path) => nodePath['normalize'](path),
1818
dirname: (path) => nodePath['dirname'](path),
1919
basename: (path) => nodePath['basename'](path),
20-
join: function () {
21-
return nodePath['join'].apply(null, arguments);
22-
},
20+
join: (...args) => nodePath['join'](...args),
2321
join2: (l, r) => nodePath['join'](l, r),
2422
},
2523
// The FS-using parts are split out into a separate object, so simple path
2624
// usage does not require the FS.
2725
$PATH_FS__deps: ['$FS'],
2826
$PATH_FS__docs: '/** @type{{resolve: function(...*)}} */',
2927
$PATH_FS: {
30-
resolve: function () {
31-
var paths = Array.prototype.slice.call(arguments, 0);
28+
resolve: (...paths) => {
3229
paths.unshift(FS.cwd());
33-
return nodePath['posix']['resolve'].apply(null, paths);
30+
return nodePath['posix']['resolve'](...paths);
3431
},
3532
relative: (from, to) => nodePath['posix']['relative'](from || FS.cwd(), to || FS.cwd()),
3633
}

0 commit comments

Comments
 (0)