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; }
SSATmp* least_common_ancestor(SSATmp* s1, SSATmp* s2) { if (s1 == s2) return s1; if (s1 == nullptr || s2 == nullptr) return nullptr; IdSet<SSATmp> seen; auto const step = [] (SSATmp* v) { assertx(v != nullptr); return v->inst()->isPassthrough() ? v->inst()->getPassthroughValue() : nullptr; }; auto const process = [&] (SSATmp*& v) { if (v == nullptr) return false; if (seen[v]) return true; seen.add(v); v = step(v); return false; }; while (s1 != nullptr || s2 != nullptr) { if (process(s1)) return s1; if (process(s2)) return s2; } return nullptr; }
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; }
bool removeUnreachable(IRUnit& unit) { FTRACE(2, "removing unreachable blocks\n"); auto modified = false; IdSet<Block> visited; smart::stack<Block*> stack; stack.push(unit.entry()); // Find all blocks reachable from the entry block. while (!stack.empty()) { auto* b = stack.top(); stack.pop(); if (visited[b]) continue; visited.add(b); if (auto* taken = b->taken()) { if (!visited[taken]) stack.push(taken); } if (auto* next = b->next()) { if (!visited[next]) stack.push(next); } } // Erase any blocks not found above. auto* trace = unit.main(); auto& blocks = trace->blocks(); for (auto it = blocks.begin(); it != blocks.end(); ) { auto* b = *it; if (!visited[b]) { FTRACE(3, "removing unreachable B{}\n", b->id()); it = trace->erase(it); modified = true; } else { ++it; } } return modified; }
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; }