static inline bool Enumerate(JSContext *cx, JSObject *obj, JSObject *pobj, jsid id, bool enumerable, uintN flags, IdSet& ht, AutoIdVector *props) { JS_ASSERT_IF(flags & JSITER_OWNONLY, obj == pobj); if (!(flags & JSITER_OWNONLY) || pobj->isProxy() || pobj->getOps()->enumerate) { /* If we've already seen this, we definitely won't add it. */ IdSet::AddPtr p = ht.lookupForAdd(id); if (JS_UNLIKELY(!!p)) return true; /* * It's not necessary to add properties to the hash table at the end of * the prototype chain, but custom enumeration behaviors might return * duplicated properties, so always add in such cases. */ if ((pobj->getProto() || pobj->isProxy() || pobj->getOps()->enumerate) && !ht.add(p, id)) return false; } if (enumerable || (flags & JSITER_HIDDEN)) return props->append(id); return true; }
static inline bool Enumerate(JSContext *cx, JSObject *obj, JSObject *pobj, jsid id, bool enumerable, bool sharedPermanent, uintN flags, IdSet& ht, AutoIdVector *props) { IdSet::AddPtr p = ht.lookupForAdd(id); JS_ASSERT_IF(obj == pobj && !obj->isProxy(), !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 -- but a proxy might return duplicated properties, so * always add for them. */ if ((pobj->getProto() || pobj->isProxy()) && !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; } if (enumerable || (flags & JSITER_HIDDEN)) return props->append(id); return true; }
static inline bool Enumerate(JSContext *cx, JSObject *obj, JSObject *pobj, jsid id, bool enumerable, uintN flags, IdSet& ht, AutoIdVector *props) { JS_ASSERT_IF(flags & JSITER_OWNONLY, obj == pobj); /* * We implement __proto__ using a property on |Object.prototype|, but * because __proto__ is highly deserving of removal, we don't want it to * show up in property enumeration, even if only for |Object.prototype| * (think introspection by Prototype-like frameworks that add methods to * the built-in prototypes). So exclude __proto__ if the object where the * property was found has no [[Prototype]] and might be |Object.prototype|. */ if (JS_UNLIKELY(!pobj->getProto() && JSID_IS_ATOM(id, cx->runtime->atomState.protoAtom))) return true; if (!(flags & JSITER_OWNONLY) || pobj->isProxy() || pobj->getOps()->enumerate) { /* If we've already seen this, we definitely won't add it. */ IdSet::AddPtr p = ht.lookupForAdd(id); if (JS_UNLIKELY(!!p)) return true; /* * It's not necessary to add properties to the hash table at the end of * the prototype chain, but custom enumeration behaviors might return * duplicated properties, so always add in such cases. */ if ((pobj->getProto() || pobj->isProxy() || pobj->getOps()->enumerate) && !ht.add(p, id)) return false; } if (enumerable || (flags & JSITER_HIDDEN)) return props->append(id); return true; }