ida = js_GrowIdArray(cx, ida, newlen);
ida = js_SetIdArrayLength(cx, ida, newlen);
JS_Enumerate(JSContext *cx, JSObject *obj){    jsint i, n;    jsval iter_state, num_properties;    jsid id;    JSIdArray *ida;    jsval *vector;    CHECK_REQUEST(cx);    ida = NULL;    iter_state = JSVAL_NULL;    /* Get the number of properties to enumerate. */    if (!OBJ_ENUMERATE(cx, obj, JSENUMERATE_INIT, &iter_state, &num_properties))        goto error;    if (!JSVAL_IS_INT(num_properties)) {        JS_ASSERT(0);        goto error;    }    /* Grow as needed if we don't know the exact amount ahead of time. */    n = JSVAL_TO_INT(num_properties);    if (n <= 0)        n = 8;    /* Create an array of jsids large enough to hold all the properties */    ida = js_NewIdArray(cx, n);    if (!ida)        goto error;    i = 0;    vector = &ida->vector[0];    for (;;) {        if (i == ida->length) {            /* Grow length by factor of 1.5 instead of doubling. */            jsint newlen = ida->length + (((jsuint)ida->length + 1) >> 1);            ida = js_GrowIdArray(cx, ida, newlen);            if (!ida)                goto error;            vector = &ida->vector[0];        }        if (!OBJ_ENUMERATE(cx, obj, JSENUMERATE_NEXT, &iter_state, &id))            goto error;        /* No more jsid's to enumerate ? */        if (iter_state == JSVAL_NULL)            break;        vector[i++] = id;    }    ida->length = i;    return ida;error:    if (iter_state != JSVAL_NULL)        OBJ_ENUMERATE(cx, obj, JSENUMERATE_DESTROY, &iter_state, 0);    if (ida)        JS_DestroyIdArray(cx, ida);    return NULL;}