JSPropertyNameIterator* JSPropertyNameIterator::create(ExecState* exec, Structure* structure, JSObject* iteratedObject, JSPropertyNameEnumerator* enumerator) { VM& vm = exec->vm(); JSPropertyNameIterator* instance = new (NotNull, allocateCell<JSPropertyNameIterator>(vm.heap)) JSPropertyNameIterator(vm, structure, iteratedObject, enumerator); instance->finishCreation(vm, structure->globalObject()); return instance; }
JSPropertyNameIterator* JSPropertyNameIterator::create(ExecState* exec, JSObject* o) { ASSERT(!o->structure()->enumerationCache() || o->structure()->enumerationCache()->cachedStructure() != o->structure() || o->structure()->enumerationCache()->cachedPrototypeChain() != o->structure()->prototypeChain(exec)); PropertyNameArray propertyNames(exec); o->getPropertyNames(exec, propertyNames); size_t numCacheableSlots = 0; if (!o->structure()->hasNonEnumerableProperties() && !o->structure()->hasAnonymousSlots() && !o->structure()->isUncacheableDictionary() && !o->structure()->typeInfo().overridesGetPropertyNames()) numCacheableSlots = o->structure()->propertyStorageSize(); JSPropertyNameIterator* jsPropertyNameIterator = new (exec) JSPropertyNameIterator(exec, propertyNames.data(), numCacheableSlots); if (o->structure()->isDictionary()) return jsPropertyNameIterator; if (o->structure()->typeInfo().overridesGetPropertyNames()) return jsPropertyNameIterator; size_t count = normalizePrototypeChain(exec, o); StructureChain* structureChain = o->structure()->prototypeChain(exec); RefPtr<Structure>* structure = structureChain->head(); for (size_t i = 0; i < count; ++i) { if (structure[i]->typeInfo().overridesGetPropertyNames()) return jsPropertyNameIterator; } jsPropertyNameIterator->setCachedPrototypeChain(structureChain); jsPropertyNameIterator->setCachedStructure(o->structure()); o->structure()->setEnumerationCache(jsPropertyNameIterator); return jsPropertyNameIterator; }
JSPropertyNameIterator* JSPropertyNameIterator::create(ExecState* exec, JSObject* o) { ASSERT(!o->structure()->enumerationCache() || o->structure()->enumerationCache()->cachedStructure() != o->structure() || o->structure()->enumerationCache()->cachedPrototypeChain() != o->structure()->prototypeChain(exec)); PropertyNameArray propertyNames(exec); o->methodTable()->getPropertyNames(o, exec, propertyNames, ExcludeDontEnumProperties); size_t numCacheableSlots = 0; if (!o->structure()->hasNonEnumerableProperties() && !o->structure()->hasGetterSetterProperties() && !o->structure()->isUncacheableDictionary() && !o->structure()->typeInfo().overridesGetPropertyNames()) numCacheableSlots = o->structure()->totalStorageSize(); JSPropertyNameIterator* jsPropertyNameIterator = new (NotNull, allocateCell<JSPropertyNameIterator>(*exec->heap())) JSPropertyNameIterator(exec, propertyNames.data(), numCacheableSlots); jsPropertyNameIterator->finishCreation(exec, propertyNames.data(), o); if (o->structure()->isDictionary()) return jsPropertyNameIterator; if (o->structure()->typeInfo().overridesGetPropertyNames()) return jsPropertyNameIterator; size_t count = normalizePrototypeChain(exec, o); StructureChain* structureChain = o->structure()->prototypeChain(exec); WriteBarrier<Structure>* structure = structureChain->head(); for (size_t i = 0; i < count; ++i) { if (structure[i]->typeInfo().overridesGetPropertyNames()) return jsPropertyNameIterator; } jsPropertyNameIterator->setCachedPrototypeChain(exec->globalData(), structureChain); jsPropertyNameIterator->setCachedStructure(exec->globalData(), o->structure()); o->structure()->setEnumerationCache(exec->globalData(), jsPropertyNameIterator); return jsPropertyNameIterator; }
void JSPropertyNameIterator::visitChildren(JSCell* cell, SlotVisitor& visitor) { JSPropertyNameIterator* thisObject = jsCast<JSPropertyNameIterator*>(cell); ASSERT_GC_OBJECT_INHERITS(thisObject, &s_info); ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren()); visitor.appendValues(thisObject->m_jsStrings.get(), thisObject->m_jsStringsSize); visitor.append(&thisObject->m_cachedPrototypeChain); }
EncodedJSValue JSC_HOST_CALL propertyNameIteratorFuncNext(ExecState* exec) { VM& vm = exec->vm(); auto scope = DECLARE_THROW_SCOPE(vm); JSPropertyNameIterator* iterator = jsDynamicCast<JSPropertyNameIterator*>(exec->thisValue()); if (!iterator) return JSValue::encode(throwTypeError(exec, scope, ASCIILiteral("Cannot call PropertyNameIterator.next() on a non-PropertyNameIterator object"))); JSValue result; if (iterator->next(exec, result)) return JSValue::encode(createIteratorResultObject(exec, result, false)); return JSValue::encode(createIteratorResultObject(exec, jsUndefined(), true)); }