summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/arguments
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--js/src/jit-test/tests/arguments/access-formals.js44
-rw-r--r--js/src/jit-test/tests/arguments/alias-function-closed.js167
-rw-r--r--js/src/jit-test/tests/arguments/alias-function-not-closed.js87
-rw-r--r--js/src/jit-test/tests/arguments/args-attributes.js75
-rw-r--r--js/src/jit-test/tests/arguments/args-createontrace.js18
-rw-r--r--js/src/jit-test/tests/arguments/args-mochi-2.js23
-rw-r--r--js/src/jit-test/tests/arguments/args-mochi-2a.js23
-rw-r--r--js/src/jit-test/tests/arguments/args-mochi.js17
-rw-r--r--js/src/jit-test/tests/arguments/args-mutate-length-1.js16
-rw-r--r--js/src/jit-test/tests/arguments/args-mutate-length-2.js15
-rw-r--r--js/src/jit-test/tests/arguments/args-range-2.js37
-rw-r--r--js/src/jit-test/tests/arguments/args-range-const.js14
-rw-r--r--js/src/jit-test/tests/arguments/args-range.js18
-rw-r--r--js/src/jit-test/tests/arguments/args-redefine-iterator-1.js14
-rw-r--r--js/src/jit-test/tests/arguments/args-redefine-iterator-2.js14
-rw-r--r--js/src/jit-test/tests/arguments/args-redefine-length-1.js7
-rw-r--r--js/src/jit-test/tests/arguments/args-redefine-length-2.js8
-rw-r--r--js/src/jit-test/tests/arguments/args-redefine-length-3.js14
-rw-r--r--js/src/jit-test/tests/arguments/args-redefine-length-4.js14
-rw-r--r--js/src/jit-test/tests/arguments/args-redefine-length-5.js14
-rw-r--r--js/src/jit-test/tests/arguments/args-redefine-length-6.js14
-rw-r--r--js/src/jit-test/tests/arguments/args-redefine-length-7.js14
-rw-r--r--js/src/jit-test/tests/arguments/args-sum.js16
-rw-r--r--js/src/jit-test/tests/arguments/args-vargc.js18
-rw-r--r--js/src/jit-test/tests/arguments/args1.js15
-rw-r--r--js/src/jit-test/tests/arguments/args10.js16
-rw-r--r--js/src/jit-test/tests/arguments/args11.js14
-rw-r--r--js/src/jit-test/tests/arguments/args2.js20
-rw-r--r--js/src/jit-test/tests/arguments/args2a.js17
-rw-r--r--js/src/jit-test/tests/arguments/args2b.js17
-rw-r--r--js/src/jit-test/tests/arguments/args2c.js19
-rw-r--r--js/src/jit-test/tests/arguments/args2d.js17
-rw-r--r--js/src/jit-test/tests/arguments/args3.js20
-rw-r--r--js/src/jit-test/tests/arguments/args4.js21
-rw-r--r--js/src/jit-test/tests/arguments/args5.js24
-rw-r--r--js/src/jit-test/tests/arguments/args6.js22
-rw-r--r--js/src/jit-test/tests/arguments/args6a.js23
-rw-r--r--js/src/jit-test/tests/arguments/args7.js14
-rw-r--r--js/src/jit-test/tests/arguments/args8.js14
-rw-r--r--js/src/jit-test/tests/arguments/args9.js16
-rw-r--r--js/src/jit-test/tests/arguments/argsub.js13
-rw-r--r--js/src/jit-test/tests/arguments/argsx-1.js22
-rw-r--r--js/src/jit-test/tests/arguments/argsx-2.js23
-rw-r--r--js/src/jit-test/tests/arguments/argsx-3.js27
-rw-r--r--js/src/jit-test/tests/arguments/argsx-3a.js27
-rw-r--r--js/src/jit-test/tests/arguments/argsx-4.js23
-rw-r--r--js/src/jit-test/tests/arguments/arguments-on-proto.js27
-rw-r--r--js/src/jit-test/tests/arguments/bug-917585-relax-aliasing-constraints.js18
-rw-r--r--js/src/jit-test/tests/arguments/bug1051760.js4
-rw-r--r--js/src/jit-test/tests/arguments/bug1227287.js8
-rw-r--r--js/src/jit-test/tests/arguments/bug1423937.js17
-rw-r--r--js/src/jit-test/tests/arguments/bug1503071.js16
-rw-r--r--js/src/jit-test/tests/arguments/bug1621265.js17
-rw-r--r--js/src/jit-test/tests/arguments/bug503772.js16
-rw-r--r--js/src/jit-test/tests/arguments/bug508178.js18
-rw-r--r--js/src/jit-test/tests/arguments/bug633020.js11
-rw-r--r--js/src/jit-test/tests/arguments/bug843985.js5
-rw-r--r--js/src/jit-test/tests/arguments/bug956173.js7
-rw-r--r--js/src/jit-test/tests/arguments/defaults-basic.js35
-rw-r--r--js/src/jit-test/tests/arguments/defaults-bound-to-function.js43
-rw-r--r--js/src/jit-test/tests/arguments/defaults-bug759904.js4
-rw-r--r--js/src/jit-test/tests/arguments/defaults-call-function.js15
-rw-r--r--js/src/jit-test/tests/arguments/defaults-destructuring-array.js17
-rw-r--r--js/src/jit-test/tests/arguments/defaults-destructuring-expression-closure.js19
-rw-r--r--js/src/jit-test/tests/arguments/defaults-destructuring-function-expression.js9
-rw-r--r--js/src/jit-test/tests/arguments/defaults-destructuring-mixed-default-value.js55
-rw-r--r--js/src/jit-test/tests/arguments/defaults-destructuring-mixed.js29
-rw-r--r--js/src/jit-test/tests/arguments/defaults-destructuring-object.js27
-rw-r--r--js/src/jit-test/tests/arguments/defaults-destructuring-with-rest.js29
-rw-r--r--js/src/jit-test/tests/arguments/defaults-evaluation-order.js27
-rw-r--r--js/src/jit-test/tests/arguments/defaults-exceptions.js6
-rw-r--r--js/src/jit-test/tests/arguments/defaults-invalid-syntax.js30
-rw-r--r--js/src/jit-test/tests/arguments/defaults-scoping.js36
-rw-r--r--js/src/jit-test/tests/arguments/defaults-strict-mode.js41
-rw-r--r--js/src/jit-test/tests/arguments/defaults-with-arguments.js10
-rw-r--r--js/src/jit-test/tests/arguments/defaults-with-rest.js23
-rw-r--r--js/src/jit-test/tests/arguments/destructuring-after-defaults.js14
-rw-r--r--js/src/jit-test/tests/arguments/destructuring-default-value-scope.js10
-rw-r--r--js/src/jit-test/tests/arguments/destructuring-exprbody.js8
-rw-r--r--js/src/jit-test/tests/arguments/destructuring-with-rest.js21
-rw-r--r--js/src/jit-test/tests/arguments/dynamicBindings.js32
-rw-r--r--js/src/jit-test/tests/arguments/function_dot_caller_restrictions.js78
-rw-r--r--js/src/jit-test/tests/arguments/inline-rest-array-creation.js83
-rw-r--r--js/src/jit-test/tests/arguments/inline-transpile.js17
-rw-r--r--js/src/jit-test/tests/arguments/iterator-set-and-redefine.js33
-rw-r--r--js/src/jit-test/tests/arguments/mapped-define.js20
-rw-r--r--js/src/jit-test/tests/arguments/mapped-freeze.js8
-rw-r--r--js/src/jit-test/tests/arguments/mapped-unmapped-args.js61
-rw-r--r--js/src/jit-test/tests/arguments/nonstrict-args.js24
-rw-r--r--js/src/jit-test/tests/arguments/nonstrict-assign-element-get-parameter.js13
-rw-r--r--js/src/jit-test/tests/arguments/nonstrict-assign-parameter-get-element.js13
-rw-r--r--js/src/jit-test/tests/arguments/nonstrict-assign.js17
-rw-r--r--js/src/jit-test/tests/arguments/nonstrict-later-assign.js18
-rw-r--r--js/src/jit-test/tests/arguments/nonstrict-noargs.js21
-rw-r--r--js/src/jit-test/tests/arguments/rest-alias-function.js10
-rw-r--r--js/src/jit-test/tests/arguments/rest-arguments-as-parameters.js9
-rw-r--r--js/src/jit-test/tests/arguments/rest-basic.js15
-rw-r--r--js/src/jit-test/tests/arguments/rest-bug763954.js5
-rw-r--r--js/src/jit-test/tests/arguments/rest-debugger.js17
-rw-r--r--js/src/jit-test/tests/arguments/rest-disallow-arguments-strict.js8
-rw-r--r--js/src/jit-test/tests/arguments/rest-in-Function.js3
-rw-r--r--js/src/jit-test/tests/arguments/rest-invalid-syntax.js12
-rw-r--r--js/src/jit-test/tests/arguments/rest-nested-arguments.js7
-rw-r--r--js/src/jit-test/tests/arguments/rest-nested.js7
-rw-r--r--js/src/jit-test/tests/arguments/rest-underflow.js9
-rw-r--r--js/src/jit-test/tests/arguments/rest-with-arguments.js40
-rw-r--r--js/src/jit-test/tests/arguments/strict-args-flushstack.js27
-rw-r--r--js/src/jit-test/tests/arguments/strict-args-generator-flushstack.js27
-rw-r--r--js/src/jit-test/tests/arguments/strict-args.js25
-rw-r--r--js/src/jit-test/tests/arguments/strict-assign-after.js28
-rw-r--r--js/src/jit-test/tests/arguments/strict-assign-arguments-element.js21
-rw-r--r--js/src/jit-test/tests/arguments/strict-assign-outer-param-psych.js27
-rw-r--r--js/src/jit-test/tests/arguments/strict-assign-outer-param.js27
-rw-r--r--js/src/jit-test/tests/arguments/strict-assign-parameter-get-element.js14
-rw-r--r--js/src/jit-test/tests/arguments/strict-assign.js26
-rw-r--r--js/src/jit-test/tests/arguments/strict-eval-mutation.js24
-rw-r--r--js/src/jit-test/tests/arguments/strict-eval.js30
-rw-r--r--js/src/jit-test/tests/arguments/strict-maybe-assign-outer.js26
-rw-r--r--js/src/jit-test/tests/arguments/strict-maybe-nested-eval.js26
-rw-r--r--js/src/jit-test/tests/arguments/strict-nested-assign-shadow-function-call.js33
-rw-r--r--js/src/jit-test/tests/arguments/strict-nested-assign-shadow-function-name.js33
-rw-r--r--js/src/jit-test/tests/arguments/strict-nested-assign-shadow-function.js32
-rw-r--r--js/src/jit-test/tests/arguments/strict-nested-assign-shadowed-catch-call.js39
-rw-r--r--js/src/jit-test/tests/arguments/strict-nested-assign-shadowed-catch.js39
-rw-r--r--js/src/jit-test/tests/arguments/strict-nested-assign-shadowed-var.js29
-rw-r--r--js/src/jit-test/tests/arguments/strict-nested-eval.js31
-rw-r--r--js/src/jit-test/tests/arguments/strict-nested-shadow-eval.js30
-rw-r--r--js/src/jit-test/tests/arguments/strict-nested-shadow-maybe-eval.js30
-rw-r--r--js/src/jit-test/tests/arguments/strict-noargs.js25
-rw-r--r--js/src/jit-test/tests/arguments/strict-osr-shadowed-args.js13
-rw-r--r--js/src/jit-test/tests/arguments/testDelArg1.js13
-rw-r--r--js/src/jit-test/tests/arguments/testDelArg2.js13
-rw-r--r--js/src/jit-test/tests/arguments/testDelArg3.js42
-rw-r--r--js/src/jit-test/tests/arguments/testDelArg3Strict.js44
134 files changed, 3151 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/arguments/access-formals.js b/js/src/jit-test/tests/arguments/access-formals.js
new file mode 100644
index 0000000000..a63098500c
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/access-formals.js
@@ -0,0 +1,44 @@
+function g1(x, args) {
+ args[0] = 88;
+}
+
+// We assume we can optimize arguments access in |f|.
+//
+// Then the apply-call invalidates the arguments optimization,
+// and creates a real arguments object.
+//
+// Test that x and y fetch the values from the args object when
+// that happens.
+function f1(x, y, o) {
+ var res = 0;
+ for (var i=0; i<50; i++) {
+ res += x + y;
+ if (i > 10)
+ o.apply(null, arguments);
+ }
+ return res;
+}
+
+var o1 = {apply: g1};
+assertEq(f1(3, 5, o1), 3630);
+assertEq(f1(3, 5, o1), 3630);
+
+// In strict mode, the arguments object does not alias formals.
+function g2(x, args) {
+ args[0] = 88;
+}
+
+function f2(x, y, o) {
+ "use strict";
+ var res = 0;
+ for (var i=0; i<50; i++) {
+ res += x + y;
+ if (i > 10)
+ o.apply(null, arguments);
+ }
+ return res;
+}
+
+var o2 = {apply: g2};
+assertEq(f2(3, 5, o2), 400);
+assertEq(f2(3, 5, o2), 400);
diff --git a/js/src/jit-test/tests/arguments/alias-function-closed.js b/js/src/jit-test/tests/arguments/alias-function-closed.js
new file mode 100644
index 0000000000..ba91cc6f66
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/alias-function-closed.js
@@ -0,0 +1,167 @@
+function f1(a, aIs, // without default parameter
+ b=()=>62, bIs, // with default parameter
+ // before function body
+ c=(assertEq(a(), aIs), assertEq(b(), bIs),
+ ()=>63),
+ cIs) {
+ // before function declarations
+ assertEq(a(), 52);
+ assertEq(b(), 53);
+ assertEq(c(), 55);
+
+ function a() {
+ return 52;
+ }
+ function c() {
+ return 54;
+ }
+ function g() {
+ // close here
+ assertEq(a(), 52); // after function declaration
+ assertEq(b(), 53); // before function declaration
+ assertEq(c(), 55); // before last function declaration
+ }
+ // function declaration after closed
+ function b() {
+ return 53;
+ }
+
+ assertEq(a(), 52); // after function declaration
+ assertEq(b(), 53); // after function declaration
+ assertEq(c(), 55); // before last function declaration
+
+ g();
+ c = ()=>72;
+ assertEq(c(), 72); // after assignment in body
+ h();
+ assertEq(c(), 82); // after assignment in closed function
+
+ function h() {
+ assertEq(c(), 72); // after assignment in body
+ c = ()=>82;
+ assertEq(c(), 82); // after assignment in closed function
+ }
+ // function re-declaration after closed and assignment
+ function c() {
+ return 55;
+ }
+}
+f1(()=>42, 42, undefined, 62, undefined, 63);
+f1(()=>42, 42, undefined, 62, ()=>44, 44);
+f1(()=>42, 42, ()=>43, 43, undefined, 63);
+f1(()=>42, 42, ()=>43, 43, ()=>44, 44);
+
+function f2(a, aIs,
+ // call before body
+ b=(function() { assertEq(a(), aIs); })(),
+ // a inside body not accessible from defaults
+ c=function() { assertEq(a(), 42); }) {
+ function a() {
+ return 52;
+ }
+ function g() {
+ // close here
+ assertEq(a(), 52);
+ }
+
+ assertEq(a(), 52);
+ g();
+ c();
+}
+f2(()=>42, 42);
+
+function f3(a, aIs,
+ // call before body
+ // close here
+ b=(function() { assertEq(a(), aIs); })(),
+ // a inside body not accessible from defaults
+ c=function() { assertEq(a(), 42); }) {
+ function a() {
+ return 52;
+ }
+
+ assertEq(a(), 52);
+ c();
+}
+f3(()=>42, 42);
+
+function f4(a,
+ // assignment before body
+ b=a=()=>62,
+ c=(assertEq(a(), 62)),
+ e=(assertEq(a(), 62))) {
+ function a() {
+ return 52;
+ }
+ function g() {
+ // close here
+ assertEq(a(), 52);
+ }
+
+ assertEq(a(), 52);
+ g();
+}
+f4(()=>42);
+
+function f5(a, b, c, d) {
+ // before var/function declarations
+ assertEq(a(), 52);
+ assertEq(b(), 53);
+ assertEq(c(), 54);
+ assertEq(d(), 55);
+
+ function g() {
+ // before var/function declarations, called after var declarations
+ // close here
+ assertEq(a(), 52);
+ assertEq(b(), 63);
+ assertEq(c(), 54);
+ assertEq(d(), 65);
+ }
+
+ var a, b = ()=>63;
+ var c, d = ()=>65;
+
+ // after var declarations, before function declarations
+ assertEq(a(), 52);
+ assertEq(b(), 63);
+ assertEq(c(), 54);
+ assertEq(d(), 65);
+
+ function h() {
+ // after var declarations, before function declarations
+ assertEq(a(), 52);
+ assertEq(b(), 63);
+ assertEq(c(), 54);
+ assertEq(d(), 65);
+ }
+ function a() {
+ return 52;
+ }
+ function b() {
+ return 53;
+ }
+ function c() {
+ return 54;
+ }
+ function d() {
+ return 55;
+ }
+ function i() {
+ // after var/function declarations
+ assertEq(a(), 52);
+ assertEq(b(), 63);
+ assertEq(c(), 54);
+ assertEq(d(), 65);
+ }
+
+ // after var/function declarations
+ assertEq(a(), 52);
+ assertEq(b(), 63);
+ assertEq(c(), 54);
+ assertEq(d(), 65);
+ g();
+ h();
+ i();
+}
+f5(()=>42, ()=>43, ()=>44, ()=>45);
diff --git a/js/src/jit-test/tests/arguments/alias-function-not-closed.js b/js/src/jit-test/tests/arguments/alias-function-not-closed.js
new file mode 100644
index 0000000000..3de71f7c8e
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/alias-function-not-closed.js
@@ -0,0 +1,87 @@
+function f1(a, aIs, // without default parameter
+ b=()=>62, bIs, // with default parameter
+ // before function body
+ c=(assertEq(a(), aIs), assertEq(b(), bIs),
+ ()=>63),
+ cIs) {
+ // before function declarations
+ assertEq(a(), 52);
+ assertEq(b(), 53);
+ assertEq(c(), 55);
+
+ function a() {
+ return 52;
+ }
+ function b() {
+ return 53;
+ }
+ function c() {
+ return 54;
+ }
+
+ assertEq(a(), 52); // after function declaration
+ assertEq(b(), 53); // after function declaration
+ assertEq(c(), 55); // before last function declaration
+
+ c = ()=>72;
+ assertEq(c(), 72); // after assignment in body
+
+ // function re-declaration after assignment
+ function c() {
+ return 55;
+ }
+}
+f1(()=>42, 42, undefined, 62, undefined, 63);
+f1(()=>42, 42, undefined, 62, ()=>44, 44);
+f1(()=>42, 42, ()=>43, 43, undefined, 63);
+f1(()=>42, 42, ()=>43, 43, ()=>44, 44);
+
+function f2(a,
+ // assignment before body
+ b=a=()=>62,
+ c=(assertEq(a(), 62)),
+ e=(assertEq(a(), 62))) {
+ function a() {
+ return 52;
+ }
+
+ assertEq(a(), 52);
+}
+f2(()=>42);
+
+function f3(a, b, c, d) {
+ // before var/function declarations
+ assertEq(a(), 52);
+ assertEq(b(), 53);
+ assertEq(c(), 54);
+ assertEq(d(), 55);
+
+ var a, b = ()=>63;
+ var c, d = ()=>65;
+
+ // after var declarations, before function declarations
+ assertEq(a(), 52);
+ assertEq(b(), 63);
+ assertEq(c(), 54);
+ assertEq(d(), 65);
+
+ function a() {
+ return 52;
+ }
+ function b() {
+ return 53;
+ }
+ function c() {
+ return 54;
+ }
+ function d() {
+ return 55;
+ }
+
+ // after var/function declarations
+ assertEq(a(), 52);
+ assertEq(b(), 63);
+ assertEq(c(), 54);
+ assertEq(d(), 65);
+}
+f3(()=>42, ()=>43, ()=>44, ()=>45);
diff --git a/js/src/jit-test/tests/arguments/args-attributes.js b/js/src/jit-test/tests/arguments/args-attributes.js
new file mode 100644
index 0000000000..5182202371
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/args-attributes.js
@@ -0,0 +1,75 @@
+function strictArgs() {
+ return (function (a, b, c) {'use strict'; return arguments; })(1, 2);
+}
+
+function normalArgs() {
+ return (function (a, b, c) { return arguments; })(1, 2);
+}
+
+function checkProperty(options, prop, shouldThrow) {
+ var desc, orig;
+ var obj = options.strict ? strictArgs() : normalArgs();
+ var objType = options.strict ? "strict arguments." : "normal arguments.";
+
+ function check() {
+ orig = Object.getOwnPropertyDescriptor(obj, prop);
+
+ var threw = false;
+ try {
+ obj[prop] = obj[prop];
+ }
+ catch (e) {
+ threw = true;
+ }
+ assertEq(threw, shouldThrow, objType + prop + " threw");
+
+ if (orig === undefined) {
+ // The property wasn't defined, so we can skip it.
+ return;
+ }
+
+ desc = Object.getOwnPropertyDescriptor(obj, prop);
+ if ("value" in orig) {
+ assertEq(desc.value, orig.value, objType + prop + " value");
+ } else {
+ assertEq(desc.get, orig.get, objType + prop + " get");
+ assertEq(desc.set, orig.set, objType + prop + " set");
+ }
+ assertEq(desc.writable, orig.writable, objType + prop + " writable");
+ assertEq(desc.enumerable, orig.enumerable, objType + prop + " enumerable");
+ assertEq(desc.configurable, orig.configurable, objType + prop + " configurable");
+ }
+
+ check();
+
+ if (orig && orig.configurable) {
+ if(options.refresh) { obj = options.strict ? strictArgs() : normalArgs(); }
+ Object.defineProperty(obj, prop, {writable: false, enumerable: true});
+ check();
+
+ if(options.refresh) { obj = options.strict ? strictArgs() : normalArgs(); }
+ Object.defineProperty(obj, prop, {writable: true, enumerable: false});
+ check();
+
+ if(options.refresh) { obj = options.strict ? strictArgs() : normalArgs(); }
+ Object.defineProperty(obj, prop, {writable: false, configurable: false});
+ check();
+ }
+}
+
+checkProperty({strict: true, refresh: true}, 'callee', true);
+checkProperty({strict: true, refresh: false}, 'callee', true);
+checkProperty({strict: false, refresh: true}, 'callee', false);
+checkProperty({strict: false, refresh: false}, 'callee', false);
+
+checkProperty({strict: true, refresh: true}, 'length', false);
+checkProperty({strict: true, refresh: false}, 'length', false);
+checkProperty({strict: false, refresh: true}, 'length', false);
+checkProperty({strict: false, refresh: false}, 'length', false);
+
+for (var i = 0; i <= 5; i++) {
+ checkProperty({strict: true, refresh: true}, "" + i, false);
+ checkProperty({strict: true, refresh: false}, "" + i, false);
+ checkProperty({strict: false, refresh: true}, "" + i, false);
+ checkProperty({strict: false, refresh: false}, "" + i, false);
+}
diff --git a/js/src/jit-test/tests/arguments/args-createontrace.js b/js/src/jit-test/tests/arguments/args-createontrace.js
new file mode 100644
index 0000000000..9f9f0a4082
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/args-createontrace.js
@@ -0,0 +1,18 @@
+actual = '';
+expected = '5,4,3,2,1,X,5,4,3,2,1,Y,5,4,3,2,1,';
+
+function f() {
+ for (var i = 0; i < 5; ++i) {
+ var args = arguments;
+ appendToActual(args[i]);
+ }
+}
+
+f(5, 4, 3, 2, 1);
+appendToActual("X");
+f(5, 4, 3, 2, 1);
+appendToActual("Y");
+f(5, 4, 3, 2, 1);
+
+
+assertEq(actual, expected)
diff --git a/js/src/jit-test/tests/arguments/args-mochi-2.js b/js/src/jit-test/tests/arguments/args-mochi-2.js
new file mode 100644
index 0000000000..4fec2dd9b0
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/args-mochi-2.js
@@ -0,0 +1,23 @@
+actual = '';
+expected = 'true,';
+
+var isNotEmpty = function (args, i) {
+ var o = args[i];
+ if (!(o && o.length)) {
+ return false;
+ }
+ return true;
+};
+
+var f = function(obj) {
+ for (var i = 0; i < arguments.length; i++) {
+ if (!isNotEmpty(arguments, i))
+ return false;
+ }
+ return true;
+}
+
+appendToActual(f([1], [1], [1], "asdf", [1]));
+
+
+assertEq(actual, expected)
diff --git a/js/src/jit-test/tests/arguments/args-mochi-2a.js b/js/src/jit-test/tests/arguments/args-mochi-2a.js
new file mode 100644
index 0000000000..5c8895b15a
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/args-mochi-2a.js
@@ -0,0 +1,23 @@
+actual = '';
+expected = 'true,';
+
+function isNotEmpty(args, i) {
+ var o = args[i];
+ if (!(o && o.length)) {
+ return false;
+ }
+ return true;
+};
+
+function f(obj) {
+ for (var i = 0; i < arguments.length; i++) {
+ if (!isNotEmpty(arguments, i))
+ return false;
+ }
+ return true;
+}
+
+appendToActual(f([1], [1], [1], "asdf", [1]));
+
+
+assertEq(actual, expected)
diff --git a/js/src/jit-test/tests/arguments/args-mochi.js b/js/src/jit-test/tests/arguments/args-mochi.js
new file mode 100644
index 0000000000..c477ef0972
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/args-mochi.js
@@ -0,0 +1,17 @@
+actual = '';
+expected = 'true,';
+
+var isNotEmpty = function (obj) {
+ for (var i = 0; i < arguments.length; i++) {
+ var o = arguments[i];
+ if (!(o && o.length)) {
+ return false;
+ }
+ }
+ return true;
+};
+
+appendToActual(isNotEmpty([1], [1], [1], "asdf", [1]));
+
+
+assertEq(actual, expected)
diff --git a/js/src/jit-test/tests/arguments/args-mutate-length-1.js b/js/src/jit-test/tests/arguments/args-mutate-length-1.js
new file mode 100644
index 0000000000..cea55bc36a
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/args-mutate-length-1.js
@@ -0,0 +1,16 @@
+actual = '';
+expected = '0,0,0,';
+
+function f() {
+ arguments.length--;
+ for (var i = 0; i < arguments.length; ++i) {
+ appendToActual(i);
+ }
+}
+
+f(1, 2);
+f(1, 2);
+f(2, 2);
+
+
+assertEq(actual, expected)
diff --git a/js/src/jit-test/tests/arguments/args-mutate-length-2.js b/js/src/jit-test/tests/arguments/args-mutate-length-2.js
new file mode 100644
index 0000000000..1db881b423
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/args-mutate-length-2.js
@@ -0,0 +1,15 @@
+actual = '';
+expected = '0,1,0,1,0,1,';
+
+function f() {
+ for (var i = 0; i < arguments.length; ++i) {
+ appendToActual(i);
+ }
+}
+
+f(1, 2);
+f(1, 2);
+f(2, 2);
+
+
+assertEq(actual, expected)
diff --git a/js/src/jit-test/tests/arguments/args-range-2.js b/js/src/jit-test/tests/arguments/args-range-2.js
new file mode 100644
index 0000000000..393d574df5
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/args-range-2.js
@@ -0,0 +1,37 @@
+actual = '';
+expected = "undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,";
+
+var index;
+
+function h() {
+ for (var i = 0; i < 5; ++i) {
+ var a = arguments;
+ appendToActual(a[index]);
+ }
+}
+
+index = 0;
+h();
+index = -1;
+h();
+index = 1;
+h();
+
+index = -9999999;
+h(1, 2, 3);
+index = -1;
+h(1, 2, 3);
+index = 0;
+h(1, 2, 3);
+index = 1;
+h(1, 2, 3);
+index = 2;
+h(1, 2, 3);
+index = 3;
+h(1, 2, 3);
+index = 4;
+h(1, 2, 3);
+index = 9999999;
+h(1, 2, 3);
+
+assertEq(actual, expected)
diff --git a/js/src/jit-test/tests/arguments/args-range-const.js b/js/src/jit-test/tests/arguments/args-range-const.js
new file mode 100644
index 0000000000..d4a9193b9e
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/args-range-const.js
@@ -0,0 +1,14 @@
+actual = '';
+expected = 'undefined,undefined,undefined,undefined,undefined,';
+
+function h() {
+ for (var i = 0; i < 5; ++i) {
+ var a = arguments;
+ appendToActual(a[100]);
+ }
+}
+
+h();
+
+
+assertEq(actual, expected)
diff --git a/js/src/jit-test/tests/arguments/args-range.js b/js/src/jit-test/tests/arguments/args-range.js
new file mode 100644
index 0000000000..a5e40acaab
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/args-range.js
@@ -0,0 +1,18 @@
+actual = '';
+expected = '0,0,0,0,0,88,88,88,88,88,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,';
+
+function h(k) {
+ for (var i = 0; i < 5; ++i) {
+ var a = arguments;
+ appendToActual(a[k]);
+ }
+}
+
+h(0);
+h(2, 99, 88, 77);
+h(-5);
+h(46);
+h('adf');
+
+
+assertEq(actual, expected)
diff --git a/js/src/jit-test/tests/arguments/args-redefine-iterator-1.js b/js/src/jit-test/tests/arguments/args-redefine-iterator-1.js
new file mode 100644
index 0000000000..77241a6ae7
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/args-redefine-iterator-1.js
@@ -0,0 +1,14 @@
+function t()
+{
+ var a = arguments;
+ Object.defineProperty(a, Symbol.iterator, { });
+ for (var i = 0; i < 5; i++)
+ assertEq(a[Symbol.iterator], Array.prototype[Symbol.iterator]);
+
+ var desc = Object.getOwnPropertyDescriptor(a, Symbol.iterator);
+ assertEq(desc.value, Array.prototype[Symbol.iterator]);
+ assertEq(desc.writable, true);
+ assertEq(desc.enumerable, false);
+ assertEq(desc.configurable, true);
+}
+t();
diff --git a/js/src/jit-test/tests/arguments/args-redefine-iterator-2.js b/js/src/jit-test/tests/arguments/args-redefine-iterator-2.js
new file mode 100644
index 0000000000..186be930c4
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/args-redefine-iterator-2.js
@@ -0,0 +1,14 @@
+function t()
+{
+ var a = arguments;
+ Object.defineProperty(a, Symbol.iterator, { writable: false, enumerable: true, configurable: false });
+ for (var i = 0; i < 5; i++)
+ assertEq(a[Symbol.iterator], Array.prototype[Symbol.iterator]);
+
+ var desc = Object.getOwnPropertyDescriptor(a, Symbol.iterator);
+ assertEq(desc.value, Array.prototype[Symbol.iterator]);
+ assertEq(desc.writable, false);
+ assertEq(desc.enumerable, true);
+ assertEq(desc.configurable, false);
+}
+t();
diff --git a/js/src/jit-test/tests/arguments/args-redefine-length-1.js b/js/src/jit-test/tests/arguments/args-redefine-length-1.js
new file mode 100644
index 0000000000..c71c97b1cb
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/args-redefine-length-1.js
@@ -0,0 +1,7 @@
+function t()
+{
+ Object.defineProperty(arguments, "length", { value: 17 });
+ for (var i = 0; i < 5; i++)
+ assertEq(arguments.length, 17);
+}
+t();
diff --git a/js/src/jit-test/tests/arguments/args-redefine-length-2.js b/js/src/jit-test/tests/arguments/args-redefine-length-2.js
new file mode 100644
index 0000000000..fe1c9cf2fe
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/args-redefine-length-2.js
@@ -0,0 +1,8 @@
+function t()
+{
+ var a = arguments;
+ Object.defineProperty(a, "length", { value: 17 });
+ for (var i = 0; i < 5; i++)
+ assertEq(a.length, 17);
+}
+t();
diff --git a/js/src/jit-test/tests/arguments/args-redefine-length-3.js b/js/src/jit-test/tests/arguments/args-redefine-length-3.js
new file mode 100644
index 0000000000..a4d6823acf
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/args-redefine-length-3.js
@@ -0,0 +1,14 @@
+function t()
+{
+ var a = arguments;
+ Object.defineProperty(a, "length", { });
+ for (var i = 0; i < 5; i++)
+ assertEq(a.length, 0);
+
+ var desc = Object.getOwnPropertyDescriptor(a, "length");
+ assertEq(desc.value, 0);
+ assertEq(desc.writable, true);
+ assertEq(desc.enumerable, false);
+ assertEq(desc.configurable, true);
+}
+t();
diff --git a/js/src/jit-test/tests/arguments/args-redefine-length-4.js b/js/src/jit-test/tests/arguments/args-redefine-length-4.js
new file mode 100644
index 0000000000..1029e8fca3
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/args-redefine-length-4.js
@@ -0,0 +1,14 @@
+function t()
+{
+ var a = arguments;
+ Object.defineProperty(a, "length", { writable: false });
+ for (var i = 0; i < 5; i++)
+ assertEq(a.length, 0);
+
+ var desc = Object.getOwnPropertyDescriptor(a, "length");
+ assertEq(desc.value, 0);
+ assertEq(desc.writable, false);
+ assertEq(desc.enumerable, false);
+ assertEq(desc.configurable, true);
+}
+t();
diff --git a/js/src/jit-test/tests/arguments/args-redefine-length-5.js b/js/src/jit-test/tests/arguments/args-redefine-length-5.js
new file mode 100644
index 0000000000..2ae30bf0f7
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/args-redefine-length-5.js
@@ -0,0 +1,14 @@
+function t()
+{
+ var a = arguments;
+ Object.defineProperty(a, "length", { enumerable: true });
+ for (var i = 0; i < 5; i++)
+ assertEq(a.length, 0);
+
+ var desc = Object.getOwnPropertyDescriptor(a, "length");
+ assertEq(desc.value, 0);
+ assertEq(desc.writable, true);
+ assertEq(desc.enumerable, true);
+ assertEq(desc.configurable, true);
+}
+t();
diff --git a/js/src/jit-test/tests/arguments/args-redefine-length-6.js b/js/src/jit-test/tests/arguments/args-redefine-length-6.js
new file mode 100644
index 0000000000..a4b768d4bd
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/args-redefine-length-6.js
@@ -0,0 +1,14 @@
+function t()
+{
+ var a = arguments;
+ Object.defineProperty(a, "length", { configurable: false });
+ for (var i = 0; i < 5; i++)
+ assertEq(a.length, 0);
+
+ var desc = Object.getOwnPropertyDescriptor(a, "length");
+ assertEq(desc.value, 0);
+ assertEq(desc.writable, true);
+ assertEq(desc.enumerable, false);
+ assertEq(desc.configurable, false);
+}
+t();
diff --git a/js/src/jit-test/tests/arguments/args-redefine-length-7.js b/js/src/jit-test/tests/arguments/args-redefine-length-7.js
new file mode 100644
index 0000000000..042b224740
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/args-redefine-length-7.js
@@ -0,0 +1,14 @@
+function t()
+{
+ var a = arguments;
+ Object.defineProperty(a, "length", { value: 0 });
+ for (var i = 0; i < 5; i++)
+ assertEq(a.length, 0);
+
+ var desc = Object.getOwnPropertyDescriptor(a, "length");
+ assertEq(desc.value, 0);
+ assertEq(desc.writable, true);
+ assertEq(desc.enumerable, false);
+ assertEq(desc.configurable, true);
+}
+t();
diff --git a/js/src/jit-test/tests/arguments/args-sum.js b/js/src/jit-test/tests/arguments/args-sum.js
new file mode 100644
index 0000000000..04946e0fe8
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/args-sum.js
@@ -0,0 +1,16 @@
+actual = '';
+expected = '666,';
+
+function h() {
+ var ans = 0;
+ for (var i = 0; i < arguments.length; ++i) {
+ ans += arguments[i];
+ }
+ return ans;
+}
+
+var q = h(600, 60, 6);
+appendToActual(q);
+
+
+assertEq(actual, expected)
diff --git a/js/src/jit-test/tests/arguments/args-vargc.js b/js/src/jit-test/tests/arguments/args-vargc.js
new file mode 100644
index 0000000000..615323c48a
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/args-vargc.js
@@ -0,0 +1,18 @@
+actual = '';
+expected = '1 2,1 2,1 2,1 2,1 2,1 2,1 2,1 2,1 undefined,1 undefined,1 undefined,1 undefined,1 undefined,1 undefined,1 undefined,1 undefined,';
+
+function g(a, b) {
+ appendToActual(a + ' ' + b);
+}
+
+function f() {
+ for (var i = 0; i < 8; ++i) {
+ g.apply(this, arguments);
+ }
+}
+
+f(1, 2);
+f(1);
+
+
+assertEq(actual, expected)
diff --git a/js/src/jit-test/tests/arguments/args1.js b/js/src/jit-test/tests/arguments/args1.js
new file mode 100644
index 0000000000..3efc2994cf
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/args1.js
@@ -0,0 +1,15 @@
+actual = '';
+expected = 'a,';
+
+function f() {
+ arguments;
+}
+
+for (var i = 0; i < 1000; ++i) {
+ f(1, 2);
+}
+
+appendToActual('a')
+
+
+assertEq(actual, expected)
diff --git a/js/src/jit-test/tests/arguments/args10.js b/js/src/jit-test/tests/arguments/args10.js
new file mode 100644
index 0000000000..4f31084e06
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/args10.js
@@ -0,0 +1,16 @@
+actual = '';
+expected = 'function h(x, y) { return arguments; },2,4,8,';
+
+function h(x, y) { return arguments; }
+
+var p;
+for (var i = 0; i < 5; ++i) {
+ p = h(i, i*2);
+}
+appendToActual(p.callee);
+appendToActual(p.length);
+appendToActual(p[0]);
+appendToActual(p[1]);
+
+
+assertEq(actual, expected)
diff --git a/js/src/jit-test/tests/arguments/args11.js b/js/src/jit-test/tests/arguments/args11.js
new file mode 100644
index 0000000000..13e5893a5d
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/args11.js
@@ -0,0 +1,14 @@
+actual = '';
+expected = 'true,true,true,true,true,';
+
+function h() {
+ var a = arguments;
+ for (var i = 0; i < 5; ++i) {
+ appendToActual(a == arguments);
+ }
+}
+
+h();
+
+
+assertEq(actual, expected)
diff --git a/js/src/jit-test/tests/arguments/args2.js b/js/src/jit-test/tests/arguments/args2.js
new file mode 100644
index 0000000000..2c19c3198e
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/args2.js
@@ -0,0 +1,20 @@
+actual = '';
+expected = '151,';
+
+var g = 0;
+
+function add(a, b) {
+ g = a + b;
+}
+
+function f() {
+ add.apply(this, arguments);
+}
+
+for (var i = 0; i < 5; ++i) {
+ f(100, 51);
+}
+appendToActual(g);
+
+
+assertEq(actual, expected)
diff --git a/js/src/jit-test/tests/arguments/args2a.js b/js/src/jit-test/tests/arguments/args2a.js
new file mode 100644
index 0000000000..627aef0eb8
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/args2a.js
@@ -0,0 +1,17 @@
+actual = '';
+expected = 'g,g,g,g,g,';
+
+function g() {
+ appendToActual('g');
+}
+
+function f() {
+ g.apply(this, arguments);
+}
+
+for (var i = 0; i < 5; ++i) {
+ f();
+}
+
+
+assertEq(actual, expected)
diff --git a/js/src/jit-test/tests/arguments/args2b.js b/js/src/jit-test/tests/arguments/args2b.js
new file mode 100644
index 0000000000..aa477863e7
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/args2b.js
@@ -0,0 +1,17 @@
+actual = '';
+expected = 'g 0,g 1,g 2,g 3,g 4,';
+
+function g(x) {
+ appendToActual('g ' + x);
+}
+
+function f() {
+ g.apply(this, arguments);
+}
+
+for (var i = 0; i < 5; ++i) {
+ f(i);
+}
+
+
+assertEq(actual, expected)
diff --git a/js/src/jit-test/tests/arguments/args2c.js b/js/src/jit-test/tests/arguments/args2c.js
new file mode 100644
index 0000000000..9e83a424dc
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/args2c.js
@@ -0,0 +1,19 @@
+actual = '';
+expected = 'g 0 0,g 1 2,g 2 4,g 3 6,g 4 8,';
+
+function g(x, y) {
+ appendToActual('g ' + x + ' ' + y);
+ //appendToActual('g ' + x + ' ' + y);
+ //appendToActual('g ' + y);
+}
+
+function f() {
+ g.apply(this, arguments);
+}
+
+for (var i = 0; i < 5; ++i) {
+ f(i, i*2);
+}
+
+
+assertEq(actual, expected)
diff --git a/js/src/jit-test/tests/arguments/args2d.js b/js/src/jit-test/tests/arguments/args2d.js
new file mode 100644
index 0000000000..a95c821fe6
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/args2d.js
@@ -0,0 +1,17 @@
+actual = '';
+expected = 'g 0 0 0,g 1 2 1,g 2 4 4,g 3 6 9,g 4 8 16,';
+
+function g(x, y, z) {
+ appendToActual('g ' + x + ' ' + y + ' ' + z);
+}
+
+function f() {
+ g.apply(this, arguments);
+}
+
+for (var i = 0; i < 5; ++i) {
+ f(i, i*2, i*i);
+}
+
+
+assertEq(actual, expected)
diff --git a/js/src/jit-test/tests/arguments/args3.js b/js/src/jit-test/tests/arguments/args3.js
new file mode 100644
index 0000000000..7098521222
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/args3.js
@@ -0,0 +1,20 @@
+actual = '';
+expected = '51,';
+
+var g = 0;
+
+function add(a, b) {
+ g = a + b;
+}
+
+function f() {
+ g = arguments[1];
+}
+
+for (var i = 0; i < 10000; ++i) {
+ f(100, 51);
+}
+appendToActual(g);
+
+
+assertEq(actual, expected)
diff --git a/js/src/jit-test/tests/arguments/args4.js b/js/src/jit-test/tests/arguments/args4.js
new file mode 100644
index 0000000000..bd13c88156
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/args4.js
@@ -0,0 +1,21 @@
+actual = '';
+expected = '51,';
+
+var g = 0;
+
+function h(args) {
+ g = args[1];
+}
+
+function f() {
+ h(arguments);
+}
+
+for (var i = 0; i < 10000; ++i) {
+ f(100, 51);
+}
+
+appendToActual(g);
+
+
+assertEq(actual, expected)
diff --git a/js/src/jit-test/tests/arguments/args5.js b/js/src/jit-test/tests/arguments/args5.js
new file mode 100644
index 0000000000..8bd1c1cb46
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/args5.js
@@ -0,0 +1,24 @@
+actual = '';
+expected = '150,';
+
+var g = 0;
+
+function h(args) {
+ var ans = 0;
+ for (var i = 0; i < 5; ++i) {
+ ans += args[i];
+ }
+ g = ans;
+}
+
+function f() {
+ h(arguments);
+}
+
+for (var i = 0; i < 5; ++i) {
+ f(10, 20, 30, 40, 50);
+}
+appendToActual(g);
+
+
+assertEq(actual, expected)
diff --git a/js/src/jit-test/tests/arguments/args6.js b/js/src/jit-test/tests/arguments/args6.js
new file mode 100644
index 0000000000..a2fc60d36a
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/args6.js
@@ -0,0 +1,22 @@
+actual = '';
+expected = '6,';
+
+// tracing length
+
+var g = 0;
+
+function h(args) {
+ g = args.length;
+}
+
+function f() {
+ h(arguments);
+}
+
+for (var i = 0; i < 5; ++i) {
+ f(10, 20, 30, 40, 50, 60);
+}
+appendToActual(g);
+
+
+assertEq(actual, expected)
diff --git a/js/src/jit-test/tests/arguments/args6a.js b/js/src/jit-test/tests/arguments/args6a.js
new file mode 100644
index 0000000000..ce5206da1c
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/args6a.js
@@ -0,0 +1,23 @@
+actual = '';
+expected = '5,';
+
+// tracing length
+
+var g = 0;
+
+function h(args) {
+ for (var i = 0; i < 6; ++i)
+ g = args.length;
+}
+
+function f() {
+ h(arguments);
+}
+
+for (var i = 0; i < 5; ++i) {
+ f(10, 20, 30, 40, 50);
+}
+appendToActual(g);
+
+
+assertEq(actual, expected)
diff --git a/js/src/jit-test/tests/arguments/args7.js b/js/src/jit-test/tests/arguments/args7.js
new file mode 100644
index 0000000000..5d713e81ac
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/args7.js
@@ -0,0 +1,14 @@
+actual = '';
+expected = '5,4,3,2,1,';
+
+function f() {
+ while (arguments.length > 0) {
+ appendToActual(arguments[arguments.length-1]);
+ arguments.length--;
+ }
+}
+
+f(1, 2, 3, 4, 5);
+
+
+assertEq(actual, expected)
diff --git a/js/src/jit-test/tests/arguments/args8.js b/js/src/jit-test/tests/arguments/args8.js
new file mode 100644
index 0000000000..57938d9e23
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/args8.js
@@ -0,0 +1,14 @@
+actual = '';
+expected = '[object Arguments],[object Arguments],[object Arguments],[object Arguments],[object Arguments],';
+
+function h() {
+ return arguments;
+}
+
+for (var i = 0; i < 5; ++i) {
+ var p = h(i, i*2);
+ appendToActual(p);
+}
+
+
+assertEq(actual, expected)
diff --git a/js/src/jit-test/tests/arguments/args9.js b/js/src/jit-test/tests/arguments/args9.js
new file mode 100644
index 0000000000..79a54dfaef
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/args9.js
@@ -0,0 +1,16 @@
+actual = '';
+expected = '10,20,';
+
+function h() {
+ var p;
+ for (var i = 0; i < 5; ++i) {
+ p = arguments;
+ }
+ appendToActual(p[0]);
+ appendToActual(p[1]);
+}
+
+h(10, 20);
+
+
+assertEq(actual, expected)
diff --git a/js/src/jit-test/tests/arguments/argsub.js b/js/src/jit-test/tests/arguments/argsub.js
new file mode 100644
index 0000000000..e52992c6b5
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/argsub.js
@@ -0,0 +1,13 @@
+actual = '';
+expected = 'undefined,undefined,undefined,undefined,undefined,';
+
+function h() {
+ for (var i = 0; i < 5; ++i) {
+ appendToActual(arguments[100]);
+ }
+}
+
+h();
+
+
+assertEq(actual, expected)
diff --git a/js/src/jit-test/tests/arguments/argsx-1.js b/js/src/jit-test/tests/arguments/argsx-1.js
new file mode 100644
index 0000000000..ea9d0906e4
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/argsx-1.js
@@ -0,0 +1,22 @@
+actual = '';
+expected = "function f() {\n var a = arguments;\n \n for (var i = 0; i < 10; ++i) {\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},3,1,2,function f() {\n var a = arguments;\n \n for (var i = 0; i < 10; ++i) {\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},3,1,2,function f() {\n var a = arguments;\n \n for (var i = 0; i < 10; ++i) {\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},3,1,2,function f() {\n var a = arguments;\n \n for (var i = 0; i < 10; ++i) {\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},3,1,2,function f() {\n var a = arguments;\n \n for (var i = 0; i < 10; ++i) {\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},3,1,2,function f() {\n var a = arguments;\n \n for (var i = 0; i < 10; ++i) {\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},3,1,2,function f() {\n var a = arguments;\n \n for (var i = 0; i < 10; ++i) {\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},3,1,2,function f() {\n var a = arguments;\n \n for (var i = 0; i < 10; ++i) {\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},3,1,2,function f() {\n var a = arguments;\n \n for (var i = 0; i < 10; ++i) {\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},3,1,2,function f() {\n var a = arguments;\n \n for (var i = 0; i < 10; ++i) {\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},3,1,2,function f() {\n var a = arguments;\n \n for (var i = 0; i < 10; ++i) {\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},2,[object Object],a,function f() {\n var a = arguments;\n \n for (var i = 0; i < 10; ++i) {\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},2,[object Object],a,function f() {\n var a = arguments;\n \n for (var i = 0; i < 10; ++i) {\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},2,[object Object],a,function f() {\n var a = arguments;\n \n for (var i = 0; i < 10; ++i) {\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},2,[object Object],a,function f() {\n var a = arguments;\n \n for (var i = 0; i < 10; ++i) {\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},2,[object Object],a,function f() {\n var a = arguments;\n \n for (var i = 0; i < 10; ++i) {\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},2,[object Object],a,function f() {\n var a = arguments;\n \n for (var i = 0; i < 10; ++i) {\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},2,[object Object],a,function f() {\n var a = arguments;\n \n for (var i = 0; i < 10; ++i) {\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},2,[object Object],a,function f() {\n var a = arguments;\n \n for (var i = 0; i < 10; ++i) {\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},2,[object Object],a,function f() {\n var a = arguments;\n \n for (var i = 0; i < 10; ++i) {\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},2,[object Object],a,function f() {\n var a = arguments;\n \n for (var i = 0; i < 10; ++i) {\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},2,abc,def,function f() {\n var a = arguments;\n \n for (var i = 0; i < 10; ++i) {\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},2,abc,def,function f() {\n var a = arguments;\n \n for (var i = 0; i < 10; ++i) {\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},2,abc,def,function f() {\n var a = arguments;\n \n for (var i = 0; i < 10; ++i) {\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},2,abc,def,function f() {\n var a = arguments;\n \n for (var i = 0; i < 10; ++i) {\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},2,abc,def,function f() {\n var a = arguments;\n \n for (var i = 0; i < 10; ++i) {\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},2,abc,def,function f() {\n var a = arguments;\n \n for (var i = 0; i < 10; ++i) {\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},2,abc,def,function f() {\n var a = arguments;\n \n for (var i = 0; i < 10; ++i) {\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},2,abc,def,function f() {\n var a = arguments;\n \n for (var i = 0; i < 10; ++i) {\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},2,abc,def,function f() {\n var a = arguments;\n \n for (var i = 0; i < 10; ++i) {\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},2,abc,def,"
+
+// args object created by interpreter
+
+function f() {
+ var a = arguments;
+
+ for (var i = 0; i < 10; ++i) {
+ appendToActual(a.callee);
+ appendToActual(a.length);
+ appendToActual(a[0]);
+ appendToActual(a[1]);
+ }
+}
+
+f(1, 2, 3);
+f({}, 'a');
+f('abc', 'def');
+
+
+assertEq(actual, expected)
diff --git a/js/src/jit-test/tests/arguments/argsx-2.js b/js/src/jit-test/tests/arguments/argsx-2.js
new file mode 100644
index 0000000000..5fe9af97d8
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/argsx-2.js
@@ -0,0 +1,23 @@
+actual = '';
+expected = "function f() {\n var a = arguments;\n \n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n},3,1,2,function f() {\n var a = arguments;\n \n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n},3,1,2,function f() {\n var a = arguments;\n \n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n},3,1,2,function f() {\n var a = arguments;\n \n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n},3,1,2,function f() {\n var a = arguments;\n \n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n},3,1,2,function f() {\n var a = arguments;\n \n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n},3,1,2,function f() {\n var a = arguments;\n \n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n},3,1,2,function f() {\n var a = arguments;\n \n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n},3,1,2,function f() {\n var a = arguments;\n \n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n},3,1,2,function f() {\n var a = arguments;\n \n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n},3,1,2,function f() {\n var a = arguments;\n \n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n},2,[object Object],a,function f() {\n var a = arguments;\n \n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n},2,[object Object],a,function f() {\n var a = arguments;\n \n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n},2,[object Object],a,function f() {\n var a = arguments;\n \n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n},2,[object Object],a,function f() {\n var a = arguments;\n \n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n},2,[object Object],a,function f() {\n var a = arguments;\n \n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n},2,[object Object],a,function f() {\n var a = arguments;\n \n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n},2,[object Object],a,function f() {\n var a = arguments;\n \n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n},2,[object Object],a,function f() {\n var a = arguments;\n \n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n},2,[object Object],a,function f() {\n var a = arguments;\n \n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n},2,[object Object],a,function f() {\n var a = arguments;\n \n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n},2,abc,def,function f() {\n var a = arguments;\n \n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n},2,abc,def,function f() {\n var a = arguments;\n \n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n},2,abc,def,function f() {\n var a = arguments;\n \n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n},2,abc,def,function f() {\n var a = arguments;\n \n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n},2,abc,def,function f() {\n var a = arguments;\n \n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n},2,abc,def,function f() {\n var a = arguments;\n \n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n},2,abc,def,function f() {\n var a = arguments;\n \n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n},2,abc,def,function f() {\n var a = arguments;\n \n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n},2,abc,def,function f() {\n var a = arguments;\n \n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n},2,abc,def,"
+
+// args object created on trace
+
+function f() {
+ var a = arguments;
+
+ appendToActual(a.callee);
+ appendToActual(a.length);
+ appendToActual(a[0]);
+ appendToActual(a[1]);
+}
+
+for (var i = 0; i < 10; ++i)
+ f(1, 2, 3);
+for (var i = 0; i < 10; ++i)
+ f({}, 'a');
+for (var i = 0; i < 10; ++i)
+ f('abc', 'def');
+
+
+assertEq(actual, expected)
diff --git a/js/src/jit-test/tests/arguments/argsx-3.js b/js/src/jit-test/tests/arguments/argsx-3.js
new file mode 100644
index 0000000000..ad5942c618
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/argsx-3.js
@@ -0,0 +1,27 @@
+actual = '';
+expected = "true,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},4,true,1,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},4,true,1,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},4,true,1,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},4,true,1,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},4,true,1,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},4,true,1,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},4,true,1,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},4,true,1,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},4,true,1,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},4,true,1,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},4,false,1,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},4,false,1,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},4,false,1,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},4,false,1,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},4,false,1,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},4,false,1,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},4,false,1,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},4,false,1,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},4,false,1,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},4,false,1,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},3,false,[object Object],function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},3,false,[object Object],function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},3,false,[object Object],function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},3,false,[object Object],function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},3,false,[object Object],function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},3,false,[object Object],function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},3,false,[object Object],function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},3,false,[object Object],function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},3,false,[object Object],function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},3,false,[object Object],function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},3,false,abc,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},3,false,abc,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},3,false,abc,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},3,false,abc,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},3,false,abc,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},3,false,abc,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},3,false,abc,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},3,false,abc,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},3,false,abc,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},3,false,abc,"
+
+// args object created by interpreter at record time, but not always at run time.
+
+function f(t) {
+ if (t) {
+ var b = arguments;
+ appendToActual(b[0]);
+ }
+
+ for (var i = 0; i < 10; ++i) {
+ var a = arguments;
+ appendToActual(a.callee);
+ appendToActual(a.length);
+ appendToActual(a[0]);
+ appendToActual(a[1]);
+ }
+}
+
+f(true, 1, 2, 3);
+f(false, 1, 2, 3);
+f(false, {}, 'a');
+f(false, 'abc', 'def');
+
+
+assertEq(actual, expected)
diff --git a/js/src/jit-test/tests/arguments/argsx-3a.js b/js/src/jit-test/tests/arguments/argsx-3a.js
new file mode 100644
index 0000000000..fd278c039b
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/argsx-3a.js
@@ -0,0 +1,27 @@
+actual = '';
+expected = "function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},4,false,1,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},4,false,1,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},4,false,1,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},4,false,1,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},4,false,1,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},4,false,1,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},4,false,1,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},4,false,1,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},4,false,1,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},4,false,1,true,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},4,true,1,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},4,true,1,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},4,true,1,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},4,true,1,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},4,true,1,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},4,true,1,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},4,true,1,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},4,true,1,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},4,true,1,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},4,true,1,true,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},3,true,[object Object],function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},3,true,[object Object],function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},3,true,[object Object],function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},3,true,[object Object],function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},3,true,[object Object],function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},3,true,[object Object],function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},3,true,[object Object],function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},3,true,[object Object],function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},3,true,[object Object],function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},3,true,[object Object],true,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},3,true,abc,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},3,true,abc,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},3,true,abc,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},3,true,abc,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},3,true,abc,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},3,true,abc,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},3,true,abc,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},3,true,abc,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},3,true,abc,function f(t) {\n if (t) {\n var b = arguments;\n appendToActual(b[0]);\n }\n \n for (var i = 0; i < 10; ++i) {\n var a = arguments;\n appendToActual(a.callee);\n appendToActual(a.length);\n appendToActual(a[0]);\n appendToActual(a[1]);\n }\n},3,true,abc,"
+
+// args object not created by interpreter at record time, but maybe at run time
+
+function f(t) {
+ if (t) {
+ var b = arguments;
+ appendToActual(b[0]);
+ }
+
+ for (var i = 0; i < 10; ++i) {
+ var a = arguments;
+ appendToActual(a.callee);
+ appendToActual(a.length);
+ appendToActual(a[0]);
+ appendToActual(a[1]);
+ }
+}
+
+f(false, 1, 2, 3);
+f(true, 1, 2, 3);
+f(true, {}, 'a');
+f(true, 'abc', 'def');
+
+
+assertEq(actual, expected)
diff --git a/js/src/jit-test/tests/arguments/argsx-4.js b/js/src/jit-test/tests/arguments/argsx-4.js
new file mode 100644
index 0000000000..b52b14853c
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/argsx-4.js
@@ -0,0 +1,23 @@
+actual = '';
+expected = '[object Arguments] undefined undefined,[object Arguments] undefined undefined,';
+
+function f() {
+ g(arguments);
+}
+
+function g(a, b, c) {
+ h(arguments);
+ a = 1;
+ b = 2;
+ c = 3;
+ h(arguments);
+}
+
+function h(a, b, c) {
+ appendToActual(a + ' ' + b + ' ' + c);
+}
+
+f(4, 5, 6);
+
+
+assertEq(actual, expected)
diff --git a/js/src/jit-test/tests/arguments/arguments-on-proto.js b/js/src/jit-test/tests/arguments/arguments-on-proto.js
new file mode 100644
index 0000000000..745c77b9da
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/arguments-on-proto.js
@@ -0,0 +1,27 @@
+function create() {
+ return Object.create(arguments, {2: {value: "shadowed"}});
+}
+
+function createStrict() {
+ "use strict";
+ return Object.create(arguments, {40: {value: "shadowed2"}});
+}
+
+function f() {
+ var args = [createStrict(10, 20, 30, 40), create(1, 2, 3)];
+
+ var threshold = getJitCompilerOptions()["ion.warmup.trigger"] + 101;
+
+ for (var i = 0; i < threshold; i++) {
+ // We switch between different arguments objects, to make
+ // sure the right IC is triggered.
+ var a = args[i % 2];
+ assertEq(a.length, (i % 2) ? 3 : 4);
+ assertEq(a[0], (i % 2) ? 1 : 10);
+ assertEq(a[1], (i % 2) ? 2 : 20);
+ assertEq(a[2], (i % 2) ? "shadowed" : 30);
+ assertEq(a[3], (i % 2) ? undefined : 40);
+ }
+}
+
+f();
diff --git a/js/src/jit-test/tests/arguments/bug-917585-relax-aliasing-constraints.js b/js/src/jit-test/tests/arguments/bug-917585-relax-aliasing-constraints.js
new file mode 100644
index 0000000000..03f77d7a7f
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/bug-917585-relax-aliasing-constraints.js
@@ -0,0 +1,18 @@
+
+function foo(a, b) {
+ blah(function (x) { a = x; }, b);
+ return arguments[0];
+}
+
+function blah(f, b) {
+ f(b);
+}
+
+function main() {
+ for (var i = 0; i < 1500; i++) {
+ var x = foo(i, i*2);
+ assertEq(x, i*2);
+ }
+}
+
+main();
diff --git a/js/src/jit-test/tests/arguments/bug1051760.js b/js/src/jit-test/tests/arguments/bug1051760.js
new file mode 100644
index 0000000000..aeb54feecc
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/bug1051760.js
@@ -0,0 +1,4 @@
+function test() {
+ eval("var { [arguments] : y } = {};");
+}
+test();
diff --git a/js/src/jit-test/tests/arguments/bug1227287.js b/js/src/jit-test/tests/arguments/bug1227287.js
new file mode 100644
index 0000000000..d0c6b88262
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/bug1227287.js
@@ -0,0 +1,8 @@
+// Note: Ion/Warp have known issues with function.arguments. See bug 1626294.
+
+function f(y) {
+ y = 1;
+ assertEq(arguments.callee.arguments[0], 1);
+ return () => y;
+}
+f(0);
diff --git a/js/src/jit-test/tests/arguments/bug1423937.js b/js/src/jit-test/tests/arguments/bug1423937.js
new file mode 100644
index 0000000000..928a07a484
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/bug1423937.js
@@ -0,0 +1,17 @@
+// |jit-test| exitstatus: 6;
+
+var global = 0;
+setInterruptCallback(function() {
+ foo("A");
+});
+function foo(x) {
+ for (var i = 0; i < 1000; i++) {
+ var stack = getBacktrace({args: true});
+ }
+ if (global > 2) return;
+ global++;
+ interruptIf(true);
+ foo("B");
+ (function() { g = x;});
+}
+foo("C");
diff --git a/js/src/jit-test/tests/arguments/bug1503071.js b/js/src/jit-test/tests/arguments/bug1503071.js
new file mode 100644
index 0000000000..d34e9d598d
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/bug1503071.js
@@ -0,0 +1,16 @@
+// |jit-test| exitstatus: 6
+var g = true
+
+setInterruptCallback(function() {
+ print(getBacktrace({args: true}));
+});
+
+function foo(bt, x=3, y = eval("g")) {
+ if (g) {
+ g = false
+ interruptIf(true);
+ foo(false);
+ }
+ (function() { n = bt;});
+}
+foo(false);
diff --git a/js/src/jit-test/tests/arguments/bug1621265.js b/js/src/jit-test/tests/arguments/bug1621265.js
new file mode 100644
index 0000000000..8eaf37c480
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/bug1621265.js
@@ -0,0 +1,17 @@
+// |jit-test| error:null
+
+function f(a) {
+ // Add |arguments[0]| to mark the function as having an arguments
+ // access. Even though there's a |JSOp::SetArg| bytecode is present, we can
+ // still use lazy arguments here, because the |JSOp::SetArg| bytecode is
+ // always unreachable.
+ var v = arguments[0];
+ assertEq(v, 1);
+
+ // Anything below the |throw| is unreachable.
+ throw null;
+
+ // Add an unreachable |JSOp::SetArg| bytecode.
+ a = 4;
+}
+f(1);
diff --git a/js/src/jit-test/tests/arguments/bug503772.js b/js/src/jit-test/tests/arguments/bug503772.js
new file mode 100644
index 0000000000..6ef8e1f974
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/bug503772.js
@@ -0,0 +1,16 @@
+function f(a) {
+ // Create arguments on trace
+ var z = arguments;
+ // Make f need a call object
+ if (false) {
+ var p = function() { ++a; }
+ }
+}
+
+function g() {
+ for (var i = 0; i < 5; ++i) {
+ f(2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
+ }
+}
+
+g();
diff --git a/js/src/jit-test/tests/arguments/bug508178.js b/js/src/jit-test/tests/arguments/bug508178.js
new file mode 100644
index 0000000000..c779c82200
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/bug508178.js
@@ -0,0 +1,18 @@
+actual = '';
+expected = 'g,g,g,g,f,';
+
+function test() {
+ var testargs = arguments;
+ var f = function (name, which) {
+ var args = [testargs, arguments];
+ return args[which][0];
+ };
+ var arr = [0, 0, 0, 0, 1];
+ for (var i = 0; i < arr.length; i++)
+ arr[i] = f("f", arr[i]);
+ appendToActual(arr);
+}
+test('g');
+
+
+assertEq(actual, expected)
diff --git a/js/src/jit-test/tests/arguments/bug633020.js b/js/src/jit-test/tests/arguments/bug633020.js
new file mode 100644
index 0000000000..6e30bd1250
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/bug633020.js
@@ -0,0 +1,11 @@
+var N = 10;
+function f(b) {
+ var a = [];
+ for (var i = 0; i < N; i++)
+ a[i] = {};
+ a[N-1] = arguments;
+ for (var i = 0; i < N; i++)
+ a[i][0] = i;
+ assertEq(b, N - 1);
+}
+f(null);
diff --git a/js/src/jit-test/tests/arguments/bug843985.js b/js/src/jit-test/tests/arguments/bug843985.js
new file mode 100644
index 0000000000..3365b9ec87
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/bug843985.js
@@ -0,0 +1,5 @@
+
+for (x in (function*() {
+ eval("arguments[0]");
+ yield;
+})())(function() {})
diff --git a/js/src/jit-test/tests/arguments/bug956173.js b/js/src/jit-test/tests/arguments/bug956173.js
new file mode 100644
index 0000000000..d88efaa7ab
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/bug956173.js
@@ -0,0 +1,7 @@
+function foo() {
+ {
+ let x=arguments;
+ return function() { return x; };
+ }
+}
+foo()();
diff --git a/js/src/jit-test/tests/arguments/defaults-basic.js b/js/src/jit-test/tests/arguments/defaults-basic.js
new file mode 100644
index 0000000000..bca8528581
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/defaults-basic.js
@@ -0,0 +1,35 @@
+function f1(a, bIs, b=3) {
+ assertEq(a, 1);
+ assertEq(b, bIs);
+}
+assertEq(f1.length, 2);
+f1(1, 3);
+f1(1, 42, 42);
+f1(1, 3, undefined);
+function f2(a, bIs, cIs, b=3, c=4) {
+ assertEq(a, 1);
+ assertEq(b, bIs);
+ assertEq(c, cIs);
+}
+assertEq(f2.length, 3);
+f2(1, 3, 4);
+f2(1, 42, 4, 42);
+f2(1, 42, 43, 42, 43);
+f2(1, 3, 4, undefined);
+f2(1, 42, 4, 42, undefined);
+f2(1, 3, 42, undefined, 42);
+function f3(a, b, c=4) {
+ assertEq(a, 1);
+ assertEq(b, undefined);
+ assertEq(c, 4);
+}
+f3(1);
+function f4(a, bIs, cIs, b=3, c) {
+ assertEq(a, 1);
+ assertEq(b, bIs);
+ assertEq(c, cIs);
+}
+assertEq(f4.length, 3);
+f4(1, 3, undefined);
+f4(1, 4, undefined, 4);
+f4(1, 4, 5, 4, 5);
diff --git a/js/src/jit-test/tests/arguments/defaults-bound-to-function.js b/js/src/jit-test/tests/arguments/defaults-bound-to-function.js
new file mode 100644
index 0000000000..28a1c3b455
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/defaults-bound-to-function.js
@@ -0,0 +1,43 @@
+load(libdir + "asserts.js");
+
+function f(a=42) {
+ return a;
+ function a() { return 19; }
+}
+assertEq(f()(), 19);
+function h(a=b, b=43) {
+ return [a, b];
+ function b() { return 42; }
+}
+// TDZ
+assertThrowsInstanceOf(h, ReferenceError);
+function i(b=FAIL) {
+ function b() {}
+}
+assertThrowsInstanceOf(i, ReferenceError);
+i(42);
+function j(a=(b=42), b=8) {
+ return b;
+ function b() { return 43; }
+}
+// TDZ
+assertThrowsInstanceOf(j, ReferenceError);
+function k(a=(b=42), b=8) {
+ return b;
+ function a() { return 43; }
+}
+// TDZ
+assertThrowsInstanceOf(k, ReferenceError);
+function l(a=8, b=a) {
+ return b;
+ function a() { return 42; }
+}
+assertEq(l(), 8);
+function m([a, b]=[1, 2], c=a) {
+ function a() { return 42; }
+ assertEq(typeof a, "function");
+ assertEq(a(), 42);
+ assertEq(b, 2);
+ assertEq(c, 1);
+}
+m();
diff --git a/js/src/jit-test/tests/arguments/defaults-bug759904.js b/js/src/jit-test/tests/arguments/defaults-bug759904.js
new file mode 100644
index 0000000000..f1ea39208a
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/defaults-bug759904.js
@@ -0,0 +1,4 @@
+function* a(b=3) {
+ yield
+}
+a()
diff --git a/js/src/jit-test/tests/arguments/defaults-call-function.js b/js/src/jit-test/tests/arguments/defaults-call-function.js
new file mode 100644
index 0000000000..d3dcda0865
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/defaults-call-function.js
@@ -0,0 +1,15 @@
+load(libdir + "asserts.js");
+
+function f1(a=g()) {
+ function g() {
+ }
+}
+assertThrowsInstanceOf(f1, ReferenceError);
+
+function f2(a=g()) {
+ function g() {
+ return 43;
+ }
+ assertEq(a, 42);
+}
+f2(42);
diff --git a/js/src/jit-test/tests/arguments/defaults-destructuring-array.js b/js/src/jit-test/tests/arguments/defaults-destructuring-array.js
new file mode 100644
index 0000000000..e3994a8795
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/defaults-destructuring-array.js
@@ -0,0 +1,17 @@
+function f1(a, bIs, [b]=[3]) {
+ assertEq(a, 1);
+ assertEq(b, bIs);
+}
+assertEq(f1.length, 2);
+f1(1, 3);
+f1(1, 42, [42]);
+f1(1, 3, undefined);
+
+function f2(a, bIs, [b]=[]) {
+ assertEq(a, 1);
+ assertEq(b, bIs);
+}
+assertEq(f2.length, 2);
+f2(1, undefined);
+f2(1, 42, [42]);
+f2(1, undefined, undefined);
diff --git a/js/src/jit-test/tests/arguments/defaults-destructuring-expression-closure.js b/js/src/jit-test/tests/arguments/defaults-destructuring-expression-closure.js
new file mode 100644
index 0000000000..750289e44e
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/defaults-destructuring-expression-closure.js
@@ -0,0 +1,19 @@
+function f1(a, bIs, cIs, dIs, {b}={b: 3}, c=4, [d]=[5]) {
+ assertEq(a, 1),
+ assertEq(b, bIs),
+ assertEq(c, cIs),
+ assertEq(d, dIs)
+}
+assertEq(f1.length, 4);
+f1(1, 3, 4, 5);
+f1(1, 42, 43, 44, {b: 42}, 43, [44]);
+
+let f2 = (a, bIs, cIs, dIs, {b}={b: 3}, c=4, [d]=[5]) => (
+ assertEq(a, 1),
+ assertEq(b, bIs),
+ assertEq(c, cIs),
+ assertEq(d, dIs)
+);
+assertEq(f2.length, 4);
+f2(1, 3, 4, 5);
+f2(1, 42, 43, 44, {b: 42}, 43, [44]);
diff --git a/js/src/jit-test/tests/arguments/defaults-destructuring-function-expression.js b/js/src/jit-test/tests/arguments/defaults-destructuring-function-expression.js
new file mode 100644
index 0000000000..9517a5c4d4
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/defaults-destructuring-function-expression.js
@@ -0,0 +1,9 @@
+let f = function(a, bIs, cIs, dIs, {b}={b: 3}, c=4, [d]=[5]) {
+ assertEq(a, 1);
+ assertEq(b, bIs);
+ assertEq(c, cIs);
+ assertEq(d, dIs);
+};
+assertEq(f.length, 4);
+f(1, 3, 4, 5);
+f(1, 42, 43, 44, {b: 42}, 43, [44]);
diff --git a/js/src/jit-test/tests/arguments/defaults-destructuring-mixed-default-value.js b/js/src/jit-test/tests/arguments/defaults-destructuring-mixed-default-value.js
new file mode 100644
index 0000000000..e54255579e
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/defaults-destructuring-mixed-default-value.js
@@ -0,0 +1,55 @@
+function f1(a=1,
+ [b, c=(assertEq(a, 2), a=3, 42)]=[(assertEq(a, 1), a=2, 43)],
+ {d, e:e=(assertEq(a, 4), a=5, 44)}={d: (assertEq(a, 3), a=4, 45)},
+ f=(assertEq(a, 5), a=6, 46)) {
+ assertEq(a, 6);
+ assertEq(b, 43);
+ assertEq(c, 42);
+ assertEq(d, 45);
+ assertEq(e, 44);
+ assertEq(f, 46);
+}
+assertEq(f1.length, 0);
+f1();
+
+function f2(a=1,
+ [b, c=assertEq(false)]=[(assertEq(a, 1), a=2, 42), (assertEq(a, 2), a=3, 43)],
+ {d, e:e=assertEq(false)}={d: (assertEq(a, 3), a=4, 44), e: (assertEq(a, 4), a=5, 45)},
+ f=(assertEq(a, 5), a=6, 46)) {
+ assertEq(a, 6);
+ assertEq(b, 42);
+ assertEq(c, 43);
+ assertEq(d, 44);
+ assertEq(e, 45);
+ assertEq(f, 46);
+}
+assertEq(f2.length, 0);
+f2();
+
+function f3(a=1,
+ [b, c=(assertEq(a, 1), a=2, 42)]=[assertEq(false)],
+ {d, e:e=(assertEq(a, 2), a=3, 43)}={d: assertEq(false)},
+ f=(assertEq(a, 3), a=4, 44)) {
+ assertEq(a, 4);
+ assertEq(b, 8);
+ assertEq(c, 42);
+ assertEq(d, 9);
+ assertEq(e, 43);
+ assertEq(f, 44);
+}
+assertEq(f3.length, 0);
+f3(undefined, [8], {d: 9});
+
+function f4(a=1,
+ [b, c=assertEq(false)]=[assertEq(false), assertEq(false)],
+ {d, e:e=assertEq(false)}={d: assertEq(false), e: assertEq(false)},
+ f=(assertEq(a, 1), a=2, 42)) {
+ assertEq(a, 2);
+ assertEq(b, 8);
+ assertEq(c, 9);
+ assertEq(d, 10);
+ assertEq(e, 11);
+ assertEq(f, 42);
+}
+assertEq(f4.length, 0);
+f4(undefined, [8, 9], {d: 10, e: 11});
diff --git a/js/src/jit-test/tests/arguments/defaults-destructuring-mixed.js b/js/src/jit-test/tests/arguments/defaults-destructuring-mixed.js
new file mode 100644
index 0000000000..74cb00f1f2
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/defaults-destructuring-mixed.js
@@ -0,0 +1,29 @@
+function f1(a, bIs, cIs, dIs, b=3, {c}={c: 4}, [d]=[5]) {
+ assertEq(a, 1);
+ assertEq(b, bIs);
+ assertEq(c, cIs);
+ assertEq(d, dIs);
+}
+assertEq(f1.length, 4);
+f1(1, 3, 4, 5);
+f1(1, 42, 4, 5, 42);
+f1(1, 42, 43, 5, 42, {c: 43});
+f1(1, 42, 43, 44, 42, {c: 43}, [44]);
+f1(1, 3, 4, 5, undefined);
+f1(1, 42, 4, 5, 42, undefined);
+f1(1, 3, 42, 5, undefined, {c: 42});
+f1(1, 3, 4, 42, undefined, undefined, [42]);
+
+function f2(a, bIs, cIs, dIs, eIs, {b}={b: 3}, [c]=[b], d=c, {ee: e}={ee: d}) {
+ assertEq(a, 1);
+ assertEq(b, bIs);
+ assertEq(c, cIs);
+ assertEq(d, dIs);
+ assertEq(e, eIs);
+}
+assertEq(f2.length, 5);
+f2(1, 3, 3, 3, 3);
+f2(1, 42, 42, 42, 42, {b: 42});
+f2(1, 42, 43, 43, 43, {b: 42}, [43]);
+f2(1, 42, 43, 44, 44, {b: 42}, [43], 44);
+f2(1, 42, 43, 44, 45, {b: 42}, [43], 44, {ee: 45});
diff --git a/js/src/jit-test/tests/arguments/defaults-destructuring-object.js b/js/src/jit-test/tests/arguments/defaults-destructuring-object.js
new file mode 100644
index 0000000000..0ca970a144
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/defaults-destructuring-object.js
@@ -0,0 +1,27 @@
+function f1(a, bIs, cIs, {b}={b: 3}, {cc: c}={cc: 4}) {
+ assertEq(a, 1);
+ assertEq(b, bIs);
+ assertEq(c, cIs);
+}
+assertEq(f1.length, 3);
+f1(1, 3, 4);
+f1(1, 42, 4, {b: 42});
+f1(1, 42, 4, {b: 42}, undefined);
+f1(1, 42, 43, {b: 42}, {cc: 43});
+f1(1, 3, 4, undefined);
+f1(1, 3, 4, undefined, undefined);
+f1(1, 3, 43, undefined, {cc: 43});
+
+function f2(a, bIs, cIs, {b}={}, {cc: c}={}) {
+ assertEq(a, 1);
+ assertEq(b, bIs);
+ assertEq(c, cIs);
+}
+assertEq(f2.length, 3);
+f2(1, undefined, undefined);
+f2(1, 42, undefined, {b: 42});
+f2(1, 42, undefined, {b: 42}, undefined);
+f2(1, 42, 43, {b: 42}, {cc: 43});
+f2(1, undefined, undefined, undefined);
+f2(1, undefined, undefined, undefined, undefined);
+f2(1, undefined, 43, undefined, {cc: 43});
diff --git a/js/src/jit-test/tests/arguments/defaults-destructuring-with-rest.js b/js/src/jit-test/tests/arguments/defaults-destructuring-with-rest.js
new file mode 100644
index 0000000000..26c35f6a43
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/defaults-destructuring-with-rest.js
@@ -0,0 +1,29 @@
+load(libdir + "asserts.js");
+load(libdir + "eqArrayHelper.js");
+
+function f1(a, bIs, [b]=[3], ...rest) {
+ assertEq(a, 1);
+ assertEq(bIs, b);
+ assertEqArray(rest, []);
+}
+assertEq(f1.length, 2);
+f1(1, 3);
+f1(1, 42, [42]);
+
+function f2([a]=[rest], ...rest) {
+ assertEq(a, undefined);
+}
+// TDZ
+assertThrowsInstanceOf(f2, ReferenceError);
+
+function f3([a]=[rest], ...rest) {
+ assertEq(a, 1);
+ assertEqArray(rest, [2, 3, 4]);
+}
+// TDZ
+assertThrowsInstanceOf(f3, ReferenceError);
+
+function f4([a]=rest, ...rest) {
+}
+// TDZ
+assertThrowsInstanceOf(f4, ReferenceError);
diff --git a/js/src/jit-test/tests/arguments/defaults-evaluation-order.js b/js/src/jit-test/tests/arguments/defaults-evaluation-order.js
new file mode 100644
index 0000000000..c4ddff7372
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/defaults-evaluation-order.js
@@ -0,0 +1,27 @@
+function f1(a, bIs, cIs, dIs, b=a, c=5, d=c) {
+ assertEq(a, 1);
+ assertEq(b, bIs);
+ assertEq(c, cIs);
+ assertEq(d, dIs);
+}
+f1(1, 1, 5, 5);
+f1(1, 42, 5, 5, 42);
+f1(1, 42, 43, 43, 42, 43);
+f1(1, 42, 43, 44, 42, 43, 44);
+function f2(a=[]) { return a; }
+assertEq(f2() !== f2(), true);
+function f3(a=function () {}) { return a; }
+assertEq(f3() !== f3(), true);
+function f4(a=Date) { return a; }
+assertEq(f4(), Date);
+Date = 0;
+assertEq(f4(), 0);
+function f5(x=FAIL()) {}; // don't throw
+var n = 0;
+function f6(a=n++) {}
+assertEq(n, 0);
+function f7([a, b], A=a, B=b) {
+ assertEq(A, a);
+ assertEq(B, b);
+}
+f7([0, 1]);
diff --git a/js/src/jit-test/tests/arguments/defaults-exceptions.js b/js/src/jit-test/tests/arguments/defaults-exceptions.js
new file mode 100644
index 0000000000..ab8d9c1b69
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/defaults-exceptions.js
@@ -0,0 +1,6 @@
+load(libdir + "asserts.js");
+
+function die() { throw "x"; }
+var ok = true;
+function f(a = die()) { ok = false; }
+assertThrowsValue(f, "x");
diff --git a/js/src/jit-test/tests/arguments/defaults-invalid-syntax.js b/js/src/jit-test/tests/arguments/defaults-invalid-syntax.js
new file mode 100644
index 0000000000..f1e1e508af
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/defaults-invalid-syntax.js
@@ -0,0 +1,30 @@
+load(libdir + "asserts.js");
+
+assertThrowsInstanceOf(function () {
+ eval("function f(...rest=23) {}");
+}, SyntaxError);
+assertThrowsInstanceOf(function () {
+ eval("function f(a=yield 24) {}");
+}, SyntaxError);
+assertThrowsInstanceOf(function () {
+ eval("function f(a={a : 19 + (yield 24).prop}) {}");
+}, SyntaxError);
+assertThrowsInstanceOf(function () {
+ eval("function f(a=1,a=1) {}");
+}, SyntaxError);
+assertThrowsInstanceOf(function () {
+ eval("function f(a,a=1) {}");
+}, SyntaxError);
+assertThrowsInstanceOf(function () {
+ eval("function f(a=1,a) {}");
+}, SyntaxError);
+assertThrowsInstanceOf(function () {
+ eval("function f(a,a,b=1) {}");
+}, SyntaxError);
+assertThrowsInstanceOf(function () {
+ eval("function f(a,b=1,a=1) {}");
+}, SyntaxError);
+assertThrowsInstanceOf(function () {
+ eval("function f(a=1,b=1,a=1) {}");
+}, SyntaxError);
+function silly_but_okay(a=(function* () { yield 97; })) {}
diff --git a/js/src/jit-test/tests/arguments/defaults-scoping.js b/js/src/jit-test/tests/arguments/defaults-scoping.js
new file mode 100644
index 0000000000..366439590e
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/defaults-scoping.js
@@ -0,0 +1,36 @@
+load(libdir + "asserts.js");
+
+var x = 'global';
+function f(a=x) { // global variable x
+ var x = 'local';
+ return a;
+}
+assertEq(f(), 'global');
+
+var i = 42;
+function g(f=function () { return ++i; }) { // closes on global variable i
+ var i = 0;
+ return f;
+}
+var gf = g();
+assertEq(gf(), 43);
+assertEq(gf(), 44);
+gf = g();
+assertEq(gf(), 45);
+
+function h(f=function (s) { return eval(s); }) { // closes on global scope
+ var x = 'hlocal';
+ return f;
+}
+var hf = h();
+assertEq(hf('x'), 'global');
+assertEq(hf('f'), hf);
+assertEq(hf('var x = 3; x'), 3);
+
+function j(expr, v=eval(expr)) {
+ return v;
+}
+assertEq(j("expr"), "expr");
+assertThrowsInstanceOf(() => j("v"), ReferenceError);
+assertEq(j("Array"), Array);
+assertEq(j("arguments").length, 1);
diff --git a/js/src/jit-test/tests/arguments/defaults-strict-mode.js b/js/src/jit-test/tests/arguments/defaults-strict-mode.js
new file mode 100644
index 0000000000..c4ba7bd63d
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/defaults-strict-mode.js
@@ -0,0 +1,41 @@
+load(libdir + "asserts.js");
+
+eval(`"use strict";
+function f1(f=(function () { return typeof this !== "object"; })) { return f; }
+assertEq(f1()(), true);
+`);
+
+function f2(f=(function () { "use strict"; return (function () { return typeof this !== "object"; }) })) { assertEq(typeof this, "object"); return f; }
+assertEq(f2()()(), true);
+
+eval(`"use strict";
+function f3(f=(function () { return (function () { return typeof this !== "object"; }) })) { return f; }
+assertEq(f3()()(), true);
+`);
+
+// These should be okay.
+function f4(f=(function () { with (Object) {} }), g=(function () { "use strict"; })) {}
+function f5(g=(function () { "use strict"; }), f=(function () { with (Object) {} })) {}
+
+assertThrowsInstanceOf(function () {
+ eval("'use strict'; function f(a=delete x) { }");
+}, SyntaxError);
+assertThrowsInstanceOf(function () {
+ Math.sin(4);
+ eval("'use strict'; function f(a='\\251') { }");
+}, SyntaxError);
+assertThrowsInstanceOf(function () {
+ eval("'use strict'; function f(a='\\251', b=delete x) { }");
+}, SyntaxError);
+assertThrowsInstanceOf(function () {
+ eval("'use strict'; function f(a=delete x, b='\\251') { }");
+}, SyntaxError);
+assertThrowsInstanceOf(function () {
+ eval("'use strict'; function f(a=(function () { '\\251'; })) { }");
+}, SyntaxError);
+assertThrowsInstanceOf(function () {
+ eval("'use strict'; function f(a=(function () { with (Object) {} })) { }");
+}, SyntaxError);
+assertThrowsInstanceOf(function () {
+ eval("'use strict'; function f(a=(function (b, b) {})) { }");
+}, SyntaxError);
diff --git a/js/src/jit-test/tests/arguments/defaults-with-arguments.js b/js/src/jit-test/tests/arguments/defaults-with-arguments.js
new file mode 100644
index 0000000000..9924c7c238
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/defaults-with-arguments.js
@@ -0,0 +1,10 @@
+function f(a=1, b=2, c=3) { return arguments; }
+var args = f();
+assertEq(args.length, 0);
+assertEq("0" in args, false);
+args = f(5, 6);
+assertEq(args.length, 2);
+assertEq(args[1], 6);
+args = f(9, 8, 7, 6, 5);
+assertEq(args.length, 5);
+assertEq(args[4], 5);
diff --git a/js/src/jit-test/tests/arguments/defaults-with-rest.js b/js/src/jit-test/tests/arguments/defaults-with-rest.js
new file mode 100644
index 0000000000..b0c7c8bcf9
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/defaults-with-rest.js
@@ -0,0 +1,23 @@
+load(libdir + "eqArrayHelper.js");
+load(libdir + "asserts.js");
+
+function f1(a, bIs, b=3, ...rest) {
+ assertEq(a, 1);
+ assertEq(bIs, b);
+ assertEqArray(rest, []);
+}
+assertEq(f1.length, 2);
+f1(1, 3);
+f1(1, 42, 42);
+function f2(a=rest, ...rest) {
+}
+// TDZ
+assertThrowsInstanceOf(f2, ReferenceError);
+function f3(a=rest, ...rest) {
+}
+assertThrowsInstanceOf(f3, ReferenceError);
+function f4(a=42, ...f) {
+ assertEq(typeof f, "function");
+ function f() {}
+}
+f4()
diff --git a/js/src/jit-test/tests/arguments/destructuring-after-defaults.js b/js/src/jit-test/tests/arguments/destructuring-after-defaults.js
new file mode 100644
index 0000000000..66f24a8342
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/destructuring-after-defaults.js
@@ -0,0 +1,14 @@
+load(libdir + "asserts.js");
+
+function f1(a, bIs, cIs, dIs, b=1, [c], {d}) {
+ assertEq(a, 1);
+ assertEq(b, bIs);
+ assertEq(c, cIs);
+ assertEq(d, dIs);
+}
+assertEq(f1.length, 4);
+f1(1, 1, 42, 43, undefined, [42], {d: 43});
+f1(1, 42, 43, 44, 42, [43], {d: 44});
+assertThrowsInstanceOf(function () {
+ f1(1, 1, 1, 1);
+}, TypeError);
diff --git a/js/src/jit-test/tests/arguments/destructuring-default-value-scope.js b/js/src/jit-test/tests/arguments/destructuring-default-value-scope.js
new file mode 100644
index 0000000000..c4b16ea4df
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/destructuring-default-value-scope.js
@@ -0,0 +1,10 @@
+var a = 10;
+function f1(a,
+ [b=(assertEq(a, 1), a=2, 42)],
+ {c:c=(assertEq(a, 2), a=3, 43)}) {
+ assertEq(a, 3);
+ assertEq(b, 42);
+ assertEq(c, 43);
+}
+f1(1, [], {});
+assertEq(a, 10);
diff --git a/js/src/jit-test/tests/arguments/destructuring-exprbody.js b/js/src/jit-test/tests/arguments/destructuring-exprbody.js
new file mode 100644
index 0000000000..5f3f04ecb7
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/destructuring-exprbody.js
@@ -0,0 +1,8 @@
+// See bug 763313
+load(libdir + "iteration.js");
+function f([a]) { return a; }
+var i = 0;
+var o = {[Symbol.iterator]: function () { i++; return {
+ next: function () { i++; return {value: 42, done: false}; }}}};
+assertEq(f(o), 42);
+assertEq(i, 2);
diff --git a/js/src/jit-test/tests/arguments/destructuring-with-rest.js b/js/src/jit-test/tests/arguments/destructuring-with-rest.js
new file mode 100644
index 0000000000..81e69ce54d
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/destructuring-with-rest.js
@@ -0,0 +1,21 @@
+load(libdir + "eqArrayHelper.js");
+
+function f1(a, bIs, [b], ...rest) {
+ assertEq(a, 1);
+ assertEq(bIs, b);
+ assertEqArray(rest, []);
+}
+assertEq(f1.length, 3);
+f1(1, 3, [3]);
+f1(1, 42, [42]);
+
+function f2([a], ...rest) {
+ assertEq(a, undefined);
+}
+f2([]);
+
+function f3([a], ...rest) {
+ assertEq(a, 1);
+ assertEqArray(rest, [2, 3, 4]);
+}
+f3([1], 2, 3, 4);
diff --git a/js/src/jit-test/tests/arguments/dynamicBindings.js b/js/src/jit-test/tests/arguments/dynamicBindings.js
new file mode 100644
index 0000000000..326038e12b
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/dynamicBindings.js
@@ -0,0 +1,32 @@
+
+function testEval(x, y) {
+ x = 5;
+ eval("arguments[0] += 10");
+ assertEq(x, 15);
+}
+for (var i = 0; i < 5; i++)
+ testEval(3);
+
+function testEvalWithArguments(x, y) {
+ eval("arguments[0] += 10");
+ assertEq(arguments[y], 13);
+}
+for (var i = 0; i < 5; i++)
+ testEvalWithArguments(3, 0);
+
+function testNestedEval(x, y) {
+ x = 5;
+ eval("eval('arguments[0] += 10')");
+ assertEq(x, 15);
+}
+for (var i = 0; i < 5; i++)
+ testNestedEval(3);
+
+function testWith(x, y) {
+ with ({}) {
+ arguments[0] += 10;
+ assertEq(x, 13);
+ }
+}
+for (var i = 0; i < 5; i++)
+ testWith(3);
diff --git a/js/src/jit-test/tests/arguments/function_dot_caller_restrictions.js b/js/src/jit-test/tests/arguments/function_dot_caller_restrictions.js
new file mode 100644
index 0000000000..414f348eb6
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/function_dot_caller_restrictions.js
@@ -0,0 +1,78 @@
+
+function g() { }
+function strict() {
+ "use strict";
+}
+
+let bound = g.bind();
+let arrow = x => 0;
+
+async function fn_async() { }
+function * fn_generator() { }
+
+let o = {
+ mtd() {},
+ get x() {},
+ set x(v) {},
+};
+
+class Base { }
+class Derived extends Base { }
+
+function asm_mod() {
+ "use asm";
+ function mtd() {}
+ return { mtd: mtd }
+}
+
+let asm_fun = (new asm_mod).mtd;
+
+let builtin_selfhost = [].sort;
+let builtin_native = Math.sin;
+
+let dot_caller = Object.getOwnPropertyDescriptor(Function.__proto__,
+ "caller").get;
+
+// Returns true if fn.caller is allowed
+function check(fn) {
+ try {
+ (function() {
+ fn.caller;
+ })();
+ }
+ catch (e) {
+ assertEq(e instanceof TypeError, true);
+ return false;
+ }
+ return true;
+}
+
+// Normal sloppy functions are allowed, even if they also are intended as
+// asm.js.
+assertEq(check(g), true);
+assertEq(check(asm_mod), true);
+assertEq(check(asm_fun), true);
+
+// Most others are not
+assertEq(check(strict), false);
+assertEq(check(bound), false);
+assertEq(check(arrow), false);
+assertEq(check(fn_async), false);
+assertEq(check(fn_generator), false);
+assertEq(check(o.mtd), false)
+assertEq(check(Object.getOwnPropertyDescriptor(o, "x").get), false)
+assertEq(check(Object.getOwnPropertyDescriptor(o, "x").set), false)
+assertEq(check(Base), false);
+assertEq(check(Derived), false);
+assertEq(check(builtin_selfhost), false);
+assertEq(check(builtin_native), false);
+assertEq(check(dot_caller), false);
+
+// Have a native invoke .caller on our behalf.
+function foo() {
+ function inner() {
+ return callFunctionFromNativeFrame(dot_caller.bind(inner))
+ }
+ return inner();
+}
+assertEq(foo, foo());
diff --git a/js/src/jit-test/tests/arguments/inline-rest-array-creation.js b/js/src/jit-test/tests/arguments/inline-rest-array-creation.js
new file mode 100644
index 0000000000..34998d4cb4
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/inline-rest-array-creation.js
@@ -0,0 +1,83 @@
+function zero(...rest)
+{
+ assertEq(rest.length, 0, "zero rest wrong length");
+}
+
+function tzero()
+{
+ zero();
+}
+
+tzero(); tzero(); tzero();
+
+function one(...rest)
+{
+ assertEq(rest.length, 1, "one rest wrong length");
+}
+
+function tone()
+{
+ one(0);
+}
+
+tone(); tone(); tone();
+
+function two(...rest)
+{
+ assertEq(rest.length, 2, "two rest wrong length");
+}
+
+function ttwo()
+{
+ two(0, 1);
+}
+
+ttwo(); ttwo(); ttwo();
+
+function zeroWithLeading0(x, ...rest)
+{
+ assertEq(rest.length, 0, "zeroWithLeading0 rest wrong length");
+}
+
+function tzeroWithLeading0()
+{
+ zeroWithLeading0();
+}
+
+tzeroWithLeading0(); tzeroWithLeading0(); tzeroWithLeading0();
+
+function zeroWithLeading1(x, ...rest)
+{
+ assertEq(rest.length, 0, "zeroWithLeading1 rest wrong length");
+}
+
+function tzeroWithLeading1()
+{
+ zeroWithLeading1(0);
+}
+
+tzeroWithLeading1(); tzeroWithLeading1(); tzeroWithLeading1();
+
+function oneWithLeading(x, ...rest)
+{
+ assertEq(rest.length, 1, "oneWithLeading rest wrong length");
+}
+
+function toneWithLeading()
+{
+ oneWithLeading(0, 1);
+}
+
+toneWithLeading(); toneWithLeading(); toneWithLeading();
+
+function twoWithLeading(x, ...rest)
+{
+ assertEq(rest.length, 2, "twoWithLeading rest wrong length");
+}
+
+function ttwoWithLeading()
+{
+ twoWithLeading(0, 1, 2);
+}
+
+ttwoWithLeading(); ttwoWithLeading(); ttwoWithLeading();
diff --git a/js/src/jit-test/tests/arguments/inline-transpile.js b/js/src/jit-test/tests/arguments/inline-transpile.js
new file mode 100644
index 0000000000..0720256593
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/inline-transpile.js
@@ -0,0 +1,17 @@
+function foo(i) {
+ return i;
+}
+
+function bar(n) {
+ return foo.apply({}, arguments);
+}
+
+function baz(a, n) {
+ return bar(n);
+}
+
+var sum = 0;
+for (var i = 0; i < 10000; i++) {
+ sum += baz(0, 1);
+}
+assertEq(sum, 10000);
diff --git a/js/src/jit-test/tests/arguments/iterator-set-and-redefine.js b/js/src/jit-test/tests/arguments/iterator-set-and-redefine.js
new file mode 100644
index 0000000000..bcf182790f
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/iterator-set-and-redefine.js
@@ -0,0 +1,33 @@
+function mapped() {
+ var Iterator = {};
+
+ // First overwrite the iterator.
+ arguments[Symbol.iterator] = Iterator;
+
+ // And then redefine a property attribute.
+ Object.defineProperty(arguments, Symbol.iterator, {
+ writable: false
+ });
+
+ // Make sure redefining an attribute doesn't reset the iterator value.
+ assertEq(arguments[Symbol.iterator], Iterator);
+}
+mapped();
+
+function unmapped() {
+ "use strict";
+
+ var Iterator = {};
+
+ // First overwrite the iterator.
+ arguments[Symbol.iterator] = Iterator;
+
+ // And then redefine a property attribute.
+ Object.defineProperty(arguments, Symbol.iterator, {
+ writable: false
+ });
+
+ // Make sure redefining an attribute doesn't reset the iterator value.
+ assertEq(arguments[Symbol.iterator], Iterator);
+}
+unmapped();
diff --git a/js/src/jit-test/tests/arguments/mapped-define.js b/js/src/jit-test/tests/arguments/mapped-define.js
new file mode 100644
index 0000000000..820485608a
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/mapped-define.js
@@ -0,0 +1,20 @@
+function f(a) {
+ assertEq(arguments[0], 1);
+
+ Object.defineProperty(arguments, 0, {value: 23, writable: true, configurable: true});
+ assertEq(arguments[0], 23);
+ assertEq(a, 23);
+
+ a = 12;
+ assertEq(a, 12);
+ assertEq(arguments[0], 12);
+
+ Object.defineProperty(arguments, 0, {value: 9, writable: false, configurable: false});
+ assertEq(arguments[0], 9);
+ assertEq(a, 9);
+
+ a = 4;
+ assertEq(arguments[0], 9);
+ assertEq(a, 4);
+}
+f(1);
diff --git a/js/src/jit-test/tests/arguments/mapped-freeze.js b/js/src/jit-test/tests/arguments/mapped-freeze.js
new file mode 100644
index 0000000000..e60cb24233
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/mapped-freeze.js
@@ -0,0 +1,8 @@
+function f(a) {
+ Object.freeze(arguments);
+ a = 1;
+ return arguments[0];
+}
+
+assertEq(f(10), 10);
+assertEq(f("hello"), "hello");
diff --git a/js/src/jit-test/tests/arguments/mapped-unmapped-args.js b/js/src/jit-test/tests/arguments/mapped-unmapped-args.js
new file mode 100644
index 0000000000..d1b063be3d
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/mapped-unmapped-args.js
@@ -0,0 +1,61 @@
+// An unmapped arguments object is created for strict functions or functions
+// with default/rest/destructuring args.
+
+load(libdir + "asserts.js");
+
+function testDefaults(a, b=3) {
+ a = 3;
+ b = 4;
+ assertEq(arguments.length, 1);
+ assertEq(arguments[0], 1);
+ assertEq(arguments[1], undefined);
+ arguments[0] = 5;
+ assertEq(a, 3);
+ assertThrowsInstanceOf(() => arguments.callee, TypeError);
+}
+testDefaults(1);
+
+function testRest(a, ...rest) {
+ a = 3;
+ assertEq(arguments.length, 3);
+ assertEq(arguments[0], 1);
+ assertEq(arguments[1], 2);
+ arguments[0] = 5;
+ assertEq(a, 3);
+ arguments[1] = 6;
+ assertEq(arguments[1], 6);
+ assertEq(rest.toString(), "2,3");
+ assertThrowsInstanceOf(() => arguments.callee, TypeError);
+}
+testRest(1, 2, 3);
+
+function testDestructuring(a, {foo, bar}, b) {
+ a = 3;
+ bar = 4;
+ b = 1;
+ assertEq(arguments.length, 3);
+ assertEq(arguments[0], 1);
+ assertEq(arguments[1].bar, 2);
+ assertEq(arguments[2], 9);
+ assertThrowsInstanceOf(() => arguments.callee, TypeError);
+}
+testDestructuring(1, {foo: 1, bar: 2}, 9);
+
+function testStrict(a) {
+ "use strict";
+ a = 3;
+ assertEq(arguments[0], 1);
+ arguments[0] = 8;
+ assertEq(a, 3);
+ assertThrowsInstanceOf(() => arguments.callee, TypeError);
+}
+testStrict(1, 2);
+
+function testMapped(a) {
+ a = 3;
+ assertEq(arguments[0], 3);
+ arguments[0] = 5;
+ assertEq(a, 5);
+ assertEq(arguments.callee, testMapped);
+}
+testMapped(1);
diff --git a/js/src/jit-test/tests/arguments/nonstrict-args.js b/js/src/jit-test/tests/arguments/nonstrict-args.js
new file mode 100644
index 0000000000..750bcc1e78
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/nonstrict-args.js
@@ -0,0 +1,24 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+load(libdir + 'array-compare.js');
+
+var obj = {};
+
+function args(a) { return arguments; }
+
+var a1, a2, a3, a4;
+
+for (var i = 0; i < 5; i++)
+{
+ a1 = args();
+ a2 = args(1);
+ a3 = args(1, obj);
+ a4 = args("foopy");
+}
+
+assertEq(arraysEqual(a1, []), true);
+assertEq(arraysEqual(a2, [1]), true);
+assertEq(arraysEqual(a3, [1, obj]), true);
+assertEq(arraysEqual(a4, ["foopy"]), true);
diff --git a/js/src/jit-test/tests/arguments/nonstrict-assign-element-get-parameter.js b/js/src/jit-test/tests/arguments/nonstrict-assign-element-get-parameter.js
new file mode 100644
index 0000000000..c55588daa4
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/nonstrict-assign-element-get-parameter.js
@@ -0,0 +1,13 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+function assignElementGetParameter(a)
+{
+ arguments[0] = 17;
+ return a;
+}
+
+for (var i = 0; i < 5; i++)
+ assertEq(assignElementGetParameter(42), 17);
diff --git a/js/src/jit-test/tests/arguments/nonstrict-assign-parameter-get-element.js b/js/src/jit-test/tests/arguments/nonstrict-assign-parameter-get-element.js
new file mode 100644
index 0000000000..747abbad31
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/nonstrict-assign-parameter-get-element.js
@@ -0,0 +1,13 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+function assignParameterGetElement(a)
+{
+ a = 17;
+ return arguments[0];
+}
+
+for (var i = 0; i < 5; i++)
+ assertEq(assignParameterGetElement(42), 17);
diff --git a/js/src/jit-test/tests/arguments/nonstrict-assign.js b/js/src/jit-test/tests/arguments/nonstrict-assign.js
new file mode 100644
index 0000000000..8dd75e7209
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/nonstrict-assign.js
@@ -0,0 +1,17 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+load(libdir + 'array-compare.js');
+
+function assign(a)
+{
+ a = 17;
+ return arguments;
+}
+
+var a1;
+for (var i = 0; i < 5; i++)
+ a1 = assign(1);
+
+assertEq(arraysEqual(a1, [17]), true);
diff --git a/js/src/jit-test/tests/arguments/nonstrict-later-assign.js b/js/src/jit-test/tests/arguments/nonstrict-later-assign.js
new file mode 100644
index 0000000000..fbf72abc4c
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/nonstrict-later-assign.js
@@ -0,0 +1,18 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+load(libdir + 'array-compare.js');
+
+function getLaterAssign(a)
+{
+ var o = arguments;
+ a = 17;
+ return o;
+}
+
+var a1, a2;
+for (var i = 0; i < 5; i++)
+ a1 = getLaterAssign(1);
+
+assertEq(arraysEqual(a1, [17]), true);
diff --git a/js/src/jit-test/tests/arguments/nonstrict-noargs.js b/js/src/jit-test/tests/arguments/nonstrict-noargs.js
new file mode 100644
index 0000000000..ef1bca7dee
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/nonstrict-noargs.js
@@ -0,0 +1,21 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+load(libdir + 'array-compare.js');
+
+var obj = {};
+
+function noargs() { return arguments; }
+
+var a1, a2, a3;
+for (var i = 0; i < 5; i++)
+{
+ a1 = noargs();
+ a2 = noargs(1);
+ a3 = noargs(2, obj, 8);
+}
+
+assertEq(arraysEqual(a1, []), true);
+assertEq(arraysEqual(a2, [1]), true);
+assertEq(arraysEqual(a3, [2, obj, 8]), true);
diff --git a/js/src/jit-test/tests/arguments/rest-alias-function.js b/js/src/jit-test/tests/arguments/rest-alias-function.js
new file mode 100644
index 0000000000..1dda665210
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/rest-alias-function.js
@@ -0,0 +1,10 @@
+function no_defaults(a, ...rest) {
+ return rest;
+ function rest() { return a; }
+}
+assertEq(typeof no_defaults(), "function");
+function with_defaults(a=42, ...rest) {
+ return rest;
+ function rest() { return a; }
+}
+assertEq(typeof with_defaults(), "function");
diff --git a/js/src/jit-test/tests/arguments/rest-arguments-as-parameters.js b/js/src/jit-test/tests/arguments/rest-arguments-as-parameters.js
new file mode 100644
index 0000000000..120b0ce1c0
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/rest-arguments-as-parameters.js
@@ -0,0 +1,9 @@
+function f1(...arguments) {
+ assertEq("1,2,3", arguments.toString());
+}
+f1(1, 2, 3);
+function f2(arguments, ...rest) {
+ assertEq(arguments, 42);
+ assertEq("1,2,3", rest.toString());
+}
+f2(42, 1, 2, 3); \ No newline at end of file
diff --git a/js/src/jit-test/tests/arguments/rest-basic.js b/js/src/jit-test/tests/arguments/rest-basic.js
new file mode 100644
index 0000000000..cb050d13b3
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/rest-basic.js
@@ -0,0 +1,15 @@
+function check(expected, ...rest) {
+ assertEq(expected.toString(), rest.toString());
+}
+
+assertEq(check.length, 1);
+check([]);
+check(['a', 'b'], 'a', 'b');
+check(['a', 'b', 'c', 'd'], 'a', 'b', 'c', 'd');
+check.apply(null, [['a', 'b'], 'a', 'b'])
+check.call(null, ['a', 'b'], 'a', 'b')
+
+var g = newGlobal();
+g.eval("function f(...rest) { return rest; }");
+var a = g.f(1, 2, 3);
+assertEq(a instanceof g.Array, true); \ No newline at end of file
diff --git a/js/src/jit-test/tests/arguments/rest-bug763954.js b/js/src/jit-test/tests/arguments/rest-bug763954.js
new file mode 100644
index 0000000000..3884abf8e2
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/rest-bug763954.js
@@ -0,0 +1,5 @@
+for (i in ['']) {}
+function f(...patterns) {
+ patterns[i];
+};
+f('');
diff --git a/js/src/jit-test/tests/arguments/rest-debugger.js b/js/src/jit-test/tests/arguments/rest-debugger.js
new file mode 100644
index 0000000000..be9016a07c
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/rest-debugger.js
@@ -0,0 +1,17 @@
+var g = newGlobal({newCompartment: true});
+g.eval("function f(...x) {}");
+var dbg = new Debugger;
+var gw = dbg.addDebuggee(g);
+var fw = gw.getOwnPropertyDescriptor("f").value;
+assertEq(fw.parameterNames.toString(), "x");
+
+var g = newGlobal({newCompartment: true});
+g.eval("function f(...rest) { debugger; }");
+var dbg = Debugger(g);
+dbg.onDebuggerStatement = function (frame) {
+ frame.eval("args = arguments");
+};
+g.f(9, 8, 7);
+
+assertEq(g.args.length, 3);
+assertEq(g.args[2], 7);
diff --git a/js/src/jit-test/tests/arguments/rest-disallow-arguments-strict.js b/js/src/jit-test/tests/arguments/rest-disallow-arguments-strict.js
new file mode 100644
index 0000000000..7f54e5ef7a
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/rest-disallow-arguments-strict.js
@@ -0,0 +1,8 @@
+"use strict";
+load(libdir + "asserts.js");
+assertThrowsInstanceOf(function () {
+ eval("(function (...arguments) {})");
+}, SyntaxError);
+assertThrowsInstanceOf(function () {
+ eval("(function (...eval) {})");
+}, SyntaxError);
diff --git a/js/src/jit-test/tests/arguments/rest-in-Function.js b/js/src/jit-test/tests/arguments/rest-in-Function.js
new file mode 100644
index 0000000000..e2966be691
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/rest-in-Function.js
@@ -0,0 +1,3 @@
+h = Function("a", "b", "c", "...rest", "return rest.toString();");
+assertEq(h.length, 3);
+assertEq(h(1, 2, 3, 4, 5), "4,5");
diff --git a/js/src/jit-test/tests/arguments/rest-invalid-syntax.js b/js/src/jit-test/tests/arguments/rest-invalid-syntax.js
new file mode 100644
index 0000000000..f91d93ea62
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/rest-invalid-syntax.js
@@ -0,0 +1,12 @@
+load(libdir + "asserts.js");
+var ieval = eval;
+var offenders = [["..."], ["...rest"," x"], ["...rest", "[x]"],
+ ["...rest", "...rest2"]];
+for (var arglist of offenders) {
+ assertThrowsInstanceOf(function () {
+ ieval("function x(" + arglist.join(", ") + ") {}");
+ }, SyntaxError);
+ assertThrowsInstanceOf(function () {
+ Function.apply(null, arglist.concat("return 0;"));
+ }, SyntaxError);
+} \ No newline at end of file
diff --git a/js/src/jit-test/tests/arguments/rest-nested-arguments.js b/js/src/jit-test/tests/arguments/rest-nested-arguments.js
new file mode 100644
index 0000000000..18f5ca56df
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/rest-nested-arguments.js
@@ -0,0 +1,7 @@
+function f(...rest) {
+ function nested() {
+ return arguments.length;
+ }
+ return nested;
+}
+assertEq(f()(1, 2, 3), 3);
diff --git a/js/src/jit-test/tests/arguments/rest-nested.js b/js/src/jit-test/tests/arguments/rest-nested.js
new file mode 100644
index 0000000000..0ad82e5475
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/rest-nested.js
@@ -0,0 +1,7 @@
+function f(...rest) {
+ function nested () {
+ return rest;
+ }
+ return nested;
+}
+assertEq(f(1, 2, 3)().toString(), [1, 2, 3].toString()); \ No newline at end of file
diff --git a/js/src/jit-test/tests/arguments/rest-underflow.js b/js/src/jit-test/tests/arguments/rest-underflow.js
new file mode 100644
index 0000000000..bb9b39c50b
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/rest-underflow.js
@@ -0,0 +1,9 @@
+function f(a, b, c, ...rest) {
+ assertEq(a, 1);
+ assertEq(b, undefined);
+ assertEq(c, undefined);
+ assertEq(Array.isArray(rest), true);
+ assertEq(rest.length, 0);
+ assertEq(Object.getPrototypeOf(rest), Array.prototype);
+}
+f(1);
diff --git a/js/src/jit-test/tests/arguments/rest-with-arguments.js b/js/src/jit-test/tests/arguments/rest-with-arguments.js
new file mode 100644
index 0000000000..7dfc63c739
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/rest-with-arguments.js
@@ -0,0 +1,40 @@
+// 'arguments' is allowed with rest parameters.
+
+var args;
+
+function restWithArgs(a, b, ...rest) {
+ return arguments;
+}
+
+args = restWithArgs(1, 3, 6, 9);
+assertEq(args.length, 4);
+assertEq(JSON.stringify(args), '{"0":1,"1":3,"2":6,"3":9}');
+
+args = restWithArgs();
+assertEq(args.length, 0);
+
+args = restWithArgs(4, 5);
+assertEq(args.length, 2);
+assertEq(JSON.stringify(args), '{"0":4,"1":5}');
+
+function restWithArgsEval(a, b, ...rest) {
+ return eval("arguments");
+}
+
+args = restWithArgsEval(1, 3, 6, 9);
+assertEq(args.length, 4);
+assertEq(JSON.stringify(args), '{"0":1,"1":3,"2":6,"3":9}');
+
+function g(...rest) {
+ h();
+}
+function h() {
+ g.arguments;
+}
+g();
+
+// eval() is evil, but you can still use it with rest parameters!
+function still_use_eval(...rest) {
+ eval("x = 4");
+}
+still_use_eval();
diff --git a/js/src/jit-test/tests/arguments/strict-args-flushstack.js b/js/src/jit-test/tests/arguments/strict-args-flushstack.js
new file mode 100644
index 0000000000..257018ba3f
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/strict-args-flushstack.js
@@ -0,0 +1,27 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+var args;
+
+function test()
+{
+ "use strict";
+ eval("args = arguments;");
+ var a = [];
+ for (var i = 0; i < 9; i++)
+ a.push(arguments);
+ return a;
+}
+
+var a = test();
+
+assertEq(Array.isArray(a), true);
+assertEq(a.length, 9);
+
+var count = 0;
+a.forEach(function(v, i) { count++; assertEq(v, args); });
+assertEq(count, 9);
+
+assertEq(Object.prototype.toString.call(args), "[object Arguments]");
+assertEq(args.length, 0);
diff --git a/js/src/jit-test/tests/arguments/strict-args-generator-flushstack.js b/js/src/jit-test/tests/arguments/strict-args-generator-flushstack.js
new file mode 100644
index 0000000000..ecef5dde74
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/strict-args-generator-flushstack.js
@@ -0,0 +1,27 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+var args;
+
+function* upToTen()
+{
+ "use strict";
+ eval("args = arguments;");
+ for (var i = 0; i < 9; i++)
+ yield i;
+}
+
+var gen = upToTen();
+
+var i = 0;
+for (var v of gen)
+{
+ assertEq(v, i);
+ i++;
+}
+
+assertEq(i, 9);
+
+assertEq(Object.prototype.toString.call(args), "[object Arguments]");
+assertEq(args.length, 0);
diff --git a/js/src/jit-test/tests/arguments/strict-args.js b/js/src/jit-test/tests/arguments/strict-args.js
new file mode 100644
index 0000000000..c6d68b2b1f
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/strict-args.js
@@ -0,0 +1,25 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+load(libdir + 'array-compare.js');
+
+var obj = {};
+
+function strictArgs(a)
+{
+ "use strict";
+ return arguments;
+}
+
+var a1, a2, a3;
+for (var i = 0; i < 9; i++)
+{
+ a1 = strictArgs();
+ a2 = strictArgs(1);
+ a3 = strictArgs(1, obj);
+}
+
+assertEq(arraysEqual(a1, []), true);
+assertEq(arraysEqual(a2, [1]), true);
+assertEq(arraysEqual(a3, [1, obj]), true);
diff --git a/js/src/jit-test/tests/arguments/strict-assign-after.js b/js/src/jit-test/tests/arguments/strict-assign-after.js
new file mode 100644
index 0000000000..b295321c3b
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/strict-assign-after.js
@@ -0,0 +1,28 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+load(libdir + 'array-compare.js');
+
+var obj = {};
+
+var upper;
+function strictAssignAfter(a)
+{
+ "use strict";
+ upper = arguments;
+ a = 42;
+ return upper;
+}
+
+var a1, a2, a3;
+for (var i = 0; i < 5; i++)
+{
+ a1 = strictAssignAfter();
+ a2 = strictAssignAfter(17);
+ a3 = strictAssignAfter(obj);
+}
+
+assertEq(arraysEqual(a1, []), true);
+assertEq(arraysEqual(a2, [17]), true);
+assertEq(arraysEqual(a3, [obj]), true);
diff --git a/js/src/jit-test/tests/arguments/strict-assign-arguments-element.js b/js/src/jit-test/tests/arguments/strict-assign-arguments-element.js
new file mode 100644
index 0000000000..d2f4f1e5b8
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/strict-assign-arguments-element.js
@@ -0,0 +1,21 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+load(libdir + 'array-compare.js');
+
+var obj = {};
+
+function strictAssignArgumentsElement(a)
+{
+ "use strict";
+ arguments[0] = 42;
+ return a;
+}
+
+for (var i = 0; i < 5; i++)
+{
+ assertEq(strictAssignArgumentsElement(), undefined);
+ assertEq(strictAssignArgumentsElement(obj), obj);
+ assertEq(strictAssignArgumentsElement(17), 17);
+}
diff --git a/js/src/jit-test/tests/arguments/strict-assign-outer-param-psych.js b/js/src/jit-test/tests/arguments/strict-assign-outer-param-psych.js
new file mode 100644
index 0000000000..6b8fb680eb
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/strict-assign-outer-param-psych.js
@@ -0,0 +1,27 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+load(libdir + 'array-compare.js');
+
+var obj = {};
+
+function strictAssignOuterParamPSYCH(p)
+{
+ "use strict";
+ function inner(p) { p = 17; }
+ inner();
+ return arguments;
+}
+
+var a1, a2, a3;
+for (var i = 0; i < 5; i++)
+{
+ a1 = strictAssignOuterParamPSYCH();
+ a2 = strictAssignOuterParamPSYCH(17);
+ a3 = strictAssignOuterParamPSYCH(obj);
+}
+
+assertEq(arraysEqual(a1, []), true);
+assertEq(arraysEqual(a2, [17]), true);
+assertEq(arraysEqual(a3, [obj]), true);
diff --git a/js/src/jit-test/tests/arguments/strict-assign-outer-param.js b/js/src/jit-test/tests/arguments/strict-assign-outer-param.js
new file mode 100644
index 0000000000..f6e4f47675
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/strict-assign-outer-param.js
@@ -0,0 +1,27 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+load(libdir + 'array-compare.js');
+
+var obj = {};
+
+function strictAssignOuterParam(p)
+{
+ "use strict";
+ function inner() { p = 17; }
+ inner();
+ return arguments;
+}
+
+var a1, a2, a3;
+for (var i = 0; i < 5; i++)
+{
+ a1 = strictAssignOuterParam();
+ a2 = strictAssignOuterParam(42);
+ a3 = strictAssignOuterParam(obj);
+}
+
+assertEq(arraysEqual(a1, []), true);
+assertEq(arraysEqual(a2, [42]), true);
+assertEq(arraysEqual(a3, [obj]), true);
diff --git a/js/src/jit-test/tests/arguments/strict-assign-parameter-get-element.js b/js/src/jit-test/tests/arguments/strict-assign-parameter-get-element.js
new file mode 100644
index 0000000000..ca283fb9b6
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/strict-assign-parameter-get-element.js
@@ -0,0 +1,14 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+function strictAssignParameterGetElement(a)
+{
+ "use strict";
+ a = 17;
+ return arguments[0];
+}
+
+for (var i = 0; i < 5; i++)
+ assertEq(strictAssignParameterGetElement(42), 42);
diff --git a/js/src/jit-test/tests/arguments/strict-assign.js b/js/src/jit-test/tests/arguments/strict-assign.js
new file mode 100644
index 0000000000..6666dec9bb
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/strict-assign.js
@@ -0,0 +1,26 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+load(libdir + 'array-compare.js');
+
+var obj = {};
+
+function strictAssign(a)
+{
+ "use strict";
+ a = 17;
+ return arguments;
+}
+
+var a1, a2, a3;
+for (var i = 0; i < 5; i++)
+{
+ a1 = strictAssign();
+ a2 = strictAssign(1);
+ a3 = strictAssign(1, obj);
+}
+
+assertEq(arraysEqual(a1, []), true);
+assertEq(arraysEqual(a2, [1]), true);
+assertEq(arraysEqual(a3, [1, obj]), true);
diff --git a/js/src/jit-test/tests/arguments/strict-eval-mutation.js b/js/src/jit-test/tests/arguments/strict-eval-mutation.js
new file mode 100644
index 0000000000..d33a05c3a0
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/strict-eval-mutation.js
@@ -0,0 +1,24 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+load(libdir + 'array-compare.js');
+
+var obj = {};
+
+function strictEvalMutation(code)
+{
+ "use strict";
+ return eval(code);
+}
+
+var a1, a2;
+for (var i = 0; i < 5; i++)
+{
+ a1 = strictEvalMutation("code = 17; arguments");
+ a2 = strictEvalMutation("arguments[0] = 17; arguments");
+ assertEq(strictEvalMutation("arguments[0] = 17; code"), "arguments[0] = 17; code");
+}
+
+assertEq(arraysEqual(a1, ["code = 17; arguments"]), true);
+assertEq(arraysEqual(a2, [17]), true);
diff --git a/js/src/jit-test/tests/arguments/strict-eval.js b/js/src/jit-test/tests/arguments/strict-eval.js
new file mode 100644
index 0000000000..22ffb7fd85
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/strict-eval.js
@@ -0,0 +1,30 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+load(libdir + 'array-compare.js');
+
+function strictEval(code, p)
+{
+ "use strict";
+ eval(code);
+ return arguments;
+}
+
+var a1, a2, a3, a4, a5, a6;
+for (var i = 0; i < 5; i++)
+{
+ a1 = strictEval("1", 2);
+ a2 = strictEval("arguments");
+ a3 = strictEval("p = 2");
+ a4 = strictEval("p = 2", 17);
+ a5 = strictEval("arguments[0] = 17");
+ a6 = strictEval("arguments[0] = 17", 42);
+}
+
+assertEq(arraysEqual(a1, ["1", 2]), true);
+assertEq(arraysEqual(a2, ["arguments"]), true);
+assertEq(arraysEqual(a3, ["p = 2"]), true);
+assertEq(arraysEqual(a4, ["p = 2", 17]), true);
+assertEq(arraysEqual(a5, [17]), true);
+assertEq(arraysEqual(a6, [17, 42]), true);
diff --git a/js/src/jit-test/tests/arguments/strict-maybe-assign-outer.js b/js/src/jit-test/tests/arguments/strict-maybe-assign-outer.js
new file mode 100644
index 0000000000..63f9f69248
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/strict-maybe-assign-outer.js
@@ -0,0 +1,26 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+load(libdir + 'array-compare.js');
+
+var obj = {};
+
+function strictMaybeAssignOuterParam(p)
+{
+ "use strict";
+ function inner() { p = 17; }
+ return arguments;
+}
+
+var a1, a2, a3;
+for (var i = 0; i < 5; i++)
+{
+ a1 = strictMaybeAssignOuterParam();
+ a2 = strictMaybeAssignOuterParam(17);
+ a3 = strictMaybeAssignOuterParam(obj);
+}
+
+assertEq(arraysEqual(a1, []), true);
+assertEq(arraysEqual(a2, [17]), true);
+assertEq(arraysEqual(a3, [obj]), true);
diff --git a/js/src/jit-test/tests/arguments/strict-maybe-nested-eval.js b/js/src/jit-test/tests/arguments/strict-maybe-nested-eval.js
new file mode 100644
index 0000000000..a1fe88fd35
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/strict-maybe-nested-eval.js
@@ -0,0 +1,26 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+load(libdir + 'array-compare.js');
+
+function strictMaybeNestedEval(code, p)
+{
+ "use strict";
+ function inner() { eval(code); }
+ return arguments;
+}
+
+var a1, a2, a3, a4;
+for (var i = 0; i < 5; i++)
+{
+ a1 = strictMaybeNestedEval("1", 2);
+ a2 = strictMaybeNestedEval("arguments");
+ a3 = strictMaybeNestedEval("p = 2");
+ a4 = strictMaybeNestedEval("p = 2", 17);
+}
+
+assertEq(arraysEqual(a1, ["1", 2]), true);
+assertEq(arraysEqual(a2, ["arguments"]), true);
+assertEq(arraysEqual(a3, ["p = 2"]), true);
+assertEq(arraysEqual(a4, ["p = 2", 17]), true);
diff --git a/js/src/jit-test/tests/arguments/strict-nested-assign-shadow-function-call.js b/js/src/jit-test/tests/arguments/strict-nested-assign-shadow-function-call.js
new file mode 100644
index 0000000000..a9430e3247
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/strict-nested-assign-shadow-function-call.js
@@ -0,0 +1,33 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+load(libdir + 'array-compare.js');
+
+var obj = {};
+
+function strictNestedAssignShadowFunctionCall(p)
+{
+ "use strict";
+ function inner()
+ {
+ function p() { }
+ p = 1776;
+ }
+ inner();
+ return arguments;
+}
+
+var a1, a2, a3, a4;
+for (var i = 0; i < 5; i++)
+{
+ a1 = strictNestedAssignShadowFunctionCall();
+ a2 = strictNestedAssignShadowFunctionCall(99);
+ a3 = strictNestedAssignShadowFunctionCall("");
+ a4 = strictNestedAssignShadowFunctionCall(obj);
+}
+
+assertEq(arraysEqual(a1, []), true);
+assertEq(arraysEqual(a2, [99]), true);
+assertEq(arraysEqual(a3, [""]), true);
+assertEq(arraysEqual(a4, [obj]), true);
diff --git a/js/src/jit-test/tests/arguments/strict-nested-assign-shadow-function-name.js b/js/src/jit-test/tests/arguments/strict-nested-assign-shadow-function-name.js
new file mode 100644
index 0000000000..e8ae3177aa
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/strict-nested-assign-shadow-function-name.js
@@ -0,0 +1,33 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+load(libdir + 'array-compare.js');
+
+var obj = {};
+
+function strictNestedAssignShadowFunctionName(p)
+{
+ "use strict";
+ function inner()
+ {
+ function p() { p = 1776; }
+ p();
+ }
+ inner();
+ return arguments;
+}
+
+var a1, a2, a3, a4, a5;
+for (var i = 0; i < 5; i++)
+{
+ a1 = strictNestedAssignShadowFunctionName();
+ a2 = strictNestedAssignShadowFunctionName(99);
+ a3 = strictNestedAssignShadowFunctionName("");
+ a4 = strictNestedAssignShadowFunctionName(obj);
+}
+
+assertEq(arraysEqual(a1, []), true);
+assertEq(arraysEqual(a2, [99]), true);
+assertEq(arraysEqual(a3, [""]), true);
+assertEq(arraysEqual(a4, [obj]), true);
diff --git a/js/src/jit-test/tests/arguments/strict-nested-assign-shadow-function.js b/js/src/jit-test/tests/arguments/strict-nested-assign-shadow-function.js
new file mode 100644
index 0000000000..46e0acfd04
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/strict-nested-assign-shadow-function.js
@@ -0,0 +1,32 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+load(libdir + 'array-compare.js');
+
+var obj = {};
+
+function strictNestedAssignShadowFunction(p)
+{
+ "use strict";
+ function inner()
+ {
+ function p() { }
+ p = 1776;
+ }
+ return arguments;
+}
+
+var a1, a2, a3, a4;
+for (var i = 0; i < 5; i++)
+{
+ a1 = strictNestedAssignShadowFunction();
+ a2 = strictNestedAssignShadowFunction(99);
+ a3 = strictNestedAssignShadowFunction("");
+ a4 = strictNestedAssignShadowFunction(obj);
+}
+
+assertEq(arraysEqual(a1, []), true);
+assertEq(arraysEqual(a2, [99]), true);
+assertEq(arraysEqual(a3, [""]), true);
+assertEq(arraysEqual(a4, [obj]), true);
diff --git a/js/src/jit-test/tests/arguments/strict-nested-assign-shadowed-catch-call.js b/js/src/jit-test/tests/arguments/strict-nested-assign-shadowed-catch-call.js
new file mode 100644
index 0000000000..03c5e027de
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/strict-nested-assign-shadowed-catch-call.js
@@ -0,0 +1,39 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+load(libdir + 'array-compare.js');
+
+var obj = {};
+
+function strictNestedAssignShadowCatchCall(p)
+{
+ "use strict";
+ function inner()
+ {
+ try
+ {
+ }
+ catch (p)
+ {
+ var f = function innermost() { p = 1776; return 12; };
+ f();
+ }
+ }
+ inner();
+ return arguments;
+}
+
+var a1, a2, a3, a4;
+for (var i = 0; i < 5; i++)
+{
+ a1 = strictNestedAssignShadowCatchCall();
+ a2 = strictNestedAssignShadowCatchCall(99);
+ a3 = strictNestedAssignShadowCatchCall("");
+ a4 = strictNestedAssignShadowCatchCall(obj);
+}
+
+assertEq(arraysEqual(a1, []), true);
+assertEq(arraysEqual(a2, [99]), true);
+assertEq(arraysEqual(a3, [""]), true);
+assertEq(arraysEqual(a4, [obj]), true);
diff --git a/js/src/jit-test/tests/arguments/strict-nested-assign-shadowed-catch.js b/js/src/jit-test/tests/arguments/strict-nested-assign-shadowed-catch.js
new file mode 100644
index 0000000000..06df3f9149
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/strict-nested-assign-shadowed-catch.js
@@ -0,0 +1,39 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+load(libdir + 'array-compare.js');
+
+var obj = {};
+
+function strictNestedAssignShadowCatch(p)
+{
+ "use strict";
+ function inner()
+ {
+ try
+ {
+ }
+ catch (p)
+ {
+ var f = function innermost() { p = 1776; return 12; };
+ f();
+ }
+ }
+ return arguments;
+}
+
+var a1, a2, a3, a4;
+for (var i = 0; i < 5; i++)
+{
+ a1 = strictNestedAssignShadowCatch();
+ a2 = strictNestedAssignShadowCatch(99);
+ a3 = strictNestedAssignShadowCatch("");
+ a4 = strictNestedAssignShadowCatch(obj);
+}
+
+assertEq(arraysEqual(a1, []), true);
+assertEq(arraysEqual(a2, [99]), true);
+assertEq(arraysEqual(a3, [""]), true);
+assertEq(arraysEqual(a4, [obj]), true);
+
diff --git a/js/src/jit-test/tests/arguments/strict-nested-assign-shadowed-var.js b/js/src/jit-test/tests/arguments/strict-nested-assign-shadowed-var.js
new file mode 100644
index 0000000000..8248bed338
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/strict-nested-assign-shadowed-var.js
@@ -0,0 +1,29 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+load(libdir + 'array-compare.js');
+
+var obj = {};
+
+/********************
+ * STRICT ARGUMENTS *
+ ********************/
+
+function strictNestedAssignShadowVar(p)
+{
+ "use strict";
+ function inner()
+ {
+ var p = 12;
+ function innermost() { p = 1776; return 12; }
+ return innermost();
+ }
+ return arguments;
+}
+
+assertEq(arraysEqual(strictNestedAssignShadowVar(), []), true);
+assertEq(arraysEqual(strictNestedAssignShadowVar(99), [99]), true);
+assertEq(arraysEqual(strictNestedAssignShadowVar(""), [""]), true);
+assertEq(arraysEqual(strictNestedAssignShadowVar(obj), [obj]), true);
+
diff --git a/js/src/jit-test/tests/arguments/strict-nested-eval.js b/js/src/jit-test/tests/arguments/strict-nested-eval.js
new file mode 100644
index 0000000000..1f6eab54e4
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/strict-nested-eval.js
@@ -0,0 +1,31 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+load(libdir + 'array-compare.js');
+
+function strictNestedEval(code, p)
+{
+ "use strict";
+ function inner() { eval(code); }
+ inner();
+ return arguments;
+}
+
+var a1, a2, a3, a4, a5, a6;
+for (var i = 0; i < 5; i++)
+{
+ a1 = strictNestedEval("1", 2);
+ a2 = strictNestedEval("arguments");
+ a3 = strictNestedEval("p = 2");
+ a4 = strictNestedEval("p = 2", 17);
+ a5 = strictNestedEval("arguments[0] = 17");
+ a6 = strictNestedEval("arguments[0] = 17", 42);
+}
+
+assertEq(arraysEqual(a1, ["1", 2]), true);
+assertEq(arraysEqual(a2, ["arguments"]), true);
+assertEq(arraysEqual(a3, ["p = 2"]), true);
+assertEq(arraysEqual(a4, ["p = 2", 17]), true);
+assertEq(arraysEqual(a5, ["arguments[0] = 17"]), true);
+assertEq(arraysEqual(a6, ["arguments[0] = 17", 42]), true);
diff --git a/js/src/jit-test/tests/arguments/strict-nested-shadow-eval.js b/js/src/jit-test/tests/arguments/strict-nested-shadow-eval.js
new file mode 100644
index 0000000000..d80b7be0a7
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/strict-nested-shadow-eval.js
@@ -0,0 +1,30 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+load(libdir + 'array-compare.js');
+
+function strictNestedShadowEval(code, p)
+{
+ "use strict";
+ function inner(p) { eval(code); }
+ return arguments;
+}
+
+var a1, a2, a3, a4, a5, a6;
+for (var i = 0; i < 5; i++)
+{
+ a1 = strictNestedShadowEval("1", 2);
+ a2 = strictNestedShadowEval("arguments");
+ a3 = strictNestedShadowEval("p = 2");
+ a4 = strictNestedShadowEval("p = 2", 17);
+ a5 = strictNestedShadowEval("arguments[0] = 17");
+ a6 = strictNestedShadowEval("arguments[0] = 17", 42);
+}
+
+assertEq(arraysEqual(a1, ["1", 2]), true);
+assertEq(arraysEqual(a2, ["arguments"]), true);
+assertEq(arraysEqual(a3, ["p = 2"]), true);
+assertEq(arraysEqual(a4, ["p = 2", 17]), true);
+assertEq(arraysEqual(a5, ["arguments[0] = 17"]), true);
+assertEq(arraysEqual(a6, ["arguments[0] = 17", 42]), true);
diff --git a/js/src/jit-test/tests/arguments/strict-nested-shadow-maybe-eval.js b/js/src/jit-test/tests/arguments/strict-nested-shadow-maybe-eval.js
new file mode 100644
index 0000000000..cf9edea9ee
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/strict-nested-shadow-maybe-eval.js
@@ -0,0 +1,30 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+load(libdir + 'array-compare.js');
+
+function strictNestedShadowMaybeEval(code, p)
+{
+ "use strict";
+ function inner(p) { eval(code); }
+ return arguments;
+}
+
+var a1, a2, a3, a4, a5, a6;
+for (var i = 0; i < 5; i++)
+{
+ a1 = strictNestedShadowMaybeEval("1", 2);
+ a2 = strictNestedShadowMaybeEval("arguments");
+ a3 = strictNestedShadowMaybeEval("p = 2");
+ a4 = strictNestedShadowMaybeEval("p = 2", 17);
+ a5 = strictNestedShadowMaybeEval("arguments[0] = 17");
+ a6 = strictNestedShadowMaybeEval("arguments[0] = 17", 42);
+}
+
+assertEq(arraysEqual(a1, ["1", 2]), true);
+assertEq(arraysEqual(a2, ["arguments"]), true);
+assertEq(arraysEqual(a3, ["p = 2"]), true);
+assertEq(arraysEqual(a4, ["p = 2", 17]), true);
+assertEq(arraysEqual(a5, ["arguments[0] = 17"]), true);
+assertEq(arraysEqual(a6, ["arguments[0] = 17", 42]), true);
diff --git a/js/src/jit-test/tests/arguments/strict-noargs.js b/js/src/jit-test/tests/arguments/strict-noargs.js
new file mode 100644
index 0000000000..dfee3c8583
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/strict-noargs.js
@@ -0,0 +1,25 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+load(libdir + 'array-compare.js');
+
+var obj = {};
+
+function strictNoargs()
+{
+ "use strict";
+ return arguments;
+}
+
+var a1, a2, a3;
+for (var i = 0; i < 5; i++)
+{
+ a1 = strictNoargs();
+ a2 = strictNoargs(1);
+ a3 = strictNoargs(1, obj);
+}
+
+assertEq(arraysEqual(a1, []), true);
+assertEq(arraysEqual(a2, [1]), true);
+assertEq(arraysEqual(a3, [1, obj]), true);
diff --git a/js/src/jit-test/tests/arguments/strict-osr-shadowed-args.js b/js/src/jit-test/tests/arguments/strict-osr-shadowed-args.js
new file mode 100644
index 0000000000..5c193b99f6
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/strict-osr-shadowed-args.js
@@ -0,0 +1,13 @@
+
+"use strict";
+
+function loop(a) {
+ a = arguments.length;
+ var result = 0;
+ for (var i = 0; i < 5000; i++) {
+ result += a;
+ }
+ return result;
+}
+
+assertEq(loop(11), 5000);
diff --git a/js/src/jit-test/tests/arguments/testDelArg1.js b/js/src/jit-test/tests/arguments/testDelArg1.js
new file mode 100644
index 0000000000..a6b5eee326
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/testDelArg1.js
@@ -0,0 +1,13 @@
+function f(x,y,z) {
+ z = 9;
+ delete arguments[2];
+ assertEq(arguments[2], undefined);
+ o = arguments;
+ assertEq(o[2], undefined);
+ assertEq(o[2] == undefined, true);
+}
+
+for (var i = 0; i < 10; ++i) {
+ print(i);
+ f(1,2,3)
+}
diff --git a/js/src/jit-test/tests/arguments/testDelArg2.js b/js/src/jit-test/tests/arguments/testDelArg2.js
new file mode 100644
index 0000000000..09fcf1f57d
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/testDelArg2.js
@@ -0,0 +1,13 @@
+function f(del) {
+ o = arguments;
+ if (del)
+ delete o[2];
+ for (var i = 0; i < 10; ++i)
+ assertEq(o[2] == undefined, del);
+}
+
+// record without arg deleted
+f(false, 1,2,3,4);
+
+// run with arg deleted
+f(true, 1,2,3,4);
diff --git a/js/src/jit-test/tests/arguments/testDelArg3.js b/js/src/jit-test/tests/arguments/testDelArg3.js
new file mode 100644
index 0000000000..4931870bbc
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/testDelArg3.js
@@ -0,0 +1,42 @@
+function assertGood(x) {
+ assertEq(x, "good");
+}
+
+(function() {
+ var a = arguments;
+ return function() {
+ assertGood.apply(null, a);
+ }
+})("good")();
+
+(function() {
+ var a = arguments;
+ return function() {
+ a[0] = "good";
+ assertGood.apply(null, a);
+ }
+})("bad")();
+
+Object.prototype[0] = "good";
+
+(function() {
+ var a = arguments;
+ return function() {
+ delete a[0];
+ assertGood.apply(null, a);
+ }
+})("bad")();
+
+delete Object.prototype[0];
+
+function assertUndefined(x) {
+ assertEq(x, undefined);
+}
+
+(function() {
+ var a = arguments;
+ return function() {
+ a[0] = "bad";
+ assertUndefined.apply(null, a);
+ }
+})()();
diff --git a/js/src/jit-test/tests/arguments/testDelArg3Strict.js b/js/src/jit-test/tests/arguments/testDelArg3Strict.js
new file mode 100644
index 0000000000..77d247a4d8
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/testDelArg3Strict.js
@@ -0,0 +1,44 @@
+"use strict";
+
+function assertGood(x) {
+ assertEq(x, "good");
+}
+
+(function() {
+ var a = arguments;
+ return function() {
+ assertGood.apply(null, a);
+ }
+})("good")();
+
+(function() {
+ var a = arguments;
+ return function() {
+ a[0] = "good";
+ assertGood.apply(null, a);
+ }
+})("bad")();
+
+Object.prototype[0] = "good";
+
+(function() {
+ var a = arguments;
+ return function() {
+ delete a[0];
+ assertGood.apply(null, a);
+ }
+})("bad")();
+
+delete Object.prototype[0];
+
+function assertUndefined(x) {
+ assertEq(x, undefined);
+}
+
+(function() {
+ var a = arguments;
+ return function() {
+ a[0] = "bad";
+ assertUndefined.apply(null, a);
+ }
+})()();