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 +----------------------------------------------------------------------+
17 #ifndef incl_HPHP_RUNTIME_VM_NAMEVALUETABLE_H_
18 #define incl_HPHP_RUNTIME_VM_NAMEVALUETABLE_H_
20 #include <boost/noncopyable.hpp>
22 #include <folly/Bits.h>
24 #include "hphp/runtime/base/complex-types.h"
28 //////////////////////////////////////////////////////////////////////
33 * This class implements a name to TypedValue map. Basically a hashtable from
34 * StringData* to TypedValue.
36 * This is for use in variable environments in bytecode.cpp, and is also used
37 * for the global variable environment ($GLOBALS via GlobalsArray).
39 * The table may be optionally attached to an ActRec, in which case it will
40 * contain a kNamedLocalDataType TypedValue per every named local defined in
41 * ActRec's function. This is to keep storage for locals in functions with a
42 * VarEnv in their normal location, but still make them accessible by name
45 struct NameValueTable
: private boost::noncopyable
{
47 explicit Iterator(const NameValueTable
* tab
);
48 static Iterator
getLast(const NameValueTable
* tab
);
49 static Iterator
getEnd(const NameValueTable
* tab
);
52 * The following two constructors are primarily for using this with
53 * the ArrayData interface (see GlobalsArray), which
54 * expects iterators to be represented by a ssize_t.
56 * The constructor taking `pos' must be given a value previously
57 * returned from toInteger().
59 * The constructor taking a const StringData* starts iteration at
60 * the key given, or returns an invalid iterator if that key does
63 explicit Iterator(const NameValueTable
* tab
, ssize_t pos
);
64 explicit Iterator(const NameValueTable
* tab
, const StringData
* start
);
66 ssize_t
toInteger() const;
68 const StringData
* curKey() const;
69 const TypedValue
* curVal() const;
74 explicit Iterator() {}
78 const NameValueTable
* m_tab
;
83 * Create a global NameValueTable.
85 explicit NameValueTable();
88 * Create a NameValueTable attached to an already existing ActRec
89 * and populate the table with ActRec's locals.
91 explicit NameValueTable(ActRec
* fp
);
94 * Clone NameValueTable.
96 explicit NameValueTable(const NameValueTable
& nvTable
, ActRec
* fp
);
101 * Suspend locals into an in-resumable ActRec.
103 void suspend(const ActRec
* oldFP
, ActRec
* newFP
);
106 * Attach to a new ActRec and populate its locals with TypedValues stored
107 * in this NameValueTable.
109 void attach(ActRec
* fp
);
112 * Detach from the current ActRec and steal its named locals.
114 void detach(ActRec
* fp
);
116 ActRec
* getFP() const { return m_fp
; }
119 * Explicitly request letting go of all elements in the
120 * NameValueTable without decrefing them.
122 * This is intended for use when destroying the global scope, where
123 * we shouldn't be running destructors.
128 * Set the slot for the supplied name to `val', allocating it if
131 TypedValue
* set(const StringData
* name
, const TypedValue
* val
);
134 * Bind the slot for the supplied name to `val', allocating it and
135 * boxing it first if necessary.
137 TypedValue
* bind(const StringData
* name
, TypedValue
* val
);
140 * Remove an element from this table. All elements added always
141 * occupy storage, so this is done by setting the element to
144 void unset(const StringData
* name
);
147 * Lookup a name, returning null if it doesn't exist in this table.
149 TypedValue
* lookup(const StringData
* name
);
152 * Insert a name to value entry with KindOfNull for the value, or
153 * return what is already there if the key already exists in the
156 TypedValue
* lookupAdd(const StringData
* name
);
161 const StringData
* m_name
;
165 void reserve(size_t desiredSize
);
166 void allocate(const size_t newCapac
);
167 TypedValue
* derefNamedLocal(TypedValue
* tv
) const;
168 TypedValue
* findTypedValue(const StringData
* name
);
169 Elm
* insertImpl(const StringData
* name
);
170 Elm
* insert(const StringData
* name
);
171 void rehash(Elm
* const oldTab
, const size_t oldMask
);
172 Elm
* findElm(const StringData
* name
) const;
175 ActRec
* m_fp
{nullptr};
176 Elm
* m_table
{nullptr}; // Power of two sized hashtable.
177 uint32_t m_tabMask
{0};
181 //////////////////////////////////////////////////////////////////////