inline bool ForOfIterator::nextFromOptimizedArray(MutableHandleValue vp, bool* done) { MOZ_ASSERT(index != NOT_ARRAY); if (!CheckForInterrupt(cx_)) return false; ArrayObject* arr = &iterator->as<ArrayObject>(); if (index >= arr->length()) { vp.setUndefined(); *done = true; return true; } *done = false; // Try to get array element via direct access. if (index < arr->getDenseInitializedLength()) { vp.set(arr->getDenseElement(index)); if (!vp.isMagic(JS_ELEMENTS_HOLE)) { ++index; return true; } } return GetElement(cx_, iterator, iterator, index++, vp); }
bool SetObject::construct(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (!ThrowIfNotConstructing(cx, args, "Set")) return false; RootedObject proto(cx); RootedObject newTarget(cx, &args.newTarget().toObject()); if (!GetPrototypeFromConstructor(cx, newTarget, &proto)) return false; Rooted<SetObject*> obj(cx, SetObject::create(cx, proto)); if (!obj) return false; if (!args.get(0).isNullOrUndefined()) { RootedValue iterable(cx, args[0]); bool optimized = false; if (!IsOptimizableInitForSet<GlobalObject::getOrCreateSetPrototype, isBuiltinAdd>(cx, obj, iterable, &optimized)) return false; if (optimized) { RootedValue keyVal(cx); Rooted<HashableValue> key(cx); ValueSet* set = obj->getData(); ArrayObject* array = &iterable.toObject().as<ArrayObject>(); for (uint32_t index = 0; index < array->getDenseInitializedLength(); ++index) { keyVal.set(array->getDenseElement(index)); MOZ_ASSERT(!keyVal.isMagic(JS_ELEMENTS_HOLE)); if (!key.setValue(cx, keyVal)) return false; if (!WriteBarrierPost(cx->runtime(), obj, keyVal) || !set->put(key)) { ReportOutOfMemory(cx); return false; } } } else { FixedInvokeArgs<1> args2(cx); args2[0].set(args[0]); RootedValue thisv(cx, ObjectValue(*obj)); if (!CallSelfHostedFunction(cx, cx->names().SetConstructorInit, thisv, args2, args2.rval())) return false; } } args.rval().setObject(*obj); return true; }