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_NAME_VALUE_TABLE_WRAPPER_H
17 #define incl_HPHP_RUNTIME_VM_NAME_VALUE_TABLE_WRAPPER_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.
29 * This is used to expose a NameValueTable to php code, particularly
30 * for $GLOBALS, but also for some internal generated-bytecode
31 * initialization routines (86pinit, 86sinit).
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
40 * converted to strings.)
42 * - size() is an O(N) operation. (This is because of KindOfNamedLocal
43 * support in the underlying NameValueTable.)
45 * - Append/prepend operations are not supported.
47 * - Strong iterators "past the end" are not updated when new
48 * elements are added. (Since iteration order is unspecified,
49 * this semantic would seem weird anyway.)
51 * This holds a pointer to a NameValueTable whose lifetime must be
52 * guaranteed to outlast the lifetime of the NameValueTableWrapper.
53 * (The wrapper is refcounted, as required by ArrayData, but the table
56 struct NameValueTableWrapper
: private ArrayData
{
57 explicit NameValueTableWrapper(NameValueTable
* tab
)
58 : ArrayData(kNvtwKind
)
61 ~NameValueTableWrapper();
63 // We only allow explicit conversions to ArrayData. Generally you
64 // should not be talking to the NameValueTableWrapper directly (see
66 ArrayData
* asArrayData() { return this; }
67 const ArrayData
* asArrayData() const { return this; }
70 static void Release(ArrayData
*) {}
71 static ArrayData
* Copy(const ArrayData
* ad
) {
72 return const_cast<ArrayData
*>(ad
);
74 static size_t Vsize(const ArrayData
*);
75 static void NvGetKey(const ArrayData
* ad
, TypedValue
* out
, ssize_t pos
);
76 static const Variant
& GetValueRef(const ArrayData
*, ssize_t pos
);
78 static bool ExistsInt(const ArrayData
* ad
, int64_t k
);
79 static bool ExistsStr(const ArrayData
* ad
, const StringData
* k
);
81 static const TypedValue
* NvGetInt(const ArrayData
*, int64_t k
);
82 static const TypedValue
* NvGetStr(const ArrayData
*, const StringData
* k
);
84 static ArrayData
* LvalInt(ArrayData
*, int64_t k
, Variant
*& ret
, bool copy
);
85 static ArrayData
* LvalStr(ArrayData
*, StringData
* k
, Variant
*& ret
,
87 static ArrayData
* LvalNew(ArrayData
*, Variant
*& ret
, bool copy
);
89 static ArrayData
* SetInt(ArrayData
*, int64_t k
, Cell v
, bool copy
);
90 static ArrayData
* SetStr(ArrayData
*, StringData
* k
, Cell v
, bool copy
);
91 static ArrayData
* SetRefInt(ArrayData
*, int64_t k
, Variant
& v
, bool copy
);
92 static ArrayData
* SetRefStr(ArrayData
*, StringData
* k
, Variant
& v
,
94 static constexpr auto AddInt
= &SetInt
;
95 static constexpr auto AddStr
= &SetStr
;
96 static ArrayData
* RemoveInt(ArrayData
*, int64_t k
, bool copy
);
97 static ArrayData
* RemoveStr(ArrayData
*, const StringData
* k
, bool copy
);
99 static ArrayData
* Append(ArrayData
*, const Variant
& v
, bool copy
);
100 static ArrayData
* AppendRef(ArrayData
*, Variant
& v
, bool copy
);
101 static ArrayData
* AppendWithRef(ArrayData
*, const Variant
& v
, bool copy
);
103 static ArrayData
* PlusEq(ArrayData
*, const ArrayData
* elems
);
104 static ArrayData
* Merge(ArrayData
*, const ArrayData
* elems
);
105 static ArrayData
* Prepend(ArrayData
*, const Variant
& v
, bool copy
);
106 static ArrayData
* CopyWithStrongIterators(const ArrayData
*);
108 static ssize_t
IterBegin(const ArrayData
*);
109 static ssize_t
IterLast(const ArrayData
*);
110 static ssize_t
IterEnd(const ArrayData
*);
111 static ssize_t
IterAdvance(const ArrayData
*, ssize_t prev
);
112 static ssize_t
IterRewind(const ArrayData
*, ssize_t prev
);
114 static bool ValidMArrayIter(const ArrayData
*, const MArrayIter
& fp
);
115 static bool AdvanceMArrayIter(ArrayData
*, MArrayIter
&);
116 static bool IsVectorData(const ArrayData
*);
117 static ArrayData
* NonSmartCopy(const ArrayData
*);
118 static constexpr auto Pop
= &ArrayCommon::Pop
;
119 static constexpr auto Dequeue
= &ArrayCommon::Dequeue
;
120 static void Renumber(ArrayData
*);
121 static void OnSetEvalScalar(ArrayData
*);
123 static ArrayData
* EscalateForSort(ArrayData
*);
124 static void Ksort(ArrayData
*, int sort_flags
, bool ascending
);
125 static void Sort(ArrayData
*, int sort_flags
, bool ascending
);
126 static void Asort(ArrayData
*, int sort_flags
, bool ascending
);
127 static bool Uksort(ArrayData
*, const Variant
& cmp_function
);
128 static bool Usort(ArrayData
*, const Variant
& cmp_function
);
129 static bool Uasort(ArrayData
*, const Variant
& cmp_function
);
131 static ArrayData
* Escalate(const ArrayData
* ad
) {
132 return const_cast<ArrayData
*>(ad
);
136 static NameValueTableWrapper
* asNVTW(ArrayData
* ad
);
137 static const NameValueTableWrapper
* asNVTW(const ArrayData
* ad
);
140 NameValueTable
* const m_tab
;
143 class GlobalNameValueTableWrapper
: public NameValueTableWrapper
{
145 explicit GlobalNameValueTableWrapper(NameValueTable
* tab
);
148 //////////////////////////////////////////////////////////////////////