| /* |
| * 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 { |
| // FIXME: vectorLength should be least significant, so that it's really hard to craft a pointer by |
| // mucking with the butterfly. |
| // https://bugs.webkit.org/show_bug.cgi?id=174927 |
| 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 |