Bug 923028 - Part1: Emit JSOP_INITELEM_ARRAY for elements before spread operator. r=jandem
authorTooru Fujisawa <arai_a@mac.com>
Thu, 22 May 2014 02:44:54 +0900
changeset 186599 2d06b7c9cc5bd0f1441598190e16d75e56043ebb
parent 186598 07a74e6e53b2829feff8205aa7630854ef239d3c
child 186600 dae53a38052e91c0fc27c0a0c994acba96970b9f
push idunknown
push userunknown
push dateunknown
reviewersjandem
bugs923028
milestone32.0a1
Bug 923028 - Part1: Emit JSOP_INITELEM_ARRAY for elements before spread operator. r=jandem
js/src/frontend/BytecodeEmitter.cpp
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -6062,44 +6062,48 @@ EmitArray(ExclusiveContext *cx, Bytecode
     jsbytecode *pc = bce->code(off);
 
     // For arrays with spread, this is a very pessimistic allocation, the
     // minimum possible final size.
     SET_UINT24(pc, count - nspread);
 
     ParseNode *pn2 = pn;
     jsatomid atomIndex;
-    if (nspread && !EmitNumberOp(cx, 0, bce))
-        return false;
+    bool afterSpread = false;
     for (atomIndex = 0; pn2; atomIndex++, pn2 = pn2->pn_next) {
+        if (!afterSpread && pn2->isKind(PNK_SPREAD)) {
+            afterSpread = true;
+            if (!EmitNumberOp(cx, atomIndex, bce))
+                return false;
+        }
         if (!UpdateSourceCoordNotes(cx, bce, pn2->pn_pos.begin))
             return false;
         if (pn2->isKind(PNK_ELISION)) {
             if (Emit1(cx, bce, JSOP_HOLE) < 0)
                 return false;
         } else {
             ParseNode *expr = pn2->isKind(PNK_SPREAD) ? pn2->pn_kid : pn2;
             if (!EmitTree(cx, bce, expr))
                 return false;
         }
         if (pn2->isKind(PNK_SPREAD)) {
             if (Emit1(cx, bce, JSOP_SPREAD) < 0)
                 return false;
-        } else if (nspread) {
+        } else if (afterSpread) {
             if (Emit1(cx, bce, JSOP_INITELEM_INC) < 0)
                 return false;
         } else {
             off = EmitN(cx, bce, JSOP_INITELEM_ARRAY, 3);
             if (off < 0)
                 return false;
             SET_UINT24(bce->code(off), atomIndex);
         }
     }
     JS_ASSERT(atomIndex == count);
-    if (nspread) {
+    if (afterSpread) {
         if (Emit1(cx, bce, JSOP_POP) < 0)
             return false;
     }
 
     /* Emit an op to finish the array and aid in decompilation. */
     return Emit1(cx, bce, JSOP_ENDINIT) >= 0;
 }