From f206911ef6c85b1d18e3780dff695f816c284705 Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Tue, 6 Feb 2024 15:28:17 -0800 Subject: [PATCH] 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. --- src/cpuprofiler.js | 2 +- src/embind/embind.js | 42 +++++++++---------- src/embind/emval.js | 2 +- src/jsifier.js | 8 ++-- src/library.js | 18 +++----- src/library_async.js | 10 ++--- src/library_ccall.js | 2 +- src/library_dylink.js | 4 +- src/library_fs.js | 4 +- src/library_glemu.js | 2 +- src/library_html5.js | 2 +- src/library_idbfs.js | 6 +-- src/library_math.js | 2 +- src/library_nodefs.js | 2 +- src/library_nodepath.js | 9 ++-- src/library_noderawfs.js | 30 ++++++------- src/library_path.js | 11 ++--- src/library_proxyfs.js | 2 +- src/library_pthread.js | 2 +- src/library_sdl.js | 2 +- src/parseTools.js | 4 +- src/preamble.js | 14 +++---- src/runtime_debug.js | 6 +-- src/shell.html | 4 +- src/shell_minimal.html | 4 +- src/worker.js | 8 ++-- .../metadce/test_metadce_cxx_ctors1.gzsize | 2 +- .../metadce/test_metadce_cxx_ctors1.jssize | 2 +- .../metadce/test_metadce_cxx_ctors2.gzsize | 2 +- .../metadce/test_metadce_cxx_ctors2.jssize | 2 +- .../metadce/test_metadce_cxx_except.gzsize | 2 +- .../metadce/test_metadce_cxx_except.jssize | 2 +- .../test_metadce_cxx_except_wasm.gzsize | 2 +- .../test_metadce_cxx_except_wasm.jssize | 2 +- .../metadce/test_metadce_cxx_mangle.gzsize | 2 +- .../metadce/test_metadce_cxx_mangle.jssize | 2 +- .../metadce/test_metadce_cxx_noexcept.gzsize | 2 +- .../metadce/test_metadce_cxx_noexcept.jssize | 2 +- .../metadce/test_metadce_files_js_fs.gzsize | 2 +- .../metadce/test_metadce_files_js_fs.jssize | 2 +- .../metadce/test_metadce_hello_O0.gzsize | 2 +- .../metadce/test_metadce_hello_O0.jssize | 2 +- .../metadce/test_metadce_hello_dylink.gzsize | 2 +- .../metadce/test_metadce_hello_dylink.jssize | 2 +- .../metadce/test_metadce_minimal_O0.gzsize | 2 +- .../metadce/test_metadce_minimal_O0.jssize | 2 +- .../test_metadce_minimal_pthreads.gzsize | 2 +- .../test_metadce_minimal_pthreads.jssize | 2 +- test/other/test_unoptimized_code_size.js.size | 2 +- .../test_unoptimized_code_size_strict.js.size | 2 +- test/test_other.py | 12 ++++-- 51 files changed, 124 insertions(+), 138 deletions(-) diff --git a/src/cpuprofiler.js b/src/cpuprofiler.js index 6d0393584eba4..f8f919431afed 100644 --- a/src/cpuprofiler.js +++ b/src/cpuprofiler.js @@ -580,7 +580,7 @@ var emscriptenCpuProfiler = { var realf = 'real_' + f; glCtx[realf] = glCtx[f]; var numArgs = this.webGLFunctionLength(f); // On Firefox & Chrome, could do "glCtx[realf].length", but that doesn't work on Edge, which always reports 0. - // Accessing 'arguments' is super slow, so to avoid overhead, statically reason the number of arguments. + // Accessing 'arguments'/'...' is super slow, so to avoid overhead, statically reason the number of arguments. switch (numArgs) { case 0: glCtx[f] = () => { this.enterSection(section); var ret = glCtx[realf](); this.endSection(section); return ret; }; break; case 1: glCtx[f] = (a1) => { this.enterSection(section); var ret = glCtx[realf](a1); this.endSection(section); return ret; }; break; diff --git a/src/embind/embind.js b/src/embind/embind.js index a7147b4124858..bee7627b4c9a0 100644 --- a/src/embind/embind.js +++ b/src/embind/embind.js @@ -98,12 +98,12 @@ var LibraryEmbind = { if (undefined === proto[methodName].overloadTable) { var prevFunc = proto[methodName]; // Inject an overload resolver function that routes to the appropriate overload based on the number of arguments. - proto[methodName] = function() { + proto[methodName] = function(...args) { // TODO This check can be removed in -O3 level "unsafe" optimizations. - if (!proto[methodName].overloadTable.hasOwnProperty(arguments.length)) { - throwBindingError(`Function '${humanName}' called with an invalid number of arguments (${arguments.length}) - expects one of (${proto[methodName].overloadTable})!`); + if (!proto[methodName].overloadTable.hasOwnProperty(args.length)) { + throwBindingError(`Function '${humanName}' called with an invalid number of arguments (${args.length}) - expects one of (${proto[methodName].overloadTable})!`); } - return proto[methodName].overloadTable[arguments.length].apply(this, arguments); + return proto[methodName].overloadTable[args.length].apply(this, args); }; // Move the previous function into the overload table. proto[methodName].overloadTable = []; @@ -818,9 +818,9 @@ var LibraryEmbind = { var argsWired = new Array(expectedArgCount); var invokerFuncArgs = []; var destructors = []; - var invokerFn = function() { - if (arguments.length !== expectedArgCount) { - throwBindingError(`function ${humanName} called with ${arguments.length} arguments, expected ${expectedArgCount}`); + var invokerFn = function(...args) { + if (args.length !== expectedArgCount) { + throwBindingError(`function ${humanName} called with ${args.length} arguments, expected ${expectedArgCount}`); } #if EMSCRIPTEN_TRACING Module.emscripten_trace_enter_context(`embind::${humanName}`); @@ -834,11 +834,11 @@ var LibraryEmbind = { invokerFuncArgs[1] = thisWired; } for (var i = 0; i < expectedArgCount; ++i) { - argsWired[i] = argTypes[i + 2]['toWireType'](destructors, arguments[i]); + argsWired[i] = argTypes[i + 2]['toWireType'](destructors, args[i]); invokerFuncArgs.push(argsWired[i]); } - var rv = cppInvokerFunc.apply(null, invokerFuncArgs); + var rv = cppInvokerFunc(...invokerFuncArgs); function onDone(rv) { if (needsDestructorStack) { @@ -896,11 +896,11 @@ var LibraryEmbind = { #if EMBIND_AOT var signature = createJsInvokerSignature(argTypes, isClassMethodFunc, returns, isAsync); - var invokerFn = InvokerFunctions[signature].apply(null, closureArgs); + var invokerFn = InvokerFunctions[signature](...closureArgs); #else let [args, invokerFnBody] = createJsInvoker(argTypes, isClassMethodFunc, returns, isAsync); args.push(invokerFnBody); - var invokerFn = newFunc(Function, args).apply(null, closureArgs); + var invokerFn = newFunc(Function, args)(...closureArgs); #endif #endif return createNamedFunction(humanName, invokerFn); @@ -1765,18 +1765,18 @@ var LibraryEmbind = { basePrototype = ClassHandle.prototype; } - var constructor = createNamedFunction(name, function() { + var constructor = createNamedFunction(name, function(...args) { if (Object.getPrototypeOf(this) !== instancePrototype) { throw new BindingError("Use 'new' to construct " + name); } if (undefined === registeredClass.constructor_body) { throw new BindingError(name + " has no accessible constructor"); } - var body = registeredClass.constructor_body[arguments.length]; + var body = registeredClass.constructor_body[args.length]; if (undefined === body) { - 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!`); + 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!`); } - return body.apply(this, arguments); + return body.apply(this, args); }); var instancePrototype = Object.create(basePrototype, { @@ -2197,14 +2197,12 @@ var LibraryEmbind = { wrapperType = requireRegisteredType(wrapperType, 'wrapper'); properties = Emval.toValue(properties); - var arraySlice = [].slice; - var registeredClass = wrapperType.registeredClass; var wrapperPrototype = registeredClass.instancePrototype; var baseClass = registeredClass.baseClass; var baseClassPrototype = baseClass.instancePrototype; var baseConstructor = registeredClass.baseClass.constructor; - var ctor = createNamedFunction(constructorName, function() { + var ctor = createNamedFunction(constructorName, function(...args) { registeredClass.baseClass.pureVirtualFunctions.forEach(function(name) { if (this[name] === baseClassPrototype[name]) { throw new PureVirtualError(`Pure virtual function ${name} must be implemented in JavaScript`); @@ -2214,19 +2212,17 @@ var LibraryEmbind = { Object.defineProperty(this, '__parent', { value: wrapperPrototype }); - this["__construct"].apply(this, arraySlice.call(arguments)); + this["__construct"](...args); }); // It's a little nasty that we're modifying the wrapper prototype here. - wrapperPrototype["__construct"] = function __construct() { + wrapperPrototype["__construct"] = function __construct(...args) { if (this === wrapperPrototype) { throwBindingError("Pass correct 'this' to __construct"); } - var inner = baseConstructor["implement"].apply( - undefined, - [this].concat(arraySlice.call(arguments))); + var inner = baseConstructor["implement"](this, ...args); detachFinalizer(inner); var $$ = inner.$$; inner["notifyOnDestruction"](); diff --git a/src/embind/emval.js b/src/embind/emval.js index 174834aa64a3c..ce221c174685b 100644 --- a/src/embind/emval.js +++ b/src/embind/emval.js @@ -369,7 +369,7 @@ var LibraryEmVal = { "};\n"; params.push(functionBody); - var invokerFunction = newFunc(Function, params).apply(null, args); + var invokerFunction = newFunc(Function, params)(...args); #endif var functionName = `methodCaller<(${types.map(t => t.name).join(', ')}) => ${retType.name}>`; return emval_addMethodCaller(createNamedFunction(functionName, invokerFunction)); diff --git a/src/jsifier.js b/src/jsifier.js index 50a8256cc33ab..02580d0befe13 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -238,9 +238,9 @@ ${argConvertions} if (LIBRARY_DEBUG && !isJsOnlySymbol(symbol)) { snippet = modifyJSFunction(snippet, (args, body, async) => `\ function(${args}) { - var ret = (function() { if (runtimeDebug) err("[library call:${mangled}: " + Array.prototype.slice.call(arguments).map(prettyPrint) + "]"); + var ret = (() => { if (runtimeDebug) err("[library call:${mangled}: " + Array.prototype.slice.call(arguments).map(prettyPrint) + "]"); ${body} - }).apply(this, arguments); + })(); if (runtimeDebug && typeof ret != "undefined") err(" [ return:" + prettyPrint(ret)); return ret; }`); @@ -444,8 +444,8 @@ function(${args}) { if (ASSERTIONS) { 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`; } - const functionBody = assertion + `return ${target}.apply(null, arguments);`; - LibraryManager.library[symbol] = new Function(functionBody); + const functionBody = assertion + `return ${target}(...args);`; + LibraryManager.library[symbol] = new Function('...args', functionBody); isStub = true; } } diff --git a/src/library.js b/src/library.js index 135c734fc0aa6..88cc447b59859 100644 --- a/src/library.js +++ b/src/library.js @@ -2874,7 +2874,7 @@ addToLibrary({ #if ASSERTIONS 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.`); #endif - return ASM_CONSTS[code].apply(null, args); + return ASM_CONSTS[code](...args); }, emscripten_asm_const_int__deps: ['$runEmAsmFunction'], @@ -2917,7 +2917,7 @@ addToLibrary({ #if ASSERTIONS 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.`); #endif - return ASM_CONSTS[code].apply(null, args); + return ASM_CONSTS[code](...args); }, emscripten_asm_const_int_sync_on_main_thread__deps: ['$runMainThreadEmAsm'], emscripten_asm_const_int_sync_on_main_thread: (code, sigPtr, argbuf) => { @@ -3100,7 +3100,7 @@ addToLibrary({ #endif var f = Module['dynCall_' + sig]; #endif - return args && args.length ? f.apply(null, [ptr].concat(args)) : f.call(null, ptr); + return f(ptr, ...args); }, $dynCall__deps: ['$dynCallLegacy', '$getWasmTableEntry'], #endif @@ -3113,16 +3113,10 @@ addToLibrary({ #if ASSERTIONS && !DYNCALLS assert(sig.includes('j') || sig.includes('p'), 'getDynCaller should only be called with i64 sigs') #endif - var argCache = []; - return function() { - argCache.length = 0; - Object.assign(argCache, arguments); - return dynCall(sig, ptr, argCache); - }; + return (...args) => dynCall(sig, ptr, args); }, - $dynCall__docs: '/** @param {Object=} args */', - $dynCall: (sig, ptr, args) => { + $dynCall: (sig, ptr, args = []) => { #if MEMORY64 // With MEMORY64 we have an additional step to convert `p` arguments to // bigint. This is the runtime equivalent of the wrappers we create for wasm @@ -3145,7 +3139,7 @@ addToLibrary({ #if ASSERTIONS assert(getWasmTableEntry(ptr), `missing table entry in dynCall: ${ptr}`); #endif - var rtn = getWasmTableEntry(ptr).apply(null, args); + var rtn = getWasmTableEntry(ptr)(...args); #endif #if MEMORY64 return sig[0] == 'p' ? Number(rtn) : rtn; diff --git a/src/library_async.js b/src/library_async.js index 91fb42c75ff09..c9bda2cc97c93 100644 --- a/src/library_async.js +++ b/src/library_async.js @@ -68,10 +68,10 @@ addToLibrary({ } #endif #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 - imports[x] = function() { + imports[x] = (...args) => { var originalAsyncifyState = Asyncify.state; try { - return original.apply(null, arguments); + return original(...args); } finally { // Only asyncify-declared imports are allowed to change the // state. @@ -130,7 +130,7 @@ addToLibrary({ original = Asyncify.makeAsyncFunction(original); } #endif - ret[x] = function() { + ret[x] = (...args) => { #if ASYNCIFY_DEBUG >= 2 dbg(`ASYNCIFY: ${' '.repeat(Asyncify.exportCallStack.length} try ${x}`); #endif @@ -143,9 +143,9 @@ addToLibrary({ // can just call the function with no args at all since and the engine will produce zeros // for all arguments. However, for i64 arguments we get `undefined cannot be converted to // BigInt`. - return original.apply(null, Asyncify.saveOrRestoreRewindArguments(x, arguments)); + return original(...Asyncify.saveOrRestoreRewindArguments(x, args)); #else - return original.apply(null, arguments); + return original(...args); #endif #if ASYNCIFY == 1 } finally { diff --git a/src/library_ccall.js b/src/library_ccall.js index f90caf0039a87..0eedb39017e3c 100644 --- a/src/library_ccall.js +++ b/src/library_ccall.js @@ -77,7 +77,7 @@ addToLibrary({ // Data for a previous async operation that was in flight before us. var previousAsync = Asyncify.currData; #endif - var ret = func.apply(null, cArgs); + var ret = func(...cArgs); function onDone(ret) { #if ASYNCIFY == 1 runtimeKeepalivePop(); diff --git a/src/library_dylink.js b/src/library_dylink.js index 7c449378df2b1..38fb24852922d 100644 --- a/src/library_dylink.js +++ b/src/library_dylink.js @@ -707,9 +707,9 @@ var LibraryDylink = { // when first called. if (!(prop in stubs)) { var resolved; - stubs[prop] = function() { + stubs[prop] = (...args) => { resolved ||= resolveSymbol(prop); - return resolved.apply(null, arguments); + return resolved(...args); }; } return stubs[prop]; diff --git a/src/library_fs.js b/src/library_fs.js index 71566c744dfd7..b82868ba5fb2c 100644 --- a/src/library_fs.js +++ b/src/library_fs.js @@ -1784,9 +1784,9 @@ FS.staticInit();` + var keys = Object.keys(node.stream_ops); keys.forEach((key) => { var fn = node.stream_ops[key]; - stream_ops[key] = function forceLoadLazyFile() { + stream_ops[key] = (...args) => { FS.forceLoadFile(node); - return fn.apply(null, arguments); + return fn(...args); }; }); function writeChunks(stream, buffer, offset, length, position) { diff --git a/src/library_glemu.js b/src/library_glemu.js index 18a88a8c68446..b5cf3001c2db6 100644 --- a/src/library_glemu.js +++ b/src/library_glemu.js @@ -3580,7 +3580,7 @@ var LibraryGLEmulation = { _glEnableVertexAttribArray(vaa); } for (var vaa in info.vertexAttribPointers) { - _glVertexAttribPointer.apply(null, info.vertexAttribPointers[vaa]); + _glVertexAttribPointer(...info.vertexAttribPointers[vaa]); } for (var attrib in info.enabledClientStates) { _glEnableClientState(attrib|0); diff --git a/src/library_html5.js b/src/library_html5.js index 478116eb831d0..eff2402afde4f 100644 --- a/src/library_html5.js +++ b/src/library_html5.js @@ -140,7 +140,7 @@ var LibraryHTML5 = { var call = JSEvents.deferredCalls[i]; JSEvents.deferredCalls.splice(i, 1); --i; - call.targetFunction.apply(null, call.argsList); + call.targetFunction(...call.argsList); } }, #endif diff --git a/src/library_idbfs.js b/src/library_idbfs.js index 30856cd3fec3e..febc885c2b91c 100644 --- a/src/library_idbfs.js +++ b/src/library_idbfs.js @@ -21,10 +21,8 @@ addToLibrary({ }, DB_VERSION: 21, DB_STORE_NAME: 'FILE_DATA', - mount: function(mount) { - // reuse all of the core MEMFS functionality - return MEMFS.mount.apply(null, arguments); - }, + // reuse all of the core MEMFS functionality + mount: (...args) => MEMFS.mount(...args), syncfs: (mount, populate, callback) => { IDBFS.getLocalSet(mount, (err, local) => { if (err) return callback(err); diff --git a/src/library_math.js b/src/library_math.js index c971124f4db68..72ad04b7f5e35 100644 --- a/src/library_math.js +++ b/src/library_math.js @@ -26,7 +26,7 @@ addToLibrary({ for (var i = 0; i < count; ++i) { args.push({{{ makeGetValue('varargs', `i * ${getNativeTypeSize('double')}`, 'double') }}}); } - return Math.hypot.apply(null, args); + return Math.hypot(...args); }, emscripten_math_sin: (x) => Math.sin(x), emscripten_math_sinh: (x) => Math.sinh(x), diff --git a/src/library_nodefs.js b/src/library_nodefs.js index 177c57ca6958b..81864ffcc956f 100644 --- a/src/library_nodefs.js +++ b/src/library_nodefs.js @@ -87,7 +87,7 @@ addToLibrary({ } parts.push(node.mount.opts.root); parts.reverse(); - return PATH.join.apply(null, parts); + return PATH.join(...parts); }, // This maps the integer permission modes from http://linux.die.net/man/3/open // to node.js-specific file open permission strings at http://nodejs.org/api/fs.html#fs_fs_open_path_flags_mode_callback diff --git a/src/library_nodepath.js b/src/library_nodepath.js index 4e817f43ed06a..c42820f36e289 100644 --- a/src/library_nodepath.js +++ b/src/library_nodepath.js @@ -17,9 +17,7 @@ addToLibrary({ normalize: (path) => nodePath['normalize'](path), dirname: (path) => nodePath['dirname'](path), basename: (path) => nodePath['basename'](path), - join: function () { - return nodePath['join'].apply(null, arguments); - }, + join: (...args) => nodePath['join'](...args), join2: (l, r) => nodePath['join'](l, r), }, // The FS-using parts are split out into a separate object, so simple path @@ -27,10 +25,9 @@ addToLibrary({ $PATH_FS__deps: ['$FS'], $PATH_FS__docs: '/** @type{{resolve: function(...*)}} */', $PATH_FS: { - resolve: function () { - var paths = Array.prototype.slice.call(arguments, 0); + resolve: (...paths) => { paths.unshift(FS.cwd()); - return nodePath['posix']['resolve'].apply(null, paths); + return nodePath['posix']['resolve'](...paths); }, relative: (from, to) => nodePath['posix']['relative'](from || FS.cwd(), to || FS.cwd()), } diff --git a/src/library_noderawfs.js b/src/library_noderawfs.js index 15758d0e4d752..ba0bdaba349fb 100644 --- a/src/library_noderawfs.js +++ b/src/library_noderawfs.js @@ -9,9 +9,9 @@ addToLibrary({ $NODERAWFS__postset: ` if (ENVIRONMENT_IS_NODE) { var _wrapNodeError = function(func) { - return function() { + return function(...args) { try { - return func.apply(this, arguments) + return func.apply(this, args) } catch (e) { if (e.code) { throw new FS.ErrnoError(ERRNO_CODES[e.code]); @@ -52,7 +52,7 @@ addToLibrary({ }, // generic function for all node creation cwd() { return process.cwd(); }, - chdir() { process.chdir.apply(void 0, arguments); }, + chdir(...args) { process.chdir(...args); }, mknod(path, mode) { if (FS.isDir(path)) { fs.mkdirSync(path, mode); @@ -60,26 +60,26 @@ addToLibrary({ fs.writeFileSync(path, '', { mode: mode }); } }, - mkdir() { fs.mkdirSync.apply(void 0, arguments); }, - symlink() { fs.symlinkSync.apply(void 0, arguments); }, - rename() { fs.renameSync.apply(void 0, arguments); }, - rmdir() { fs.rmdirSync.apply(void 0, arguments); }, - readdir() { return ['.', '..'].concat(fs.readdirSync.apply(void 0, arguments)); }, - unlink() { fs.unlinkSync.apply(void 0, arguments); }, - readlink() { return fs.readlinkSync.apply(void 0, arguments); }, - stat() { return fs.statSync.apply(void 0, arguments); }, - lstat() { return fs.lstatSync.apply(void 0, arguments); }, - chmod() { fs.chmodSync.apply(void 0, arguments); }, + mkdir(...args) { fs.mkdirSync(...args); }, + symlink(...args) { fs.symlinkSync(...args); }, + rename(...args) { fs.renameSync(...args); }, + rmdir(...args) { fs.rmdirSync(...args); }, + readdir(...args) { return ['.', '..'].concat(fs.readdirSync(...args)); }, + unlink(...args) { fs.unlinkSync(...args); }, + readlink(...args) { return fs.readlinkSync(...args); }, + stat(...args) { return fs.statSync(...args); }, + lstat(...args) { return fs.lstatSync(...args); }, + chmod(...args) { fs.chmodSync(...args); }, fchmod(fd, mode) { var stream = FS.getStreamChecked(fd); fs.fchmodSync(stream.nfd, mode); }, - chown() { fs.chownSync.apply(void 0, arguments); }, + chown(...args) { fs.chownSync(...args); }, fchown(fd, owner, group) { var stream = FS.getStreamChecked(fd); fs.fchownSync(stream.nfd, owner, group); }, - truncate() { fs.truncateSync.apply(void 0, arguments); }, + truncate(...args) { fs.truncateSync(...args); }, ftruncate(fd, len) { // See https://github.com/nodejs/node/issues/35632 if (len < 0) { diff --git a/src/library_path.js b/src/library_path.js index 8f06d204d34e9..ab3112503a202 100644 --- a/src/library_path.js +++ b/src/library_path.js @@ -72,10 +72,7 @@ addToLibrary({ if (lastSlash === -1) return path; return path.substr(lastSlash+1); }, - join: function() { - var paths = Array.prototype.slice.call(arguments); - return PATH.normalize(paths.join('/')); - }, + join: (...paths) => PATH.normalize(paths.join('/')), join2: (l, r) => PATH.normalize(l + '/' + r), }, // The FS-using parts are split out into a separate object, so simple path @@ -90,11 +87,11 @@ addToLibrary({ #endif ], $PATH_FS: { - resolve: function() { + resolve: (...args) => { var resolvedPath = '', resolvedAbsolute = false; - for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { - var path = (i >= 0) ? arguments[i] : FS.cwd(); + for (var i = args.length - 1; i >= -1 && !resolvedAbsolute; i--) { + var path = (i >= 0) ? args[i] : FS.cwd(); // Skip empty and invalid entries if (typeof path != 'string') { throw new TypeError('Arguments to path.resolve must be strings'); diff --git a/src/library_proxyfs.js b/src/library_proxyfs.js index d234e2423fc46..b9b050dff8c4f 100644 --- a/src/library_proxyfs.js +++ b/src/library_proxyfs.js @@ -27,7 +27,7 @@ addToLibrary({ } parts.push(node.mount.opts.root); parts.reverse(); - return PATH.join.apply(null, parts); + return PATH.join(...parts); }, node_ops: { getattr(node) { diff --git a/src/library_pthread.js b/src/library_pthread.js index b1497ff91a103..346484af7d79e 100644 --- a/src/library_pthread.js +++ b/src/library_pthread.js @@ -1040,7 +1040,7 @@ var LibraryPThread = { assert(func.length == numCallArgs, 'Call args mismatch in _emscripten_receive_on_main_thread_js'); #endif PThread.currentProxiedOperationCallerThread = callingThread; - var rtn = func.apply(null, proxiedJSCallArgs); + var rtn = func(...proxiedJSCallArgs); PThread.currentProxiedOperationCallerThread = 0; #if MEMORY64 // In memory64 mode some proxied functions return bigint/pointer but diff --git a/src/library_sdl.js b/src/library_sdl.js index de6695bfec90d..42eeb2a6e331e 100644 --- a/src/library_sdl.js +++ b/src/library_sdl.js @@ -2163,7 +2163,7 @@ var LibrarySDL = { var x = stackAlloc({{{ getNativeTypeSize('i32') }}}); var y = stackAlloc({{{ getNativeTypeSize('i32') }}}); var comp = stackAlloc({{{ getNativeTypeSize('i32') }}}); - var data = Module['_' + func].apply(null, params.concat([x, y, comp, 0])); + var data = Module['_' + func](...params, x, y, comp, 0); if (!data) return null; addCleanup(() => Module['_stbi_image_free'](data)); return { diff --git a/src/parseTools.js b/src/parseTools.js index 74137e35fbebe..6dfe78b605691 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -622,9 +622,9 @@ Please update to new syntax.`); const dyncall = `dynCall_${sig}`; if (sig.length > 1) { - return `((${args}) => ${dyncall}.apply(null, [${funcPtr}, ${callArgs}]))`; + return `((${args}) => ${dyncall}(${funcPtr}, ${callArgs}))`; } - return `(() => ${dyncall}.call(null, ${funcPtr}))`; + return `(() => ${dyncall}(${funcPtr}))`; } if (needArgConversion) { diff --git a/src/preamble.js b/src/preamble.js index 032eff4b8eeb8..c4f8022ec1236 100644 --- a/src/preamble.js +++ b/src/preamble.js @@ -513,14 +513,14 @@ Module['FS_createPreloadedFile'] = FS.createPreloadedFile; #if ASSERTIONS function createExportWrapper(name) { - return function() { + return (...args) => { assert(runtimeInitialized, `native function \`${name}\` called before runtime initialization`); #if EXIT_RUNTIME assert(!runtimeExited, `native function \`${name}\` called after runtime exit (use NO_EXIT_RUNTIME to keep it alive after main() exits)`); #endif var f = wasmExports[name]; assert(f, `exported native function \`${name}\` not found`); - return f.apply(null, arguments); + return f(...args); }; } #endif @@ -537,7 +537,7 @@ var abortWrapperDepth = 0; // Creates a wrapper in a closure so that each wrapper gets it's own copy of 'original' function makeAbortWrapper(original) { - return function() { + return (...args) => { // Don't allow this function to be called if we're aborted! if (ABORT) { throw "program has already aborted!"; @@ -545,7 +545,7 @@ function makeAbortWrapper(original) { abortWrapperDepth += 1; try { - return original.apply(null, arguments); + return original(...args); } catch (e) { if ( ABORT // rethrow exception if abort() was called in the original function call above @@ -700,7 +700,7 @@ var wasmOffsetConverter; {{{ makeModuleReceiveWithVar('loadSplitModule', undefined, 'instantiateSync', true) }}} var splitModuleProxyHandler = { get(target, prop, receiver) { - return function() { + return (...args) => { #if ASYNCIFY == 2 throw new Error('Placeholder function "' + prop + '" should not be called when using JSPI.'); #else @@ -714,9 +714,9 @@ var splitModuleProxyHandler = { // When the table is dynamically laid out, the placeholder functions names // are offsets from the table base. In the main module, the table base is // always 1. - return wasmTable.get(1 + parseInt(prop)).apply(null, arguments); + return wasmTable.get(1 + parseInt(prop))(...args); #else - return wasmTable.get(prop).apply(null, arguments); + return wasmTable.get(prop)(...args); #endif #endif } diff --git a/src/runtime_debug.js b/src/runtime_debug.js index 0ade98dba7a68..210df0178ca23 100644 --- a/src/runtime_debug.js +++ b/src/runtime_debug.js @@ -161,16 +161,16 @@ function prettyPrint(arg) { #if ASSERTIONS || RUNTIME_DEBUG || AUTODEBUG // Used by XXXXX_DEBUG settings to output debug messages. -function dbg(text) { +function dbg(...args) { #if ENVIRONMENT_MAY_BE_NODE && PTHREADS // Avoid using the console for debugging in multi-threaded node applications // See https://github.com/emscripten-core/emscripten/issues/14804 if (ENVIRONMENT_IS_NODE) { - fs.writeSync(2, Array.from(arguments).join(' ') + '\n'); + fs.writeSync(2, args.join(' ') + '\n'); } else #endif // TODO(sbc): Make this configurable somehow. Its not always convenient for // logging to show up as warnings. - console.warn.apply(console, arguments); + console.warn.apply(console, args); } #endif diff --git a/src/shell.html b/src/shell.html index ad6e06097b42b..6a946c28d0c1d 100644 --- a/src/shell.html +++ b/src/shell.html @@ -38,8 +38,8 @@ print: (function() { var element = document.getElementById('output'); if (element) element.value = ''; // clear browser cache - return function(text) { - if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' '); + return (...args) => { + var text = args.join(' '); // These replacements are necessary if you render to raw HTML //text = text.replace(/&/g, "&"); //text = text.replace(/ 1) text = Array.prototype.slice.call(arguments).join(' '); + return (...args) => { + var text = args.join(' '); // These replacements are necessary if you render to raw HTML //text = text.replace(/&/g, "&"); //text = text.replace(/ 2', '()=>2'], js) self.assertContained('const ', js) self.assertContained('?.[', js) @@ -13205,6 +13207,7 @@ def check_for_es6(filename, expect): self.assertContained('??=', js) self.assertContained('||=', js) self.assertContained('&&=', js) + self.assertContained('...', js) else: self.verify_es5(filename) self.assertNotContained('foo(arg=', js) @@ -13215,6 +13218,7 @@ def check_for_es6(filename, expect): self.assertNotContained('?.', js) self.assertNotContained('||=', js) self.assertNotContained('&&=', js) + self.assertNotContained('...args', js) # Check that under normal circumstances none of these features get # removed / transpiled.