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 +----------------------------------------------------------------------+
17 #ifndef incl_HPHP_RUNTIME_VM_NAMEVALUETABLE_H_
18 #define incl_HPHP_RUNTIME_VM_NAMEVALUETABLE_H_
20 #include <folly/Bits.h>
22 #include "hphp/runtime/base/typed-value.h"
26 //////////////////////////////////////////////////////////////////////
32 * This class implements a name to TypedValue map. Basically a hashtable from
33 * StringData* to TypedValue.
35 * This is for use in variable environments in bytecode.cpp, and is also used
36 * for the global variable environment ($GLOBALS via GlobalsArray).
38 * The table may be optionally attached to an ActRec, in which case it will
39 * contain a kNamedLocalDataType TypedValue per every named local defined in
40 * ActRec's function. This is to keep storage for locals in functions with a
41 * VarEnv in their normal location, but still make them accessible by name
44 struct NameValueTable
{
46 explicit Iterator(const NameValueTable
* tab
);
47 static Iterator
getLast(const NameValueTable
* tab
);
48 static Iterator
getEnd(const NameValueTable
* tab
);
51 * The following two constructors are primarily for using this with
52 * the ArrayData interface (see GlobalsArray), which
53 * expects iterators to be represented by a ssize_t.
55 * The constructor taking `pos' must be given a value previously
56 * returned from toInteger().
58 * The constructor taking a const StringData* starts iteration at
59 * the key given, or returns an invalid iterator if that key does
62 explicit Iterator(const NameValueTable
* tab
, ssize_t pos
);
63 explicit Iterator(const NameValueTable
* tab
, const StringData
* start
);
65 ssize_t
toInteger() const;
67 const StringData
* curKey() const;
68 const TypedValue
* curVal() const;
73 explicit Iterator() {}
77 const NameValueTable
* m_tab
;
82 * Create a global NameValueTable.
84 explicit NameValueTable();
87 * Create a NameValueTable attached to an already existing ActRec
88 * and populate the table with ActRec's locals.
90 explicit NameValueTable(ActRec
* fp
);
93 * Clone NameValueTable.
95 explicit NameValueTable(const NameValueTable
& nvTable
, ActRec
* fp
);
99 NameValueTable(const NameValueTable
&) = delete;
100 NameValueTable
& operator=(const NameValueTable
&) = delete;
103 * Suspend locals into an in-resumable ActRec.
105 void suspend(const ActRec
* oldFP
, ActRec
* newFP
);
108 * Attach to a new ActRec and populate its locals with TypedValues stored
109 * in this NameValueTable.
111 void attach(ActRec
* fp
);
114 * Detach from the current ActRec and steal its named locals.
116 void detach(ActRec
* fp
);
118 ActRec
* getFP() const { return m_fp
; }
121 * Explicitly request letting go of all elements in the
122 * NameValueTable without decrefing them.
124 * This is intended for use when destroying the global scope, where
125 * we shouldn't be running destructors.
128 bool leaked() const { return !m_table
; }
131 * Set the slot for the supplied name to `val', allocating it if
134 TypedValue
* set(const StringData
* name
, const TypedValue
* val
);
137 * Bind the slot for the supplied name to `val', allocating it and
138 * boxing it first if necessary.
140 TypedValue
* bind(const StringData
* name
, TypedValue
* val
);
143 * Remove an element from this table. All elements added always
144 * occupy storage, so this is done by setting the element to
147 void unset(const StringData
* name
);
150 * Lookup a name, returning null if it doesn't exist in this table.
152 TypedValue
* lookup(const StringData
* name
);
155 * Insert a name to value entry with KindOfNull for the value, or
156 * return what is already there if the key already exists in the
159 TypedValue
* lookupAdd(const StringData
* name
);
162 // Dummy DT for named locals; keep out of conflict with actual DataTypes in
164 static constexpr auto kNamedLocalDataType
= kExtraInvalidDataType
;
166 // Element type for the name/value hashtable.
169 const StringData
* m_name
;
171 // m_tv is only valid if m_name != null
173 scanner
.scan(m_name
);
180 void reserve(size_t desiredSize
);
181 void allocate(const size_t newCapac
);
182 TypedValue
* derefNamedLocal(TypedValue
* tv
) const;
183 TypedValue
* findTypedValue(const StringData
* name
);
184 Elm
* insertImpl(const StringData
* name
);
185 Elm
* insert(const StringData
* name
);
186 void rehash(Elm
* const oldTab
, const size_t oldMask
);
187 Elm
* findElm(const StringData
* name
) const;
190 ActRec
* m_fp
{nullptr};
191 Elm
* m_table
{nullptr};
192 uint32_t m_tabMask
{0};
196 if (leaked()) return;
198 scanner
.scan(m_table
);
202 //////////////////////////////////////////////////////////////////////