Bug 794065 - Fix array literals with spread and holes at the end. r=jorendorff
authorBenjamin Peterson <benjamin@python.org>
Tue, 25 Sep 2012 14:30:37 -0400
changeset 108040 5515b887c42c320e3d75f27f4d5cb0c8ac4a9bb7
parent 108039 21c1b7080c53f579e0375acab8486c0e90ef5038
child 108041 21efec008d919c74a3edbf13478692a7276c6866
push id15343
push userbenjamin@python.org
push dateTue, 25 Sep 2012 18:33:49 +0000
treeherdermozilla-inbound@5515b887c42c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjorendorff
bugs794065
milestone18.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 794065 - Fix array literals with spread and holes at the end. r=jorendorff
js/src/jit-test/tests/basic/spread-array.js
js/src/jsinterp.cpp
--- a/js/src/jit-test/tests/basic/spread-array.js
+++ b/js/src/jit-test/tests/basic/spread-array.js
@@ -2,14 +2,16 @@ load(libdir + "eqArrayHelper.js");
 
 assertEqArray([...[1, 2, 3]], [1, 2, 3]);
 assertEqArray([1, ...[2, 3, 4], 5], [1, 2, 3, 4, 5]);
 assertEqArray([1, ...[], 2], [1, 2]);
 assertEqArray([1, ...[2, 3], 4, ...[5, 6]], [1, 2, 3, 4, 5, 6]);
 assertEqArray([1, ...[], 2], [1, 2]);
 assertEqArray([1,, ...[2]], [1,, 2]);
 assertEqArray([1,, ...[2],, 3,, 4,], [1,, 2,, 3,, 4,]);
+assertEqArray([...[1, 2, 3],,,,], [1, 2, 3,,,,]);
+assertEqArray([,,...[1, 2, 3],,,,], [,,1,2,3,,,,]);
 
 // According to the draft spec, null and undefined are to be treated as empty
 // arrays. However, they are not iterable. If the spec is not changed to be in
 // terms of iterables, these tests should be fixed.
 //assertEqArray([1, ...null, 2], [1, 2]);
 //assertEqArray([1, ...undefined, 2], [1, 2]);
--- a/js/src/jsinterp.cpp
+++ b/js/src/jsinterp.cpp
@@ -3200,20 +3200,22 @@ BEGIN_CASE(JSOP_INITELEM)
      * If rref is a hole, do not call JSObject::defineProperty. In this case,
      * obj must be an array, so if the current op is the last element
      * initialiser, set the array length to one greater than id.
      */
     if (rref.isMagic(JS_ARRAY_HOLE)) {
         JS_ASSERT(obj->isArray());
         JS_ASSERT(JSID_IS_INT(id));
         JS_ASSERT(uint32_t(JSID_TO_INT(id)) < StackSpace::ARGS_LENGTH_MAX);
-        if (JSOp(regs.pc[JSOP_INITELEM_LENGTH]) == JSOP_ENDINIT &&
-            !SetLengthProperty(cx, obj, (uint32_t) (JSID_TO_INT(id) + 1)))
+        JSOp next = JSOp(*(regs.pc + GetBytecodeLength(regs.pc)));
+        if ((next == JSOP_ENDINIT && op == JSOP_INITELEM) ||
+            (next == JSOP_POP && op == JSOP_INITELEM_INC))
         {
-            goto error;
+            if (!SetLengthProperty(cx, obj, (uint32_t) (JSID_TO_INT(id) + 1)))
+                goto error;
         }
     } else {
         if (!JSObject::defineGeneric(cx, obj, id, rref, NULL, NULL, JSPROP_ENUMERATE))
             goto error;
     }
     if (op == JSOP_INITELEM_INC) {
         JS_ASSERT(obj->isArray());
         if (JSID_TO_INT(id) == INT32_MAX) {