diff --git a/js/src/jsemit.cpp b/js/src/jsemit.cpp
--- a/js/src/jsemit.cpp
+++ b/js/src/jsemit.cpp
@@ -2407,20 +2407,19 @@ BindNameToSlot(JSContext *cx, JSCodeGene
 
             ale = cg->upvarList.add(cg->parser, atom);
             if (!ale)
                 return JS_FALSE;
             index = ALE_INDEX(ale);
             JS_ASSERT(index == cg->upvarList.count - 1);
 
             UpvarCookie *vector = cg->upvarMap.vector;
-            if (!vector) {
-                uint32 length = cg->lexdeps.count;
-
-                vector = (UpvarCookie *) js_calloc(length * sizeof *vector);
+            uint32 length = cg->lexdeps.count;
+            if (!vector || cg->upvarMap.length != length) {
+                vector = (UpvarCookie *) js_realloc(vector, length * sizeof *vector);
                 if (!vector) {
                     JS_ReportOutOfMemory(cx);
                     return JS_FALSE;
                 }
                 cg->upvarMap.vector = vector;
                 cg->upvarMap.length = length;
             }
 
@@ -2429,16 +2428,17 @@ BindNameToSlot(JSContext *cx, JSCodeGene
                 JSTreeContext *tc = cg;
                 do {
                     tc = tc->parent;
                 } while (tc->staticLevel != level);
                 if (tc->inFunction())
                     slot += tc->fun()->nargs;
             }
 
+            JS_ASSERT(index < cg->upvarMap.length);
             vector[index].set(skip, slot);
         }
 
         pn->pn_op = op;
         JS_ASSERT((index & JS_BITMASK(16)) == index);
         pn->pn_cookie.set(0, index);
         pn->pn_dflags |= PND_BOUND;
         return JS_TRUE;

