void SetObject::mark(JSTracer* trc, JSObject* obj) { SetObject* setobj = static_cast<SetObject*>(obj); if (ValueSet* set = setobj->getData()) { for (ValueSet::Range r = set->all(); !r.empty(); r.popFront()) MarkKey(r, r.front(), trc); } }
bool SetIteratorObject::next_impl(JSContext* cx, const CallArgs& args) { SetIteratorObject& thisobj = args.thisv().toObject().as<SetIteratorObject>(); ValueSet::Range* range = thisobj.range(); RootedValue value(cx); bool done; if (!range || range->empty()) { js_delete(range); thisobj.setReservedSlot(RangeSlot, PrivateValue(nullptr)); value.setUndefined(); done = true; } else { switch (thisobj.kind()) { case SetObject::Values: value = range->front().get(); break; case SetObject::Entries: { JS::AutoValueArray<2> pair(cx); pair[0].set(range->front().get()); pair[1].set(range->front().get()); JSObject* pairObj = NewDenseCopiedArray(cx, 2, pair.begin()); if (!pairObj) return false; value.setObject(*pairObj); break; } } range->popFront(); done = false; } RootedObject result(cx, CreateItrResultObject(cx, value, done)); if (!result) return false; args.rval().setObject(*result); return true; }
bool SetObject::keys(JSContext* cx, HandleObject obj, JS::MutableHandle<GCVector<JS::Value>> keys) { ValueSet* set = obj->as<SetObject>().getData(); if (!set) return false; for (ValueSet::Range r = set->all(); !r.empty(); r.popFront()) { if (!keys.append(r.front().get())) return false; } return true; }
bool SetIteratorObject::next(Handle<SetIteratorObject*> setIterator, HandleArrayObject resultObj, JSContext* cx) { // Check invariants for inlined _GetNextSetEntryForIterator. // The array should be tenured, so that post-barrier can be done simply. MOZ_ASSERT(resultObj->isTenured()); // The array elements should be fixed. MOZ_ASSERT(resultObj->hasFixedElements()); MOZ_ASSERT(resultObj->getDenseInitializedLength() == 1); MOZ_ASSERT(resultObj->getDenseCapacity() >= 1); ValueSet::Range* range = SetIteratorObjectRange(setIterator); if (!range || range->empty()) { js_delete(range); setIterator->setReservedSlot(RangeSlot, PrivateValue(nullptr)); return true; } resultObj->setDenseElementWithType(cx, 0, range->front().get()); range->popFront(); return false; }