1/* 2 * Copyright (C) 2012 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#ifndef IndexingHeader_h 27#define IndexingHeader_h 28 29#include "PropertyStorage.h" 30 31namespace JSC { 32 33class ArrayBuffer; 34class Butterfly; 35class LLIntOffsetsExtractor; 36class Structure; 37struct ArrayStorage; 38 39class IndexingHeader { 40public: 41 // Define the maximum storage vector length to be 2^32 / sizeof(JSValue) / 2 to ensure that 42 // there is no risk of overflow. 43 enum { maximumLength = 0x10000000 }; 44 45 static ptrdiff_t offsetOfIndexingHeader() { return -static_cast<ptrdiff_t>(sizeof(IndexingHeader)); } 46 47 static ptrdiff_t offsetOfArrayBuffer() { return OBJECT_OFFSETOF(IndexingHeader, u.typedArray.buffer); } 48 static ptrdiff_t offsetOfPublicLength() { return OBJECT_OFFSETOF(IndexingHeader, u.lengths.publicLength); } 49 static ptrdiff_t offsetOfVectorLength() { return OBJECT_OFFSETOF(IndexingHeader, u.lengths.vectorLength); } 50 51 IndexingHeader() 52 { 53 u.lengths.publicLength = 0; 54 u.lengths.vectorLength = 0; 55 } 56 57 uint32_t vectorLength() const { return u.lengths.vectorLength; } 58 59 void setVectorLength(uint32_t length) 60 { 61 RELEASE_ASSERT(length <= maximumLength); 62 u.lengths.vectorLength = length; 63 } 64 65 uint32_t publicLength() const { return u.lengths.publicLength; } 66 void setPublicLength(uint32_t auxWord) { u.lengths.publicLength = auxWord; } 67 68 ArrayBuffer* arrayBuffer() { return u.typedArray.buffer; } 69 void setArrayBuffer(ArrayBuffer* buffer) { u.typedArray.buffer = buffer; } 70 71 static IndexingHeader* from(Butterfly* butterfly) 72 { 73 return reinterpret_cast<IndexingHeader*>(butterfly) - 1; 74 } 75 76 static const IndexingHeader* from(const Butterfly* butterfly) 77 { 78 return reinterpret_cast<const IndexingHeader*>(butterfly) - 1; 79 } 80 81 static IndexingHeader* from(ArrayStorage* arrayStorage) 82 { 83 return const_cast<IndexingHeader*>(from(const_cast<const ArrayStorage*>(arrayStorage))); 84 } 85 86 static const IndexingHeader* from(const ArrayStorage* arrayStorage) 87 { 88 return reinterpret_cast<const IndexingHeader*>(arrayStorage) - 1; 89 } 90 91 static IndexingHeader* fromEndOf(PropertyStorage propertyStorage) 92 { 93 return reinterpret_cast<IndexingHeader*>(propertyStorage); 94 } 95 96 PropertyStorage propertyStorage() 97 { 98 return reinterpret_cast_ptr<PropertyStorage>(this); 99 } 100 101 ConstPropertyStorage propertyStorage() const 102 { 103 return reinterpret_cast_ptr<ConstPropertyStorage>(this); 104 } 105 106 ArrayStorage* arrayStorage() 107 { 108 return reinterpret_cast<ArrayStorage*>(this + 1); 109 } 110 111 Butterfly* butterfly() 112 { 113 return reinterpret_cast<Butterfly*>(this + 1); 114 } 115 116 // These methods are not standalone in the sense that they cannot be 117 // used on a copy of the IndexingHeader. 118 size_t preCapacity(Structure*); 119 size_t indexingPayloadSizeInBytes(Structure*); 120 121private: 122 friend class LLIntOffsetsExtractor; 123 124 union { 125 struct { 126 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). 127 uint32_t vectorLength; // The length of the indexed property storage. The actual size of the storage depends on this, and the type. 128 } lengths; 129 130 struct { 131 ArrayBuffer* buffer; 132 } typedArray; 133 } u; 134}; 135 136} // namespace JSC 137 138#endif // IndexingHeader_h 139 140