static inline bool Enumerate(JSContext* cx, HandleObject pobj, jsid id, bool enumerable, unsigned flags, Maybe<IdSet>& ht, AutoIdVector* props) { if (!(flags & JSITER_OWNONLY) || pobj->is<ProxyObject>() || pobj->getOps()->enumerate) { if (!ht) { ht.emplace(cx); // Most of the time there are only a handful of entries. if (!ht->init(5)) return false; } // If we've already seen this, we definitely won't add it. IdSet::AddPtr p = ht->lookupForAdd(id); if (MOZ_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->is<ProxyObject>() || pobj->getProto() || pobj->getOps()->enumerate) && !ht->add(p, id)) return false; } // Symbol-keyed properties and nonenumerable properties are skipped unless // the caller specifically asks for them. A caller can also filter out // non-symbols by asking for JSITER_SYMBOLSONLY. if (JSID_IS_SYMBOL(id) ? !(flags & JSITER_SYMBOLS) : (flags & JSITER_SYMBOLSONLY)) return true; if (!enumerable && !(flags & JSITER_HIDDEN)) return true; return props->append(id); }
static inline bool Enumerate(JSContext *cx, HandleObject pobj, jsid id, bool enumerable, unsigned flags, Maybe<IdSet>& ht, AutoIdVector *props) { // 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 (MOZ_UNLIKELY(!pobj->getTaggedProto().isObject() && JSID_IS_ATOM(id, cx->names().proto))) return true; if (!(flags & JSITER_OWNONLY) || pobj->is<ProxyObject>() || pobj->getOps()->enumerate) { if (!ht) { ht.emplace(cx); // Most of the time there are only a handful of entries. if (!ht->init(5)) return false; } // If we've already seen this, we definitely won't add it. IdSet::AddPtr p = ht->lookupForAdd(id); if (MOZ_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->is<ProxyObject>() || pobj->getProto() || pobj->getOps()->enumerate) && !ht->add(p, id)) return false; } // Symbol-keyed properties and nonenumerable properties are skipped unless // the caller specifically asks for them. A caller can also filter out // non-symbols by asking for JSITER_SYMBOLSONLY. if (JSID_IS_SYMBOL(id) ? !(flags & JSITER_SYMBOLS) : (flags & JSITER_SYMBOLSONLY)) return true; if (!enumerable && !(flags & JSITER_HIDDEN)) return true; return props->append(id); }