Fix refcounting in arReturn() and stop leaking static strings.
[hiphop-php.git] / hphp / runtime / vm / name-value-table-wrapper.h
blob5ed85e42d44c711801cafd42a16b8dd99e590eba
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
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"
23 namespace HPHP {
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
54 * pointed to is not.)
56 struct NameValueTableWrapper : private ArrayData {
57 explicit NameValueTableWrapper(NameValueTable* tab)
58 : ArrayData(kNvtwKind)
59 , m_tab(tab)
61 ~NameValueTableWrapper();
63 // We only allow explicit conversions to ArrayData. Generally you
64 // should not be talking to the NameValueTableWrapper directly (see
65 // php-globals.h).
66 ArrayData* asArrayData() { return this; }
67 const ArrayData* asArrayData() const { return this; }
69 public:
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,
86 bool copy);
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,
93 bool copy);
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);
135 private:
136 static NameValueTableWrapper* asNVTW(ArrayData* ad);
137 static const NameValueTableWrapper* asNVTW(const ArrayData* ad);
139 private:
140 NameValueTable* const m_tab;
143 class GlobalNameValueTableWrapper : public NameValueTableWrapper {
144 public:
145 explicit GlobalNameValueTableWrapper(NameValueTable* tab);
148 //////////////////////////////////////////////////////////////////////
152 #endif