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_ENUM_CACHE_H_
18 #define incl_HPHP_ENUM_CACHE_H_
20 #include "hphp/runtime/ext/extension.h"
21 #include "hphp/runtime/vm/class.h"
22 #include <tbb/concurrent_hash_map.h>
26 //////////////////////////////////////////////////////////////////////
28 // Values in the TBB map that contain the enum static arrays
30 // array from 'enum name' to 'enum value'
31 // e.g. [ 'RED' => 1, 'BLUE' =>2, ...]
33 // array from 'enum value' to 'enum name'
34 // e.g. [ 1 => 'RED', 2 => 'BLUE', ...]
42 // TBB hash and compare struct
44 bool equal(intptr_t key1
, intptr_t key2
) const {
45 assertx(key1
&& key2
);
46 bool equal
= (key1
== key2
);
47 assertx(!equal
|| getClass(key1
)->name()->equal(getClass(key2
)->name()));
51 size_t hash(intptr_t key
) const {
53 return static_cast<size_t>(hash_int64(key
));
57 // if the class provided derives from Enum the name/value and value/name
58 // arrays are build, stored in the cache and returned.
59 // If not an error is raised.
60 // If the recurse flag is 'true' array values are loaded up the hierarchy
62 static const EnumValues
* getValues(const Class
* klass
, bool recurse
);
63 // Like above, but for first-class enums
64 static const EnumValues
* getValuesBuiltin(const Class
* klass
);
65 // Like above, but for first-class enums where the values can be computed
66 // entirely statically. Returns nullptr if that's not the case.
67 static const EnumValues
* getValuesStatic(const Class
* klass
);
68 // delete the EnumValues element in the cache for the given class.
69 // If there is no entry this function is a no-op.
70 static void deleteValues(const Class
* klass
);
72 // Helper that raises a PHP exception
73 [[noreturn
]] static void failLookup(const Variant
& msg
);
75 // Large enums get the dummy LargeEnum tag (so that we can cache a single
76 // static value for these enums). Small enums get a tag based on the caller.
77 static Array
tagEnumWithProvenance(Array input
);
80 // Class* to intptr_ti key helpers
81 const static intptr_t RECURSE_MASK
= 1;
82 static const Class
* getClass(intptr_t key
) {
83 return reinterpret_cast<const Class
*>(key
& ~RECURSE_MASK
);
86 static intptr_t getKey(const Class
* klass
, bool recurse
) {
87 intptr_t key
= reinterpret_cast<intptr_t>(klass
);
88 return (recurse
) ? key
| RECURSE_MASK
: key
;
91 const EnumValues
* cachePersistentEnumValues(
97 const EnumValues
* cacheRequestEnumValues(
103 const EnumValues
* getEnumValuesIfDefined(intptr_t key
,
104 bool checkLocal
= true) const;
105 const EnumValues
* getEnumValues(const Class
* klass
, bool recurse
,
106 bool require_static
= false);
107 const EnumValues
* loadEnumValues(const Class
* klass
, bool recurse
,
108 bool require_static
= false);
109 void deleteEnumValues(intptr_t key
);
111 // Map that contains associations between Enum classes and their array
112 // values and array names.
113 using EnumValuesMap
= tbb::concurrent_hash_map
<
118 using ReqEnumValuesMap
= req::fast_map
<
122 // Persistent values, recursive case. Non-recursive are cached in Class.
123 EnumValuesMap m_enumValuesMap
;
125 rds::Link
<ReqEnumValuesMap
*, rds::Mode::Normal
> m_nonScalarEnumValuesMap
;
128 //////////////////////////////////////////////////////////////////////