Bug 574474 - Eliminate a gratuitous property-name copy from the implementation of Object.keys. r=gal

This commit is contained in:
Jeff Walden 2010-06-24 15:03:54 -07:00
Родитель e809f4b20f
Коммит c1597c0af6
1 изменённых файлов: 9 добавлений и 30 удалений

Просмотреть файл

@ -1863,43 +1863,22 @@ obj_keys(JSContext *cx, uintN argc, jsval *vp)
if (!GetFirstArgumentAsObject(cx, argc, vp, "Object.keys", &obj)) if (!GetFirstArgumentAsObject(cx, argc, vp, "Object.keys", &obj))
return JS_FALSE; return JS_FALSE;
AutoIdArray ida(cx, JS_Enumerate(cx, obj)); AutoValueVector props(cx);
if (!ida) if (!GetPropertyNames(cx, obj, JSITER_OWNONLY, props))
return JS_FALSE; return JS_FALSE;
JSObject *proto; for (size_t i = 0, len = props.length(); i < len; i++) {
if (!js_GetClassPrototype(cx, NULL, JSProto_Array, &proto)) jsid id = jsid(props[i]);
return JS_FALSE; if (JSID_IS_INT(id) && !js_ValueToStringId(cx, INT_JSID_TO_JSVAL(id), &props[i]))
vp[1] = OBJECT_TO_JSVAL(proto); return JS_FALSE;
}
JS_ASSERT(ida.length() <= UINT32_MAX); JS_ASSERT(props.length() <= UINT32_MAX);
JSObject *aobj = js_NewArrayWithSlots(cx, proto, uint32(ida.length())); JSObject *aobj = js_NewArrayObject(cx, jsuint(props.length()), props.begin(), false);
if (!aobj) if (!aobj)
return JS_FALSE; return JS_FALSE;
*vp = OBJECT_TO_JSVAL(aobj); *vp = OBJECT_TO_JSVAL(aobj);
size_t len = ida.length();
JS_ASSERT(aobj->getDenseArrayCapacity() >= len);
for (size_t i = 0; i < len; i++) {
jsid id = ida[i];
if (JSID_IS_INT(id)) {
if (!js_ValueToStringId(cx, INT_JSID_TO_JSVAL(id), aobj->addressOfDenseArrayElement(i)))
return JS_FALSE;
} else {
/*
* Object-valued ids are a possibility admitted by SpiderMonkey for
* the purposes of E4X. It's unclear whether they could ever be
* detected here -- the "obvious" possibility, a property referred
* to by a QName, actually appears as a string jsid -- but in the
* interests of fidelity we pass object jsids through unchanged.
*/
aobj->setDenseArrayElement(i, ID_TO_VALUE(id));
}
}
JS_ASSERT(len <= UINT32_MAX);
aobj->setDenseArrayCount(len);
return JS_TRUE; return JS_TRUE;
} }