js/src/jsinfer.cpp
changeset 96029 34476c720f8fa8624cf2100d1e6fa5aae16d301e
parent 95918 293a26bda18021712e9bf6dd845b10da9335a205
child 96173 227b4a4c3c4676a9bbe316a58d56ab790629854a
child 106287 5cfb73435e0655e230e74a6aa7066d576b7c6a7d
--- a/js/src/jsinfer.cpp
+++ b/js/src/jsinfer.cpp
@@ -3824,17 +3824,19 @@ ScriptAnalysis::analyzeTypesBytecode(JSC
             types->addType(cx, Type::UnknownType());
         }
         break;
       }
 
       case JSOP_ENDINIT:
         break;
 
-      case JSOP_INITELEM: {
+      case JSOP_INITELEM:
+      case JSOP_INITELEM_INC:
+      case JSOP_SPREAD: {
         const SSAValue &objv = poppedValue(pc, 2);
         jsbytecode *initpc = script->code + objv.pushedOffset();
         TypeObject *initializer = GetInitializerType(cx, script, initpc);
 
         if (initializer) {
             pushed[0].addType(cx, Type::ObjectType(initializer));
             if (!initializer->unknownProperties()) {
                 /*
@@ -3845,23 +3847,34 @@ ScriptAnalysis::analyzeTypesBytecode(JSC
                 TypeSet *types = initializer->getProperty(cx, JSID_VOID, true);
                 if (!types)
                     return false;
                 if (state.hasGetSet) {
                     types->addType(cx, Type::UnknownType());
                 } else if (state.hasHole) {
                     if (!initializer->unknownProperties())
                         initializer->setFlags(cx, OBJECT_FLAG_NON_PACKED_ARRAY);
+                } else if (op == JSOP_SPREAD) {
+                    // Iterator could put arbitrary things into the array.
+                    types->addType(cx, Type::UnknownType());
                 } else {
                     poppedTypes(pc, 0)->addSubset(cx, types);
                 }
             }
         } else {
             pushed[0].addType(cx, Type::UnknownType());
         }
+        switch (op) {
+          case JSOP_SPREAD:
+          case JSOP_INITELEM_INC:
+            poppedTypes(pc, 1)->addSubset(cx, &pushed[1]);
+            break;
+          default:
+            break;
+        }
         state.hasGetSet = false;
         state.hasHole = false;
         break;
       }
 
       case JSOP_GETTER:
       case JSOP_SETTER:
         state.hasGetSet = true;