Fix bug 616711. r=gal
authorBrian Hackett <bhackett1024@gmail.com>
Tue, 14 Dec 2010 06:34:46 -0800
changeset 59240 b013a27e6275eed80d286d9d7ab9bdc00d700f87
parent 59239 4ed3025c0be2cfcd9c21314ee4258099cbf5574b
child 59241 2062f14d20810b3caf4c464700cf539e70a31816
push id1
push usershaver@mozilla.com
push dateTue, 04 Jan 2011 17:58:04 +0000
reviewersgal
bugs616711
milestone2.0b8pre
Fix bug 616711. r=gal
js/src/jswrapper.cpp
--- a/js/src/jswrapper.cpp
+++ b/js/src/jswrapper.cpp
@@ -521,22 +521,37 @@ static bool
 CanReify(Value *vp)
 {
     JSObject *obj;
     return vp->isObject() &&
            (obj = &vp->toObject())->getClass() == &js_IteratorClass &&
            (obj->getNativeIterator()->flags & JSITER_ENUMERATE);
 }
 
+struct AutoCloseIterator
+{
+    AutoCloseIterator(JSContext *cx, JSObject *obj) : cx(cx), obj(obj) {}
+
+    ~AutoCloseIterator() { if (obj) js_CloseIterator(cx, obj); }
+
+    void clear() { obj = NULL; }
+
+  private:
+    JSContext *cx;
+    JSObject *obj;
+};
+
 static bool
 Reify(JSContext *cx, JSCompartment *origin, Value *vp)
 {
     JSObject *iterObj = &vp->toObject();
     NativeIterator *ni = iterObj->getNativeIterator();
 
+    AutoCloseIterator close(cx, iterObj);
+
     /* Wrap the iteratee. */
     JSObject *obj = ni->obj;
     if (!origin->wrap(cx, &obj))
         return false;
 
     /*
      * Wrap the elements in the iterator's snapshot.
      * N.B. the order of closing/creating iterators is important due to the
@@ -551,16 +566,17 @@ Reify(JSContext *cx, JSCompartment *orig
                 return false;
             for (size_t i = 0; i < length; ++i) {
                 keys[i] = ni->beginKey()[i];
                 if (!origin->wrapId(cx, &keys[i]))
                     return false;
             }
         }
 
+        close.clear();
         return js_CloseIterator(cx, iterObj) &&
                VectorToKeyIterator(cx, obj, ni->flags, keys, vp);
     }
 
     size_t length = ni->numValues();
     AutoValueVector vals(cx);
     if (length > 0) {
         if (!vals.resize(length))
@@ -568,16 +584,17 @@ Reify(JSContext *cx, JSCompartment *orig
         for (size_t i = 0; i < length; ++i) {
             vals[i] = ni->beginValue()[i];
             if (!origin->wrap(cx, &vals[i]))
                 return false;
         }
 
     }
 
+    close.clear();
     return js_CloseIterator(cx, iterObj) &&
            VectorToValueIterator(cx, obj, ni->flags, vals, vp);
 }
 
 bool
 JSCrossCompartmentWrapper::iterate(JSContext *cx, JSObject *wrapper, uintN flags, Value *vp)
 {
     PIERCE(cx, wrapper, GET,