Source code
Revision control
Copy as Markdown
Other Tools
// Tests when |arguments| are used in optimized spread calls.
function testBasic() {
// Return the number of arguments.
function argslen() { return arguments.length; }
// Return the first argument.
function arg0() { return arguments[0]; }
// Return the argument at the request index.
function argIndex(i) { return arguments[i]; }
// Call the above functions when no formals are present.
function noFormalsLen() { return argslen(...arguments); }
function noFormals0() { return arg0(...arguments); }
function noFormalsIndex() { return argIndex(...arguments); }
// Call the above functions when some formals are present.
function formalsLen(x, y, z) { return argslen(...arguments); }
function formals0(x, y, z) { return arg0(...arguments); }
function formalsIndex(x, y, z) { return argIndex(...arguments); }
// Call the above functions when a rest argument is present.
function restLen(...rest) { return argslen(...arguments); }
function rest0(...rest) { return arg0(...arguments); }
function restIndex(...rest) { return argIndex(...arguments); }
// Call the above functions when default parameters are present.
function defaultLen(x = 0) { return argslen(...arguments); }
function default0(x = 0) { return arg0(...arguments); }
function defaultIndex(x = 0) { return argIndex(...arguments); }
for (let i = 0; i < 100; ++i) {
assertEq(noFormalsLen(), 0);
assertEq(noFormalsLen(1), 1);
assertEq(noFormalsLen(1, 2, 3), 3);
assertEq(formalsLen(), 0);
assertEq(formalsLen(1), 1);
assertEq(formalsLen(1, 2, 3), 3);
assertEq(restLen(), 0);
assertEq(restLen(1), 1);
assertEq(restLen(1, 2, 3), 3);
assertEq(defaultLen(), 0);
assertEq(defaultLen(1), 1);
assertEq(defaultLen(1, 2, 3), 3);
assertEq(noFormals0(), undefined);
assertEq(noFormals0(100), 100);
assertEq(noFormals0(100, 200, 300), 100);
assertEq(formals0(), undefined);
assertEq(formals0(100), 100);
assertEq(formals0(100, 200, 300), 100);
assertEq(rest0(), undefined);
assertEq(rest0(100), 100);
assertEq(rest0(100, 200, 300), 100);
assertEq(default0(), undefined);
assertEq(default0(100), 100);
assertEq(default0(100, 200, 300), 100);
assertEq(noFormalsIndex(), undefined);
assertEq(noFormalsIndex(0), 0);
assertEq(noFormalsIndex(0, 100), 0);
assertEq(noFormalsIndex(0, 100, 200, 300), 0);
assertEq(noFormalsIndex(1, 100), 100);
assertEq(noFormalsIndex(1, 100, 200, 300), 100);
assertEq(formalsIndex(), undefined);
assertEq(formalsIndex(0), 0);
assertEq(formalsIndex(0, 100), 0);
assertEq(formalsIndex(0, 100, 200, 300), 0);
assertEq(formalsIndex(1, 100), 100);
assertEq(formalsIndex(1, 100, 200, 300), 100);
assertEq(restIndex(), undefined);
assertEq(restIndex(0), 0);
assertEq(restIndex(0, 100), 0);
assertEq(restIndex(0, 100, 200, 300), 0);
assertEq(restIndex(1, 100), 100);
assertEq(restIndex(1, 100, 200, 300), 100);
assertEq(defaultIndex(), undefined);
assertEq(defaultIndex(0), 0);
assertEq(defaultIndex(0, 100), 0);
assertEq(defaultIndex(0, 100, 200, 300), 0);
assertEq(defaultIndex(1, 100), 100);
assertEq(defaultIndex(1, 100, 200, 300), 100);
}
}
testBasic();
function testOverriddenIterator() {
function g(x) {
return x;
}
function f(i) {
if (i === 100) {
arguments[Symbol.iterator] = function() {
return ["bad"].values();
};
}
return g(...arguments);
}
for (let i = 0; i <= 150; ++i) {
assertEq(f(i), i !== 100 ? i : "bad");
}
}
testOverriddenIterator();
function testOverriddenLength() {
function g(x, y = 0) {
return x + y;
}
function f(i) {
if (i === 100) {
arguments.length = 1;
}
return g(...arguments);
}
for (let i = 0; i <= 150; ++i) {
assertEq(f(i, i), i !== 100 ? i * 2 : i);
}
}
testOverriddenLength();
function testOverriddenElement() {
function g(x, y) {
return x + y;
}
function f(i) {
if (i === 100) {
arguments[1] = 0;
}
return g(...arguments);
}
for (let i = 0; i <= 150; ++i) {
assertEq(f(i, i), i !== 100 ? i * 2 : i);
}
}
testOverriddenElement();
function testDeletedElement() {
function g(x, y = 0) {
return x + y;
}
function f(i) {
if (i === 100) {
delete arguments[1];
}
return g(...arguments);
}
for (let i = 0; i <= 150; ++i) {
assertEq(f(i, i), i !== 100 ? i * 2 : i);
}
}
testDeletedElement();
function testForwardedArg() {
function g(x, y) {
return x + y;
}
function f(i) {
function closedOver() {
if (i === 100) i = 0;
}
closedOver();
return g(...arguments);
}
for (let i = 0; i <= 150; ++i) {
assertEq(f(i, i), i !== 100 ? i * 2 : i);
}
}
testForwardedArg();
function testModifiedArrayIteratorPrototype() {
function g(x, y) {
return x + y;
}
const ArrayIteratorPrototype = Reflect.getPrototypeOf([][Symbol.iterator]());
const ArrayIteratorPrototypeNext = ArrayIteratorPrototype.next;
function newNext() {
var result = ArrayIteratorPrototypeNext.call(this);
if (!result.done) {
result.value *= 2;
}
return result;
}
function f(i) {
if (i === 100) {
ArrayIteratorPrototype.next = newNext;
}
return g(...arguments);
}
for (let i = 0; i <= 150; ++i) {
assertEq(f(i, i), i < 100 ? i * 2 : i * 4);
}
}
testModifiedArrayIteratorPrototype();