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_RUNTIME_VM_GLOBALS_ARRAY_H
17 #define incl_HPHP_RUNTIME_VM_GLOBALS_ARRAY_H
19 #include "hphp/runtime/vm/name-value-table.h"
20 #include "hphp/runtime/base/array-data.h"
21 #include "hphp/runtime/base/array-common.h"
25 //////////////////////////////////////////////////////////////////////
28 * Wrapper to provide a KindOfArray interface to a NameValueTable. This is
29 * used to expose a NameValueTable to php code, particularly for $GLOBALS, but
30 * also for some internal generated-bytecode initialization routines (86pinit,
33 * Some differences compared to normal php arrays:
35 * - Does not behave as if it has value semantics (i.e., no COW).
37 * - Iteration order is not specified.
39 * - Non-string keys are not really supported. (Integers are converted to
42 * - size() is an O(N) operation. (This is because of kNamedLocalDataType
43 * support in the underlying NameValueTable.)
45 * - Append/prepend operations are not supported.
47 * - Strong iterators "past the end" are not updated when new elements are
48 * added. (Since iteration order is unspecified, this semantic would seem
51 * This holds a pointer to a NameValueTable whose lifetime must be guaranteed
52 * to outlast the lifetime of the GlobalsArray. (The wrapper is
53 * refcounted, as required by ArrayData, but the table pointed to is not.)
55 struct GlobalsArray
: private ArrayData
{
56 explicit GlobalsArray(NameValueTable
* tab
);
59 // We only allow explicit conversions to ArrayData. Generally you
60 // should not be talking to the GlobalsArray directly (see
62 ArrayData
* asArrayData() { return this; }
63 const ArrayData
* asArrayData() const { return this; }
66 static void Release(ArrayData
*) {}
67 static ArrayData
* Copy(const ArrayData
* ad
) {
68 return const_cast<ArrayData
*>(ad
);
70 static size_t Vsize(const ArrayData
*);
71 static void NvGetKey(const ArrayData
* ad
, TypedValue
* out
, ssize_t pos
);
72 static const Variant
& GetValueRef(const ArrayData
*, ssize_t pos
);
74 static bool ExistsInt(const ArrayData
* ad
, int64_t k
);
75 static bool ExistsStr(const ArrayData
* ad
, const StringData
* k
);
77 static const TypedValue
* NvGetInt(const ArrayData
*, int64_t k
);
78 static const TypedValue
* NvGetStr(const ArrayData
*, const StringData
* k
);
80 static ArrayData
* LvalInt(ArrayData
*, int64_t k
, Variant
*& ret
, bool copy
);
81 static ArrayData
* LvalStr(ArrayData
*, StringData
* k
, Variant
*& ret
,
83 static ArrayData
* LvalNew(ArrayData
*, Variant
*& ret
, bool copy
);
85 static ArrayData
* SetInt(ArrayData
*, int64_t k
, Cell v
, bool copy
);
86 static ArrayData
* SetStr(ArrayData
*, StringData
* k
, Cell v
, bool copy
);
87 static ArrayData
* SetRefInt(ArrayData
*, int64_t k
, Variant
& v
, bool copy
);
88 static ArrayData
* SetRefStr(ArrayData
*, StringData
* k
, Variant
& v
,
90 static constexpr auto AddInt
= &SetInt
;
91 static constexpr auto AddStr
= &SetStr
;
92 static ArrayData
* RemoveInt(ArrayData
*, int64_t k
, bool copy
);
93 static ArrayData
* RemoveStr(ArrayData
*, const StringData
* k
, bool copy
);
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
);
99 static ArrayData
* PlusEq(ArrayData
*, const ArrayData
* elems
);
100 static ArrayData
* Merge(ArrayData
*, const ArrayData
* elems
);
101 static ArrayData
* Prepend(ArrayData
*, const Variant
& v
, bool copy
);
102 static ArrayData
* CopyWithStrongIterators(const ArrayData
*);
104 static ssize_t
IterBegin(const ArrayData
*);
105 static ssize_t
IterLast(const ArrayData
*);
106 static ssize_t
IterEnd(const ArrayData
*);
107 static ssize_t
IterAdvance(const ArrayData
*, ssize_t prev
);
108 static ssize_t
IterRewind(const ArrayData
*, ssize_t prev
);
110 static bool ValidMArrayIter(const ArrayData
*, const MArrayIter
& fp
);
111 static bool AdvanceMArrayIter(ArrayData
*, MArrayIter
&);
112 static bool IsVectorData(const ArrayData
*);
113 static ArrayData
* NonSmartCopy(const ArrayData
*);
114 static constexpr auto Pop
= &ArrayCommon::Pop
;
115 static constexpr auto Dequeue
= &ArrayCommon::Dequeue
;
116 static void Renumber(ArrayData
*);
117 static void OnSetEvalScalar(ArrayData
*);
119 static ArrayData
* EscalateForSort(ArrayData
*);
120 static void Ksort(ArrayData
*, int sort_flags
, bool ascending
);
121 static void Sort(ArrayData
*, int sort_flags
, bool ascending
);
122 static void Asort(ArrayData
*, int sort_flags
, bool ascending
);
123 static bool Uksort(ArrayData
*, const Variant
& cmp_function
);
124 static bool Usort(ArrayData
*, const Variant
& cmp_function
);
125 static bool Uasort(ArrayData
*, const Variant
& cmp_function
);
127 static ArrayData
* Escalate(const ArrayData
* ad
) {
128 return const_cast<ArrayData
*>(ad
);
132 static GlobalsArray
* asGlobals(ArrayData
* ad
);
133 static const GlobalsArray
* asGlobals(const ArrayData
* ad
);
136 NameValueTable
* const m_tab
;
139 //////////////////////////////////////////////////////////////////////