bool JSPropertyNameIterator::next(ExecState* exec, JSValue& output) { if (m_enumerationPhase == EnumerationPhase::IndexedNames) { for (; m_cursor < m_propertyNameEnumerator->indexedLength();) { uint32_t index = m_cursor++; if (m_iteratedObject->hasProperty(exec, index)) { output = jsString(exec, Identifier::from(exec, index).string()); return true; } } m_cursor = 0; m_enumerationPhase = EnumerationPhase::StructureNames; } if (m_enumerationPhase == EnumerationPhase::StructureNames) { for (; m_cursor < m_propertyNameEnumerator->endStructurePropertyIndex();) { uint32_t index = m_cursor++; JSString* propertyName = m_propertyNameEnumerator->propertyNameAtIndex(index); ASSERT(propertyName); if (m_iteratedObject->structure(exec->vm())->id() == m_propertyNameEnumerator->cachedStructureID()) { output = propertyName; return true; } if (m_iteratedObject->hasProperty(exec, propertyName->toIdentifier(exec))) { output = propertyName; return true; } } ASSERT(m_cursor >= m_propertyNameEnumerator->endStructurePropertyIndex()); // Use the same m_cursor in the GenericNames phase. m_enumerationPhase = EnumerationPhase::GenericNames; } if (m_enumerationPhase == EnumerationPhase::GenericNames) { for (; m_cursor < m_propertyNameEnumerator->endGenericPropertyIndex();) { uint32_t index = m_cursor++; JSString* propertyName = m_propertyNameEnumerator->propertyNameAtIndex(index); ASSERT(propertyName); if (m_iteratedObject->hasProperty(exec, propertyName->toIdentifier(exec))) { output = propertyName; return true; } } m_enumerationPhase = EnumerationPhase::Done; } return false; }