summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/arguments/spread-call-optimization.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit-test/tests/arguments/spread-call-optimization.js')
-rw-r--r--js/src/jit-test/tests/arguments/spread-call-optimization.js216
1 files changed, 216 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/arguments/spread-call-optimization.js b/js/src/jit-test/tests/arguments/spread-call-optimization.js
new file mode 100644
index 0000000000..5ebc68de36
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/spread-call-optimization.js
@@ -0,0 +1,216 @@
+// 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();