| /* | 
 |  * Copyright (C) 2012, 2014 Apple Inc. All rights reserved. | 
 |  * | 
 |  * Redistribution and use in source and binary forms, with or without | 
 |  * modification, are permitted provided that the following conditions | 
 |  * are met: | 
 |  * 1. Redistributions of source code must retain the above copyright | 
 |  *    notice, this list of conditions and the following disclaimer. | 
 |  * 2. Redistributions in binary form must reproduce the above copyright | 
 |  *    notice, this list of conditions and the following disclaimer in the | 
 |  *    documentation and/or other materials provided with the distribution. | 
 |  * | 
 |  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY | 
 |  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 
 |  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 
 |  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR | 
 |  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | 
 |  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | 
 |  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | 
 |  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | 
 |  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 
 |  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 
 |  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  | 
 |  */ | 
 |  | 
 | #pragma once | 
 |  | 
 | #include "PropertyStorage.h" | 
 |  | 
 | namespace JSC { | 
 |  | 
 | class ArrayBuffer; | 
 | class Butterfly; | 
 | class LLIntOffsetsExtractor; | 
 | class Structure; | 
 | struct ArrayStorage; | 
 |  | 
 | class IndexingHeader { | 
 | public: | 
 |     // Define the maximum storage vector length to be 2^32 / sizeof(JSValue) / 2 to ensure that | 
 |     // there is no risk of overflow. | 
 |     enum { maximumLength = 0x10000000 }; | 
 |      | 
 |     static ptrdiff_t offsetOfIndexingHeader() { return -static_cast<ptrdiff_t>(sizeof(IndexingHeader)); } | 
 |      | 
 |     static ptrdiff_t offsetOfArrayBuffer() { return OBJECT_OFFSETOF(IndexingHeader, u.typedArray.buffer); } | 
 |     static ptrdiff_t offsetOfPublicLength() { return OBJECT_OFFSETOF(IndexingHeader, u.lengths.publicLength); } | 
 |     static ptrdiff_t offsetOfVectorLength() { return OBJECT_OFFSETOF(IndexingHeader, u.lengths.vectorLength); } | 
 |      | 
 |     IndexingHeader() | 
 |     { | 
 |         u.lengths.publicLength = 0; | 
 |         u.lengths.vectorLength = 0; | 
 |     } | 
 |      | 
 |     uint32_t vectorLength() const { return u.lengths.vectorLength; } | 
 |      | 
 |     void setVectorLength(uint32_t length) | 
 |     { | 
 |         RELEASE_ASSERT(length <= maximumLength); | 
 |         u.lengths.vectorLength = length; | 
 |     } | 
 |      | 
 |     uint32_t publicLength() const { return u.lengths.publicLength; } | 
 |     void setPublicLength(uint32_t auxWord) { u.lengths.publicLength = auxWord; } | 
 |      | 
 |     ArrayBuffer* arrayBuffer() { return u.typedArray.buffer; } | 
 |     void setArrayBuffer(ArrayBuffer* buffer) { u.typedArray.buffer = buffer; } | 
 |      | 
 |     static IndexingHeader* from(Butterfly* butterfly) | 
 |     { | 
 |         return reinterpret_cast<IndexingHeader*>(butterfly) - 1; | 
 |     } | 
 |      | 
 |     static const IndexingHeader* from(const Butterfly* butterfly) | 
 |     { | 
 |         return reinterpret_cast<const IndexingHeader*>(butterfly) - 1; | 
 |     } | 
 |      | 
 |     static IndexingHeader* from(ArrayStorage* arrayStorage) | 
 |     { | 
 |         return const_cast<IndexingHeader*>(from(const_cast<const ArrayStorage*>(arrayStorage))); | 
 |     } | 
 |      | 
 |     static const IndexingHeader* from(const ArrayStorage* arrayStorage) | 
 |     { | 
 |         return reinterpret_cast<const IndexingHeader*>(arrayStorage) - 1; | 
 |     } | 
 |      | 
 |     static IndexingHeader* fromEndOf(PropertyStorage propertyStorage) | 
 |     { | 
 |         return reinterpret_cast<IndexingHeader*>(propertyStorage); | 
 |     } | 
 |      | 
 |     PropertyStorage propertyStorage() | 
 |     { | 
 |         return reinterpret_cast_ptr<PropertyStorage>(this); | 
 |     } | 
 |      | 
 |     ConstPropertyStorage propertyStorage() const | 
 |     { | 
 |         return reinterpret_cast_ptr<ConstPropertyStorage>(this); | 
 |     } | 
 |      | 
 |     ArrayStorage* arrayStorage() | 
 |     { | 
 |         return reinterpret_cast<ArrayStorage*>(this + 1); | 
 |     } | 
 |      | 
 |     Butterfly* butterfly() | 
 |     { | 
 |         return reinterpret_cast<Butterfly*>(this + 1); | 
 |     } | 
 |      | 
 |     // These methods are not standalone in the sense that they cannot be | 
 |     // used on a copy of the IndexingHeader. | 
 |     size_t preCapacity(Structure*); | 
 |     size_t indexingPayloadSizeInBytes(Structure*); | 
 |      | 
 | private: | 
 |     friend class LLIntOffsetsExtractor; | 
 |  | 
 |     union { | 
 |         struct { | 
 |             uint32_t publicLength; // The meaning of this field depends on the array type, but for all JSArrays we rely on this being the publicly visible length (array.length). | 
 |             uint32_t vectorLength; // The length of the indexed property storage. The actual size of the storage depends on this, and the type. | 
 |         } lengths; | 
 |          | 
 |         struct { | 
 |             ArrayBuffer* buffer; | 
 |         } typedArray; | 
 |     } u; | 
 | }; | 
 |  | 
 | } // namespace JSC |