2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present 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_RUNTIME_VM_GLOBALS_ARRAY_H
17 #define incl_HPHP_RUNTIME_VM_GLOBALS_ARRAY_H
19 #include "hphp/runtime/base/array-common.h"
20 #include "hphp/runtime/base/array-data.h"
21 #include "hphp/runtime/base/member-val.h"
22 #include "hphp/runtime/vm/name-value-table.h"
26 //////////////////////////////////////////////////////////////////////
29 * Wrapper to provide a KindOfArray interface to a NameValueTable. This is
30 * used to expose a NameValueTable to php code, particularly for $GLOBALS, but
31 * also for some internal generated-bytecode initialization routines (86pinit,
34 * Some differences compared to normal php arrays:
36 * - Does not behave as if it has value semantics (i.e., no COW).
38 * - Iteration order is not specified.
40 * - Non-string keys are not really supported. (Integers are converted to
43 * - size() is an O(N) operation. (This is because of kNamedLocalDataType
44 * support in the underlying NameValueTable.)
46 * - Append/prepend operations are not supported.
48 * - Strong iterators "past the end" are not updated when new elements are
49 * added. (Since iteration order is unspecified, this semantic would seem
52 * This holds a pointer to a NameValueTable whose lifetime must be guaranteed
53 * to outlast the lifetime of the GlobalsArray. (The wrapper is
54 * refcounted, as required by ArrayData, but the table pointed to is not.)
56 struct GlobalsArray final
: ArrayData
,
57 type_scan::MarkCollectable
<GlobalsArray
> {
58 explicit GlobalsArray(NameValueTable
* tab
);
59 ~GlobalsArray() = delete;
61 // We only allow explicit conversions to ArrayData. Generally you
62 // should not be talking to the GlobalsArray directly (see
64 ArrayData
* asArrayData() { return this; }
65 const ArrayData
* asArrayData() const { return this; }
68 static void Release(ArrayData
*) {}
69 static ArrayData
* Copy(const ArrayData
* ad
) {
70 return const_cast<ArrayData
*>(ad
);
72 static size_t Vsize(const ArrayData
*);
73 static Cell
NvGetKey(const ArrayData
* ad
, ssize_t pos
);
74 static member_rval::ptr_u
GetValueRef(const ArrayData
*, ssize_t pos
);
76 static bool ExistsInt(const ArrayData
* ad
, int64_t k
);
77 static bool ExistsStr(const ArrayData
* ad
, const StringData
* k
);
79 static member_rval::ptr_u
NvGetInt(const ArrayData
*, int64_t k
);
80 static constexpr auto NvTryGetInt
= &NvGetInt
;
81 static member_rval::ptr_u
NvGetStr(const ArrayData
*, const StringData
* k
);
82 static constexpr auto NvTryGetStr
= &NvGetStr
;
84 static member_lval
LvalInt(ArrayData
*, int64_t k
, bool copy
);
85 static constexpr auto LvalIntRef
= &LvalInt
;
86 static member_lval
LvalStr(ArrayData
*, StringData
* k
, bool copy
);
87 static constexpr auto LvalStrRef
= &LvalStr
;
88 static member_lval
LvalNew(ArrayData
*, bool copy
);
89 static constexpr auto LvalNewRef
= &LvalNew
;
91 static ArrayData
* SetInt(ArrayData
*, int64_t k
, Cell v
, bool copy
);
92 static ArrayData
* SetStr(ArrayData
*, StringData
* k
, Cell v
, bool copy
);
93 static ArrayData
* SetWithRefInt(ArrayData
*, int64_t k
,
94 TypedValue v
, bool copy
);
95 static ArrayData
* SetWithRefStr(ArrayData
*, StringData
* k
,
96 TypedValue v
, bool copy
);
97 static ArrayData
* SetRefInt(ArrayData
*, int64_t k
, Variant
& v
, bool copy
);
98 static ArrayData
* SetRefStr(ArrayData
*, StringData
* k
, Variant
& v
,
100 static constexpr auto AddInt
= &SetInt
;
101 static constexpr auto AddStr
= &SetStr
;
102 static ArrayData
* RemoveInt(ArrayData
*, int64_t k
, bool copy
);
103 static ArrayData
* RemoveStr(ArrayData
*, const StringData
* k
, bool copy
);
105 static ArrayData
* Append(ArrayData
*, Cell v
, bool copy
);
106 static ArrayData
* AppendRef(ArrayData
*, Variant
& v
, bool copy
);
107 static ArrayData
* AppendWithRef(ArrayData
*, TypedValue v
, bool copy
);
109 static ArrayData
* PlusEq(ArrayData
*, const ArrayData
* elems
);
110 static ArrayData
* Merge(ArrayData
*, const ArrayData
* elems
);
111 static ArrayData
* Prepend(ArrayData
*, Cell v
, bool copy
);
113 static ssize_t
IterBegin(const ArrayData
*);
114 static ssize_t
IterLast(const ArrayData
*);
115 static ssize_t
IterEnd(const ArrayData
*);
116 static ssize_t
IterAdvance(const ArrayData
*, ssize_t prev
);
117 static ssize_t
IterRewind(const ArrayData
*, ssize_t prev
);
119 static bool ValidMArrayIter(const ArrayData
*, const MArrayIter
& fp
);
120 static bool AdvanceMArrayIter(ArrayData
*, MArrayIter
&);
121 static bool IsVectorData(const ArrayData
*);
122 static ArrayData
* CopyStatic(const ArrayData
*);
123 static constexpr auto Pop
= &ArrayCommon::Pop
;
124 static constexpr auto Dequeue
= &ArrayCommon::Dequeue
;
125 static void Renumber(ArrayData
*);
126 static void OnSetEvalScalar(ArrayData
*);
128 static ArrayData
* EscalateForSort(ArrayData
*, SortFunction sf
);
129 static void Ksort(ArrayData
*, int sort_flags
, bool ascending
);
130 static void Sort(ArrayData
*, int sort_flags
, bool ascending
);
131 static void Asort(ArrayData
*, int sort_flags
, bool ascending
);
132 static bool Uksort(ArrayData
*, const Variant
& cmp_function
);
133 static bool Usort(ArrayData
*, const Variant
& cmp_function
);
134 static bool Uasort(ArrayData
*, const Variant
& cmp_function
);
136 static ArrayData
* Escalate(const ArrayData
* ad
) {
137 return const_cast<ArrayData
*>(ad
);
140 static ArrayData
* ToPHPArray(ArrayData
* ad
, bool) {
143 static constexpr auto ToVec
= &ArrayCommon::ToVec
;
144 static constexpr auto ToDict
= &ArrayCommon::ToDict
;
145 static constexpr auto ToKeyset
= &ArrayCommon::ToKeyset
;
146 static constexpr auto ToVArray
= &ArrayCommon::ToVArray
;
147 static constexpr auto ToDArray
= &ArrayCommon::ToDArray
;
150 static GlobalsArray
* asGlobals(ArrayData
* ad
);
151 static const GlobalsArray
* asGlobals(const ArrayData
* ad
);
154 void scan(type_scan::Scanner
& scanner
) const {
159 NameValueTable
* const m_tab
;
162 //////////////////////////////////////////////////////////////////////
165 * Gets our request-local global variables array.
167 GlobalsArray
* get_global_variables();