summaryrefslogtreecommitdiffstats
path: root/JavaScriptCore/runtime/JSPropertyNameIterator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'JavaScriptCore/runtime/JSPropertyNameIterator.cpp')
-rw-r--r--JavaScriptCore/runtime/JSPropertyNameIterator.cpp53
1 files changed, 44 insertions, 9 deletions
diff --git a/JavaScriptCore/runtime/JSPropertyNameIterator.cpp b/JavaScriptCore/runtime/JSPropertyNameIterator.cpp
index e08a3d9..6fd0344 100644
--- a/JavaScriptCore/runtime/JSPropertyNameIterator.cpp
+++ b/JavaScriptCore/runtime/JSPropertyNameIterator.cpp
@@ -29,26 +29,61 @@
#include "config.h"
#include "JSPropertyNameIterator.h"
+#include "JSGlobalObject.h"
+
namespace JSC {
ASSERT_CLASS_FITS_IN_CELL(JSPropertyNameIterator);
-JSPropertyNameIterator::~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->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;
}
-void JSPropertyNameIterator::markChildren(MarkStack& markStack)
+JSValue JSPropertyNameIterator::get(ExecState* exec, JSObject* base, size_t i)
{
- JSCell::markChildren(markStack);
- if (m_object)
- markStack.append(m_object);
+ JSValue& identifier = m_jsStrings[i];
+ if (m_cachedStructure == base->structure() && m_cachedPrototypeChain == base->structure()->prototypeChain(exec))
+ return identifier;
+
+ if (!base->hasProperty(exec, Identifier(exec, asString(identifier)->value())))
+ return JSValue();
+ return identifier;
}
-void JSPropertyNameIterator::invalidate()
+void JSPropertyNameIterator::markChildren(MarkStack& markStack)
{
- ASSERT(m_position == m_end);
- m_object = 0;
- m_data.clear();
+ markStack.appendValues(m_jsStrings.get(), m_jsStringsSize, MayContainNullValues);
}
} // namespace JSC