Skip to content

Commit b7e431c

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 b7e431c

37 files changed

+95
-106
lines changed

src/cpuprofiler.js

Lines changed: 1 addition & 1 deletion
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

Lines changed: 16 additions & 18 deletions
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,7 +834,7 @@ 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

@@ -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/jsifier.js

Lines changed: 2 additions & 2 deletions
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+
}).apply(this, ...args);
243243
if (runtimeDebug && typeof ret != "undefined") err(" [ return:" + prettyPrint(ret));
244244
return ret;
245245
}`);

src/library.js

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3113,12 +3113,7 @@ 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

31243119
$dynCall__docs: '/** @param {Object=} args */',

src/library_async.js

Lines changed: 5 additions & 5 deletions
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.apply(null, 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.apply(null, Asyncify.saveOrRestoreRewindArguments(x, args));
147147
#else
148-
return original.apply(null, arguments);
148+
return original.apply(null, args);
149149
#endif
150150
#if ASYNCIFY == 1
151151
} finally {

src/library_fs.js

Lines changed: 2 additions & 2 deletions
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.apply(null, args);
17901790
};
17911791
});
17921792
function writeChunks(stream, buffer, offset, length, position) {

src/library_idbfs.js

Lines changed: 2 additions & 4 deletions
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.apply(null, ...args);
2826
syncfs: (mount, populate, callback) => {
2927
IDBFS.getLocalSet(mount, (err, local) => {
3028
if (err) return callback(err);

src/library_nodepath.js

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,15 @@ 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'].apply(null, 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());
3330
return nodePath['posix']['resolve'].apply(null, paths);
3431
},

src/library_noderawfs.js

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ addToLibrary({
99
$NODERAWFS__postset: `
1010
if (ENVIRONMENT_IS_NODE) {
1111
var _wrapNodeError = function(func) {
12-
return function() {
12+
return function(...args) {
1313
try {
14-
return func.apply(this, arguments)
14+
return func.apply(this, args)
1515
} catch (e) {
1616
if (e.code) {
1717
throw new FS.ErrnoError(ERRNO_CODES[e.code]);
@@ -52,34 +52,34 @@ addToLibrary({
5252
},
5353
// generic function for all node creation
5454
cwd() { return process.cwd(); },
55-
chdir() { process.chdir.apply(void 0, arguments); },
55+
chdir(args) { process.chdir.apply(void 0, args); },
5656
mknod(path, mode) {
5757
if (FS.isDir(path)) {
5858
fs.mkdirSync(path, mode);
5959
} else {
6060
fs.writeFileSync(path, '', { mode: mode });
6161
}
6262
},
63-
mkdir() { fs.mkdirSync.apply(void 0, arguments); },
64-
symlink() { fs.symlinkSync.apply(void 0, arguments); },
65-
rename() { fs.renameSync.apply(void 0, arguments); },
66-
rmdir() { fs.rmdirSync.apply(void 0, arguments); },
67-
readdir() { return ['.', '..'].concat(fs.readdirSync.apply(void 0, arguments)); },
68-
unlink() { fs.unlinkSync.apply(void 0, arguments); },
69-
readlink() { return fs.readlinkSync.apply(void 0, arguments); },
70-
stat() { return fs.statSync.apply(void 0, arguments); },
71-
lstat() { return fs.lstatSync.apply(void 0, arguments); },
72-
chmod() { fs.chmodSync.apply(void 0, arguments); },
63+
mkdir(...args) { fs.mkdirSync.apply(void 0, args); },
64+
symlink(...args) { fs.symlinkSync.apply(void 0, args); },
65+
rename(...args) { fs.renameSync.apply(void 0, args); },
66+
rmdir(...args) { fs.rmdirSync.apply(void 0, args); },
67+
readdir(...args) { return ['.', '..'].concat(fs.readdirSync.apply(void 0, args)); },
68+
unlink(...args) { fs.unlinkSync.apply(void 0, args); },
69+
readlink(...args) { return fs.readlinkSync.apply(void 0, args); },
70+
stat(...args) { return fs.statSync.apply(void 0, args); },
71+
lstat(...args) { return fs.lstatSync.apply(void 0, args); },
72+
chmod(...args) { fs.chmodSync.apply(void 0, args); },
7373
fchmod(fd, mode) {
7474
var stream = FS.getStreamChecked(fd);
7575
fs.fchmodSync(stream.nfd, mode);
7676
},
77-
chown() { fs.chownSync.apply(void 0, arguments); },
77+
chown(...args) { fs.chownSync.apply(void 0, args); },
7878
fchown(fd, owner, group) {
7979
var stream = FS.getStreamChecked(fd);
8080
fs.fchownSync(stream.nfd, owner, group);
8181
},
82-
truncate() { fs.truncateSync.apply(void 0, arguments); },
82+
truncate(...args) { fs.truncateSync.apply(void 0, args); },
8383
ftruncate(fd, len) {
8484
// See https://github.com/nodejs/node/issues/35632
8585
if (len < 0) {

src/library_path.js

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,7 @@ addToLibrary({
7272
if (lastSlash === -1) return path;
7373
return path.substr(lastSlash+1);
7474
},
75-
join: function() {
76-
var paths = Array.prototype.slice.call(arguments);
77-
return PATH.normalize(paths.join('/'));
78-
},
75+
join: (...paths) => PATH.normalize(paths.join('/')),
7976
join2: (l, r) => PATH.normalize(l + '/' + r),
8077
},
8178
// The FS-using parts are split out into a separate object, so simple path
@@ -90,11 +87,11 @@ addToLibrary({
9087
#endif
9188
],
9289
$PATH_FS: {
93-
resolve: function() {
90+
resolve: (...args) => {
9491
var resolvedPath = '',
9592
resolvedAbsolute = false;
96-
for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
97-
var path = (i >= 0) ? arguments[i] : FS.cwd();
93+
for (var i = args.length - 1; i >= -1 && !resolvedAbsolute; i--) {
94+
var path = (i >= 0) ? args[i] : FS.cwd();
9895
// Skip empty and invalid entries
9996
if (typeof path != 'string') {
10097
throw new TypeError('Arguments to path.resolve must be strings');

src/preamble.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -513,14 +513,14 @@ Module['FS_createPreloadedFile'] = FS.createPreloadedFile;
513513

514514
#if ASSERTIONS
515515
function createExportWrapper(name) {
516-
return function() {
516+
return (...args) => {
517517
assert(runtimeInitialized, `native function \`${name}\` called before runtime initialization`);
518518
#if EXIT_RUNTIME
519519
assert(!runtimeExited, `native function \`${name}\` called after runtime exit (use NO_EXIT_RUNTIME to keep it alive after main() exits)`);
520520
#endif
521521
var f = wasmExports[name];
522522
assert(f, `exported native function \`${name}\` not found`);
523-
return f.apply(null, arguments);
523+
return f.apply(null, args);
524524
};
525525
}
526526
#endif
@@ -537,15 +537,15 @@ var abortWrapperDepth = 0;
537537

538538
// Creates a wrapper in a closure so that each wrapper gets it's own copy of 'original'
539539
function makeAbortWrapper(original) {
540-
return function() {
540+
return (...args) => {
541541
// Don't allow this function to be called if we're aborted!
542542
if (ABORT) {
543543
throw "program has already aborted!";
544544
}
545545

546546
abortWrapperDepth += 1;
547547
try {
548-
return original.apply(null, arguments);
548+
return original.apply(null, args);
549549
} catch (e) {
550550
if (
551551
ABORT // rethrow exception if abort() was called in the original function call above
@@ -700,7 +700,7 @@ var wasmOffsetConverter;
700700
{{{ makeModuleReceiveWithVar('loadSplitModule', undefined, 'instantiateSync', true) }}}
701701
var splitModuleProxyHandler = {
702702
get(target, prop, receiver) {
703-
return function() {
703+
return (...args) => {
704704
#if ASYNCIFY == 2
705705
throw new Error('Placeholder function "' + prop + '" should not be called when using JSPI.');
706706
#else
@@ -714,9 +714,9 @@ var splitModuleProxyHandler = {
714714
// When the table is dynamically laid out, the placeholder functions names
715715
// are offsets from the table base. In the main module, the table base is
716716
// always 1.
717-
return wasmTable.get(1 + parseInt(prop)).apply(null, arguments);
717+
return wasmTable.get(1 + parseInt(prop)).apply(null, args);
718718
#else
719-
return wasmTable.get(prop).apply(null, arguments);
719+
return wasmTable.get(prop).apply(null, args);
720720
#endif
721721
#endif
722722
}

src/runtime_debug.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -161,16 +161,16 @@ function prettyPrint(arg) {
161161

162162
#if ASSERTIONS || RUNTIME_DEBUG || AUTODEBUG
163163
// Used by XXXXX_DEBUG settings to output debug messages.
164-
function dbg(text) {
164+
function dbg(...args) {
165165
#if ENVIRONMENT_MAY_BE_NODE && PTHREADS
166166
// Avoid using the console for debugging in multi-threaded node applications
167167
// See https://github.com/emscripten-core/emscripten/issues/14804
168168
if (ENVIRONMENT_IS_NODE) {
169-
fs.writeSync(2, Array.from(arguments).join(' ') + '\n');
169+
fs.writeSync(2, args.join(' ') + '\n');
170170
} else
171171
#endif
172172
// TODO(sbc): Make this configurable somehow. Its not always convenient for
173173
// logging to show up as warnings.
174-
console.warn.apply(console, arguments);
174+
console.warn.apply(console, args);
175175
}
176176
#endif

src/shell.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@
3838
print: (function() {
3939
var element = document.getElementById('output');
4040
if (element) element.value = ''; // clear browser cache
41-
return function(text) {
42-
if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' ');
41+
return function(...args) => {
42+
text = args.join(' ');
4343
// These replacements are necessary if you render to raw HTML
4444
//text = text.replace(/&/g, "&amp;");
4545
//text = text.replace(/</g, "&lt;");

0 commit comments

Comments
 (0)