Merge from TM

This commit is contained in:
Luke Wagner
2010-07-04 14:49:39 -07:00
1783 changed files with 50279 additions and 29426 deletions

View File

@@ -201,19 +201,38 @@ struct ValueEnumeration
template <class EnumPolicy>
static inline bool
Enumerate(JSContext *cx, JSObject *obj, JSObject *pobj, jsid id,
bool enumerable, uintN flags, IdSet& ht,
bool enumerable, bool sharedPermanent, uintN flags, IdSet& ht,
typename EnumPolicy::ResultVector &vec)
{
JS_ASSERT(JSID_IS_INT(id) || JSID_IS_ATOM(id));
if (JS_LIKELY(!(flags & JSITER_OWNONLY))) {
IdSet::AddPtr p = ht.lookupForAdd(id);
/* property already encountered, done. */
if (JS_UNLIKELY(!!p))
IdSet::AddPtr p = ht.lookupForAdd(id);
JS_ASSERT_IF(obj == pobj, !p);
/* If we've already seen this, we definitely won't add it. */
if (JS_UNLIKELY(!!p))
return true;
/*
* It's not necessary to add properties to the hash table at the end of the
* prototype chain.
*/
if (pobj->getProto() && !ht.add(p, id))
return false;
if (JS_UNLIKELY(flags & JSITER_OWNONLY)) {
/*
* Shared-permanent hack: If this property is shared permanent
* and pobj and obj have the same class, then treat it as an own
* property of obj, even if pobj != obj. (But see bug 575997.)
*
* Omit the magic __proto__ property so that JS code can use
* Object.getOwnPropertyNames without worrying about it.
*/
if (!pobj->getProto() && id == ATOM_TO_JSID(cx->runtime->atomState.protoAtom))
return true;
if (pobj != obj && !(sharedPermanent && pobj->getClass() == obj->getClass()))
return true;
/* no need to add properties to the hash table at the end of the prototype chain */
if (pobj->getProto() && !ht.add(p, id))
return false;
}
if (enumerable || (flags & JSITER_HIDDEN))
@@ -236,7 +255,9 @@ EnumerateNativeProperties(JSContext *cx, JSObject *obj, JSObject *pobj, uintN fl
for (JSScopeProperty *sprop = scope->lastProperty(); sprop; sprop = sprop->parent) {
if (!JSID_IS_DEFAULT_XML_NAMESPACE(sprop->id) &&
!sprop->isAlias() &&
!Enumerate<EnumPolicy>(cx, obj, pobj, sprop->id, sprop->enumerable(), flags, ht, vec)) {
!Enumerate<EnumPolicy>(cx, obj, pobj, sprop->id, sprop->enumerable(), sprop->isSharedPermanent(),
flags, ht, sprops))
{
return false;
}
}
@@ -252,19 +273,23 @@ static bool
EnumerateDenseArrayProperties(JSContext *cx, JSObject *obj, JSObject *pobj, uintN flags,
IdSet &ht, typename EnumPolicy::ResultVector &vec)
{
size_t count = pobj->getDenseArrayCount();
if (!Enumerate(cx, obj, pobj, ATOM_TO_JSID(cx->runtime->atomState.lengthAtom), false, true,
flags, ht, props)) {
return false;
}
if (count) {
if (pobj->getDenseArrayCount() > 0) {
size_t capacity = pobj->getDenseArrayCapacity();
Value *vp = pobj->dslots;
for (size_t i = 0; i < capacity; ++i, ++vp) {
if (!vp->isMagic(JS_ARRAY_HOLE)) {
/* Dense arrays never get so large that i would not fit into an integer id. */
if (!Enumerate<EnumPolicy>(cx, obj, pobj, INT_TO_JSID(i), true, flags, ht, vec))
if (!Enumerate<EnumPolicy>(cx, obj, pobj, INT_TO_JSID(i), true, false, flags, ht, props))
return false;
}
}
}
return true;
}
@@ -272,8 +297,13 @@ template <class EnumPolicy>
static bool
Snapshot(JSContext *cx, JSObject *obj, uintN flags, typename EnumPolicy::ResultVector &vec)
{
/*
* FIXME: Bug 575997 - We won't need to initialize this hash table if
* (flags & JSITER_OWNONLY) when we eliminate inheritance of
* shared-permanent properties as own properties.
*/
IdSet ht(cx);
if (!(flags & JSITER_OWNONLY) && !ht.init(32))
if (!ht.init(32))
return NULL;
JSObject *pobj = obj;
@@ -300,14 +330,15 @@ Snapshot(JSContext *cx, JSObject *obj, uintN flags, typename EnumPolicy::ResultV
return false;
}
for (size_t n = 0, len = proxyProps.length(); n < len; n++) {
if (!Enumerate<EnumPolicy>(cx, obj, pobj, proxyProps[n], true, flags, ht, vec))
if (!Enumerate<EnumPolicy>(cx, obj, pobj, proxyProps[n], true, false, flags, ht, vec))
return false;
}
/* Proxy objects enumerate the prototype on their own, so we are done here. */
break;
}
Value state;
if (!pobj->enumerate(cx, JSENUMERATE_INIT, &state, NULL))
JSIterateOp op = (flags & JSITER_HIDDEN) ? JSENUMERATE_INIT_ALL : JSENUMERATE_INIT;
if (!pobj->enumerate(cx, op, &state, NULL))
return false;
if (state.isMagic(JS_NATIVE_ENUMERATE)) {
if (!EnumerateNativeProperties<EnumPolicy>(cx, obj, pobj, flags, ht, vec))
@@ -319,13 +350,13 @@ Snapshot(JSContext *cx, JSObject *obj, uintN flags, typename EnumPolicy::ResultV
return false;
if (state.isNull())
break;
if (!Enumerate<EnumPolicy>(cx, obj, pobj, id, true, flags, ht, vec))
if (!Enumerate<EnumPolicy>(cx, obj, pobj, id, true, false, flags, ht, vec))
return false;
}
}
}
if (JS_UNLIKELY(pobj->isXML() || (flags & JSITER_OWNONLY)))
if (JS_UNLIKELY(pobj->isXML()))
break;
} while ((pobj = pobj->getProto()) != NULL);