summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/runtime/JSMapIterator.h
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/runtime/JSMapIterator.h')
-rw-r--r--Source/JavaScriptCore/runtime/JSMapIterator.h89
1 files changed, 54 insertions, 35 deletions
diff --git a/Source/JavaScriptCore/runtime/JSMapIterator.h b/Source/JavaScriptCore/runtime/JSMapIterator.h
index 5fc965ebc..6e977c22b 100644
--- a/Source/JavaScriptCore/runtime/JSMapIterator.h
+++ b/Source/JavaScriptCore/runtime/JSMapIterator.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Apple, Inc. All rights reserved.
+ * Copyright (C) 2013, 2016 Apple, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -23,23 +23,18 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef JSMapIterator_h
-#define JSMapIterator_h
+#pragma once
-#include "JSDestructibleObject.h"
+#include "IterationKind.h"
#include "JSMap.h"
-#include "MapData.h"
+#include "JSObject.h"
namespace JSC {
-enum MapIterationKind : uint32_t {
- MapIterateKey,
- MapIterateValue,
- MapIterateKeyValue,
-};
-class JSMapIterator : public JSDestructibleObject {
+class JSMapIterator : public JSNonFinalObject {
+ typedef HashMapBucket<HashMapBucketDataKeyValue> HashMapBucketType;
public:
- typedef JSDestructibleObject Base;
+ typedef JSNonFinalObject Base;
DECLARE_EXPORT_INFO;
@@ -48,53 +43,77 @@ public:
return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
}
- static JSMapIterator* create(VM& vm, Structure* structure, JSMap* iteratedObject, MapIterationKind kind)
+ static JSMapIterator* create(VM& vm, Structure* structure, JSMap* iteratedObject, IterationKind kind)
{
JSMapIterator* instance = new (NotNull, allocateCell<JSMapIterator>(vm.heap)) JSMapIterator(vm, structure, iteratedObject, kind);
instance->finishCreation(vm, iteratedObject);
return instance;
}
- bool next(CallFrame* callFrame, JSValue& value)
+ ALWAYS_INLINE HashMapBucketType* advanceIter(ExecState* exec)
+ {
+ HashMapBucketType* prev = m_iter.get();
+ if (!prev)
+ return nullptr;
+ HashMapBucketType* bucket = m_iter->next();
+ while (bucket && bucket->deleted())
+ bucket = bucket->next();
+ if (!bucket) {
+ setIterator(exec->vm(), nullptr);
+ return nullptr;
+ }
+ setIterator(exec->vm(), bucket); // We keep m_iter on the last value since the first thing we do in this function is call next().
+ return bucket;
+ }
+ bool next(ExecState* exec, JSValue& value)
{
- if (!m_iterator.ensureSlot())
+ HashMapBucketType* bucket = advanceIter(exec);
+ if (!bucket)
return false;
- if (m_kind == MapIterateValue)
- value = m_iterator.value();
- else if (m_kind == MapIterateKey)
- value = m_iterator.key();
+ if (m_kind == IterateValue)
+ value = bucket->value();
+ else if (m_kind == IterateKey)
+ value = bucket->key();
else
- value = createPair(callFrame, m_iterator.key(), m_iterator.value());
- ++m_iterator;
+ value = createPair(exec, bucket->key(), bucket->value());
return true;
}
- void finish()
+ bool nextKeyValue(ExecState* exec, JSValue& key, JSValue& value)
{
- m_iterator.finish();
- }
+ HashMapBucketType* bucket = advanceIter(exec);
+ if (!bucket)
+ return false;
-private:
+ key = bucket->key();
+ value = bucket->value();
+ return true;
+ }
- static const unsigned StructureFlags = Base::StructureFlags | OverridesVisitChildren;
+ IterationKind kind() const { return m_kind; }
+ JSValue iteratedValue() const { return m_map.get(); }
+ JSMapIterator* clone(ExecState*);
- JSMapIterator(VM& vm, Structure* structure, JSMap* iteratedObject, MapIterationKind kind)
+private:
+ JSMapIterator(VM& vm, Structure* structure, JSMap*, IterationKind kind)
: Base(vm, structure)
- , m_iterator(iteratedObject->mapData()->begin())
, m_kind(kind)
+ { }
+
+ void setIterator(VM& vm, HashMapBucketType* bucket)
{
+ m_iter.setMayBeNull(vm, this, bucket);
}
- void finishCreation(VM&, JSMap*);
+ JS_EXPORT_PRIVATE void finishCreation(VM&, JSMap*);
JSValue createPair(CallFrame*, JSValue, JSValue);
static void visitChildren(JSCell*, SlotVisitor&);
- WriteBarrier<MapData> m_iteratedObjectData;
- MapData::const_iterator m_iterator;
- MapIterationKind m_kind;
+ WriteBarrier<JSMap> m_map;
+ WriteBarrier<HashMapBucketType> m_iter;
+ IterationKind m_kind;
};
+STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(JSMapIterator);
-}
-
-#endif // !defined(JSMapIterator_h)
+} // namespace JSC