2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2016 Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
16 #ifndef incl_HPHP_STRUCT_ARRAY_H_
17 #define incl_HPHP_STRUCT_ARRAY_H_
21 #include <sys/types.h>
23 #include "hphp/runtime/base/array-data.h"
24 #include "hphp/runtime/base/typed-value.h"
25 #include "hphp/runtime/base/array-common.h"
29 //////////////////////////////////////////////////////////////////////
39 //////////////////////////////////////////////////////////////////////
42 * Struct arrays are a specialized array layout for record-like data.
43 * That is, php arrays with static string keys and values of mixed types.
45 * Currently the layout of this array kind is set up to match MixedArray,
46 * with some of the fields uninitialized to make the code path that
47 * transitions from struct to mixed cheaper. See MixedArray::checkInvariants
50 struct StructArray
: public ArrayData
{
51 static ArrayData
* MakeUncounted(ArrayData
*);
52 static void Release(ArrayData
*);
53 static void ReleaseUncounted(ArrayData
*);
54 static const TypedValue
* NvGetInt(const ArrayData
*, int64_t ki
);
55 static const TypedValue
* NvGetStr(const ArrayData
*, const StringData
*);
56 static void NvGetKey(const ArrayData
*, TypedValue
* out
, ssize_t pos
);
57 static ArrayData
* SetInt(ArrayData
*, int64_t k
, Cell v
, bool copy
);
58 static ArrayData
* SetStr(ArrayData
*, StringData
* k
, Cell v
, bool copy
);
59 static size_t Vsize(const ArrayData
*);
60 static const Variant
& GetValueRef(const ArrayData
* ad
, ssize_t pos
);
61 static bool IsVectorData(const ArrayData
*);
62 static bool ExistsInt(const ArrayData
* ad
, int64_t k
);
63 static bool ExistsStr(const ArrayData
*, const StringData
*);
64 static ArrayData
* LvalInt(ArrayData
*, int64_t k
, Variant
*& ret
, bool copy
);
65 static ArrayData
* LvalStr(ArrayData
*, StringData
* k
, Variant
*& ret
,
67 static ArrayData
* LvalNew(ArrayData
*, Variant
*& ret
, bool copy
);
68 static ArrayData
* SetRefInt(ArrayData
*, int64_t k
, Variant
& v
, bool copy
);
69 static ArrayData
* SetRefStr(ArrayData
*, StringData
* k
, Variant
& v
,
71 static constexpr auto AddInt
= &SetInt
;
72 static constexpr auto AddStr
= &SetStr
;
73 static ArrayData
* RemoveInt(ArrayData
*, int64_t k
, bool copy
);
74 static ArrayData
* RemoveStr(ArrayData
*, const StringData
* k
, bool copy
);
75 static ssize_t
IterBegin(const ArrayData
*);
76 static ssize_t
IterLast(const ArrayData
*);
77 static ssize_t
IterEnd(const ArrayData
*);
78 static ssize_t
IterAdvance(const ArrayData
*, ssize_t pos
);
79 static ssize_t
IterRewind(const ArrayData
*, ssize_t pos
);
80 static constexpr auto ValidMArrayIter
= &ArrayCommon::ValidMArrayIter
;
81 static bool AdvanceMArrayIter(ArrayData
*, MArrayIter
& fp
);
82 static ArrayData
* Copy(const ArrayData
* ad
);
83 static ArrayData
* CopyWithStrongIterators(const ArrayData
*);
84 static ArrayData
* CopyStatic(const ArrayData
*);
85 static ArrayData
* EscalateForSort(ArrayData
*, SortFunction
);
86 static void Ksort(ArrayData
*, int, bool);
87 static void Sort(ArrayData
*, int, bool);
88 static void Asort(ArrayData
*, int, bool);
89 static bool Uksort(ArrayData
*, const Variant
&);
90 static bool Usort(ArrayData
*, const Variant
&);
91 static bool Uasort(ArrayData
*, const Variant
&);
92 static ArrayData
* ZSetInt(ArrayData
*, int64_t k
, RefData
* v
);
93 static ArrayData
* ZSetStr(ArrayData
*, StringData
* k
, RefData
* v
);
94 static ArrayData
* ZAppend(ArrayData
*, RefData
* v
, int64_t* key_ptr
);
95 static ArrayData
* Append(ArrayData
*, const Variant
& v
, bool copy
);
96 static ArrayData
* AppendRef(ArrayData
*, Variant
& v
, bool copy
);
97 static ArrayData
* AppendWithRef(ArrayData
*, const Variant
& v
, bool copy
);
98 static ArrayData
* PlusEq(ArrayData
*, const ArrayData
* elems
);
99 static ArrayData
* Merge(ArrayData
*, const ArrayData
* elems
);
100 static ArrayData
* Pop(ArrayData
*, Variant
& value
);
101 static ArrayData
* Dequeue(ArrayData
*, Variant
& value
);
102 static ArrayData
* Prepend(ArrayData
*, const Variant
& v
, bool copy
);
103 static void Renumber(ArrayData
*);
104 static void OnSetEvalScalar(ArrayData
*);
105 static ArrayData
* Escalate(const ArrayData
* ad
);
107 //////////////////////////////////////////////////////////////////////
109 ArrayData
* asArrayData() { return this; }
110 const ArrayData
* asArrayData() const { return this; }
111 static bool checkInvariants(const ArrayData
*);
113 static StructArray
* asStructArray(ArrayData
*);
114 static const StructArray
* asStructArray(const ArrayData
*);
116 static StructArray
* create(Shape
*, const TypedValue
*, size_t);
117 static StructArray
* createReversedValues(Shape
* shape
,
118 const TypedValue
* values
, size_t length
);
119 static StructArray
* createNoCopy(Shape
*, size_t);
120 static StructArray
* createStatic(Shape
*, size_t);
121 static StructArray
* createUncounted(Shape
*, size_t);
122 static size_t bytesForCapacity(size_t capacity
);
125 Shape
* shape() const;
126 void setShape(Shape
*);
128 const TypedValue
* data() const;
130 size_t capacity() const;
131 static size_t heapSize(const ArrayData
*);
133 MixedArray
* toMixedArray();
135 static const uint32_t MaxMakeSize
= 64;
137 static constexpr ptrdiff_t dataOffset() {
138 return sizeof(StructArray
);
141 static constexpr ptrdiff_t shapeOffset() {
142 return offsetof(StructArray
, m_shape
);
145 template<class F
> void scan(F
&) const;
148 StructArray(uint32_t size
, uint32_t pos
, Shape
* shape
, RefCount
= 1);
150 static MixedArray
* ToMixedHeader(size_t);
151 static MixedArray
* ToMixed(StructArray
*);
152 static MixedArray
* ToMixedCopy(const StructArray
*);
153 static MixedArray
* ToMixedCopyReserve(const StructArray
*, size_t);
155 static StructArray
* Grow(StructArray
*, Shape
*);
157 static StructArray
* CopyAndResizeIfNeeded(const StructArray
*, Shape
*);
158 static StructArray
* ResizeIfNeeded(StructArray
*, Shape
*);
163 inline size_t StructArray::bytesForCapacity(size_t capacity
) {
164 return sizeof(StructArray
) + sizeof(TypedValue
) * capacity
;