- public:
- typedef Map::iterator iterator;
- typedef Map::const_iterator const_iterator;
- typedef Map::AddResult AddResult;
-
- SparseArrayValueMap()
- : m_flags(Normal)
- , m_reportedCapacity(0)
- {
- }
-
- void visitChildren(SlotVisitor&);
-
- bool sparseMode()
- {
- return m_flags & SparseMode;
- }
-
- void setSparseMode()
- {
- m_flags = static_cast<Flags>(m_flags | SparseMode);
- }
-
- bool lengthIsReadOnly()
- {
- return m_flags & LengthIsReadOnly;
- }
-
- void setLengthIsReadOnly()
- {
- m_flags = static_cast<Flags>(m_flags | LengthIsReadOnly);
- }
-
- // These methods may mutate the contents of the map
- void put(ExecState*, JSArray*, unsigned, JSValue, bool shouldThrow);
- bool putDirect(ExecState*, JSArray*, unsigned, JSValue, bool shouldThrow);
- AddResult add(JSArray*, unsigned);
- iterator find(unsigned i) { return m_map.find(i); }
- // This should ASSERT the remove is valid (check the result of the find).
- void remove(iterator it) { m_map.remove(it); }
- void remove(unsigned i) { m_map.remove(i); }
-
- // These methods do not mutate the contents of the map.
- iterator notFound() { return m_map.end(); }
- bool isEmpty() const { return m_map.isEmpty(); }
- bool contains(unsigned i) const { return m_map.contains(i); }
- size_t size() const { return m_map.size(); }
- // Only allow const begin/end iteration.
- const_iterator begin() const { return m_map.begin(); }
- const_iterator end() const { return m_map.end(); }
-
- private:
- Map m_map;
- Flags m_flags;
- size_t m_reportedCapacity;
- };
-
- // This struct holds the actual data values of an array. A JSArray object points to it's contained ArrayStorage
- // struct by pointing to m_vector. To access the contained ArrayStorage struct, use the getStorage() and
- // setStorage() methods. It is important to note that there may be space before the ArrayStorage that
- // is used to quick unshift / shift operation. The actual allocated pointer is available by using:
- // getStorage() - m_indexBias * sizeof(JSValue)
- struct ArrayStorage {
- unsigned m_length; // The "length" property on the array
- unsigned m_numValuesInVector;
- void* m_allocBase; // Pointer to base address returned by malloc(). Keeping this pointer does eliminate false positives from the leak detector.
-#if CHECK_ARRAY_CONSISTENCY
- // Needs to be a uintptr_t for alignment purposes.
- uintptr_t m_initializationIndex;
- uintptr_t m_inCompactInitialization;
-#else
- uintptr_t m_padding;
-#endif
- WriteBarrier<Unknown> m_vector[1];
-
- static ptrdiff_t lengthOffset() { return OBJECT_OFFSETOF(ArrayStorage, m_length); }
- static ptrdiff_t numValuesInVectorOffset() { return OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector); }
- static ptrdiff_t allocBaseOffset() { return OBJECT_OFFSETOF(ArrayStorage, m_allocBase); }
- static ptrdiff_t vectorOffset() { return OBJECT_OFFSETOF(ArrayStorage, m_vector); }
- };
-
- class JSArray : public JSNonFinalObject {
- friend class LLIntOffsetsExtractor;
- friend class Walker;
- friend class JIT;
-
- protected:
- explicit JSArray(JSGlobalData& globalData, Structure* structure)
- : JSNonFinalObject(globalData, structure)
- , m_indexBias(0)
- , m_storage(0)
- , m_sparseValueMap(0)
- {
- }
-
- JS_EXPORT_PRIVATE void finishCreation(JSGlobalData&, unsigned initialLength = 0);
- JS_EXPORT_PRIVATE JSArray* tryFinishCreationUninitialized(JSGlobalData&, unsigned initialLength);
-
- public:
- typedef JSNonFinalObject Base;
-
- static void finalize(JSCell*);
-
- static JSArray* create(JSGlobalData&, Structure*, unsigned initialLength = 0);
-
- // tryCreateUninitialized is used for fast construction of arrays whose size and
- // contents are known at time of creation. Clients of this interface must:
- // - null-check the result (indicating out of memory, or otherwise unable to allocate vector).
- // - call 'initializeIndex' for all properties in sequence, for 0 <= i < initialLength.
- // - called 'completeInitialization' after all properties have been initialized.
- static JSArray* tryCreateUninitialized(JSGlobalData&, Structure*, unsigned initialLength);
-
- JS_EXPORT_PRIVATE static bool defineOwnProperty(JSObject*, ExecState*, const Identifier&, PropertyDescriptor&, bool throwException);
-
- static bool getOwnPropertySlot(JSCell*, ExecState*, const Identifier&, PropertySlot&);
- JS_EXPORT_PRIVATE static bool getOwnPropertySlotByIndex(JSCell*, ExecState*, unsigned propertyName, PropertySlot&);
- static bool getOwnPropertyDescriptor(JSObject*, ExecState*, const Identifier&, PropertyDescriptor&);
- static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
- // This is similar to the JSObject::putDirect* methods:
- // - the prototype chain is not consulted
- // - accessors are not called.
- // This method creates a property with attributes writable, enumerable and configurable all set to true.
- bool putDirectIndex(ExecState* exec, unsigned propertyName, JSValue value, bool shouldThrow = true)
- {
- if (canSetIndex(propertyName)) {
- setIndex(exec->globalData(), propertyName, value);
- return true;
- }
- return putDirectIndexBeyondVectorLength(exec, propertyName, value, shouldThrow);
- }
-
- static JS_EXPORTDATA const ClassInfo s_info;