2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2014 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_APC_LOCAL_ARRAY_H_
17 #define incl_HPHP_APC_LOCAL_ARRAY_H_
22 #include <sys/types.h>
24 #include "hphp/runtime/base/array-data.h"
25 #include "hphp/runtime/base/sweepable.h"
26 #include "hphp/runtime/base/apc-array.h"
27 #include "hphp/runtime/base/memory-manager.h"
31 //////////////////////////////////////////////////////////////////////
38 //////////////////////////////////////////////////////////////////////
41 * Wrapper for APCArray. It is what gets returned when an array is fetched
42 * via APC. It has a pointer to the APCArray that it represents and it may
43 * cache values locally depending on the type accessed and/or the operation.
45 struct APCLocalArray
: ArrayData
, private Sweepable
{
46 template<class... Args
>
47 static APCLocalArray
* Make(Args
&&... args
) {
48 return new (MM().smartMallocSize(sizeof(APCLocalArray
)))
49 APCLocalArray(std::forward
<Args
>(args
)...);
52 static APCHandle
* GetAPCHandle(const ArrayData
* ad
);
53 static size_t Vsize(const ArrayData
*);
54 static const Variant
& GetValueRef(const ArrayData
* ad
, ssize_t pos
);
55 static bool ExistsInt(const ArrayData
* ad
, int64_t k
);
56 static bool ExistsStr(const ArrayData
* ad
, const StringData
* k
);
57 static ArrayData
* LvalInt(ArrayData
*, int64_t k
, Variant
*&ret
,
59 static ArrayData
* LvalStr(ArrayData
*, StringData
* k
, Variant
*&ret
,
61 static ArrayData
* LvalNew(ArrayData
*, Variant
*&ret
, bool copy
);
63 static ArrayData
* SetInt(ArrayData
*, int64_t k
, const Variant
& v
, bool copy
);
64 static ArrayData
* SetStr(ArrayData
*, StringData
* k
, const Variant
& v
,
66 static ArrayData
* SetRefInt(ArrayData
*, int64_t k
, Variant
& v
, bool copy
);
67 static ArrayData
* SetRefStr(ArrayData
*, StringData
* k
, Variant
& v
,
69 static constexpr auto AddInt
= &SetInt
;
70 static constexpr auto AddStr
= &SetStr
;
71 static ArrayData
*RemoveInt(ArrayData
* ad
, int64_t k
, bool copy
);
72 static ArrayData
*RemoveStr(ArrayData
* ad
, const StringData
* k
, bool copy
);
73 static ArrayData
* Copy(const ArrayData
*);
74 static ArrayData
* CopyWithStrongIterators(const ArrayData
*);
75 static ArrayData
* Append(ArrayData
* a
, const Variant
& v
, bool copy
);
76 static ArrayData
* AppendRef(ArrayData
*, Variant
& v
, bool copy
);
77 static ArrayData
* AppendWithRef(ArrayData
*, const Variant
& v
, bool copy
);
78 static ArrayData
* PlusEq(ArrayData
*, const ArrayData
*elems
);
79 static ArrayData
* Merge(ArrayData
*, const ArrayData
*elems
);
80 static ArrayData
* Prepend(ArrayData
*, const Variant
& v
, bool copy
);
81 static const TypedValue
* NvGetInt(const ArrayData
*, int64_t k
);
82 static const TypedValue
* NvGetStr(const ArrayData
*, const StringData
* k
);
83 static void NvGetKey(const ArrayData
*, TypedValue
* out
, ssize_t pos
);
84 static bool IsVectorData(const ArrayData
* ad
);
85 static ssize_t
IterBegin(const ArrayData
*);
86 static ssize_t
IterEnd(const ArrayData
*);
87 static ssize_t
IterAdvance(const ArrayData
*, ssize_t prev
);
88 static ssize_t
IterRewind(const ArrayData
*, ssize_t prev
);
89 static bool ValidMArrayIter(const ArrayData
*, const MArrayIter
& fp
);
90 static bool AdvanceMArrayIter(ArrayData
*, MArrayIter
& fp
);
91 static ArrayData
* NonSmartCopy(const ArrayData
*);
92 static constexpr auto Pop
= &ArrayCommon::Pop
;
93 static constexpr auto Dequeue
= &ArrayCommon::Dequeue
;
94 static void Renumber(ArrayData
*);
95 static void OnSetEvalScalar(ArrayData
*);
96 static void Release(ArrayData
*);
97 static ArrayData
* Escalate(const ArrayData
*);
98 static ArrayData
* EscalateForSort(ArrayData
*);
99 static void Ksort(ArrayData
*, int, bool);
100 static void Sort(ArrayData
*, int, bool);
101 static void Asort(ArrayData
*, int, bool);
102 static bool Uksort(ArrayData
*, const Variant
&);
103 static bool Usort(ArrayData
*, const Variant
&);
104 static bool Uasort(ArrayData
*, const Variant
&);
106 public: // implements Sweepable
107 void sweep() override
;
110 ssize_t
iterAdvanceImpl(ssize_t prev
) const {
111 assert(prev
>= 0 && prev
< m_size
);
112 ssize_t next
= prev
+ 1;
113 return next
< m_size
? next
: invalid_index
;
117 explicit APCLocalArray(APCArray
* source
)
118 : ArrayData(kSharedKind
)
120 , m_localCache(nullptr)
122 m_size
= m_arr
->size();
123 source
->getHandle()->reference();
129 static bool checkInvariants(const ArrayData
*);
130 ssize_t
getIndex(int64_t k
) const;
131 ssize_t
getIndex(const StringData
* k
) const;
132 static APCLocalArray
* asSharedArray(ArrayData
*);
133 static const APCLocalArray
* asSharedArray(const ArrayData
*);
136 ArrayData
* loadElems() const;
137 Variant
getKey(ssize_t pos
) const {
138 return m_arr
->getKey(pos
);
143 mutable TypedValue
* m_localCache
;
146 //////////////////////////////////////////////////////////////////////