void Structure::getEnumerablePropertyNames(ExecState* exec, PropertyNameArray& propertyNames, JSObject* baseObject) { bool shouldCache = propertyNames.shouldCache() && !(propertyNames.size() || m_isDictionary); if (shouldCache && m_cachedPropertyNameArrayData) { if (m_cachedPropertyNameArrayData->cachedPrototypeChain() == prototypeChain(exec)) { propertyNames.setData(m_cachedPropertyNameArrayData); return; } clearEnumerationCache(); } getEnumerableNamesFromPropertyTable(propertyNames); getEnumerableNamesFromClassInfoTable(exec, baseObject->classInfo(), propertyNames); if (m_prototype.isObject()) { propertyNames.setShouldCache(false); // No need for our prototypes to waste memory on caching, since they're not being enumerated directly. asObject(m_prototype)->getPropertyNames(exec, propertyNames); } if (shouldCache) { m_cachedPropertyNameArrayData = propertyNames.data(); m_cachedPropertyNameArrayData->setCachedPrototypeChain(prototypeChain(exec)); m_cachedPropertyNameArrayData->setCachedStructure(this); } }
void Structure::getEnumerablePropertyNames(ExecState* exec, PropertyNameArray& propertyNames, JSObject* baseObject) { bool shouldCache = propertyNames.shouldCache() && !(propertyNames.size() || isDictionary()); if (shouldCache && m_cachedPropertyNameArrayData) { if (m_cachedPropertyNameArrayData->cachedPrototypeChain() == prototypeChain(exec)) { propertyNames.setData(m_cachedPropertyNameArrayData); return; } clearEnumerationCache(); } baseObject->getOwnPropertyNames(exec, propertyNames); if (m_prototype.isObject()) { propertyNames.setShouldCache(false); // No need for our prototypes to waste memory on caching, since they're not being enumerated directly. JSObject* prototype = asObject(m_prototype); while(1) { if (!prototype->structure()->typeInfo().hasDefaultGetPropertyNames()) { prototype->getPropertyNames(exec, propertyNames); break; } prototype->getOwnPropertyNames(exec, propertyNames); JSValue nextProto = prototype->prototype(); if (!nextProto.isObject()) break; prototype = asObject(nextProto); } } if (shouldCache) { StructureChain* protoChain = prototypeChain(exec); m_cachedPropertyNameArrayData = propertyNames.data(); if (!protoChain->isCacheable()) return; m_cachedPropertyNameArrayData->setCachedPrototypeChain(protoChain); m_cachedPropertyNameArrayData->setCachedStructure(this); } }