Don't detach handler after onError
[hiphop-php.git] / hphp / runtime / base / collections.h
blob64768ea5fc4814ec001d4fb1b97a45e5ef5dc2be
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
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 #pragma once
19 #include "hphp/runtime/base/header-kind.h"
20 #include "hphp/runtime/base/tv-val.h"
21 #include "hphp/runtime/base/type-string.h"
23 namespace HPHP {
24 struct ArrayData;
25 struct Class;
26 struct c_Pair;
27 struct c_Vector;
28 struct c_ImmVector;
29 struct c_Map;
30 struct c_ImmMap;
31 struct c_Set;
32 struct c_ImmSet;
35 namespace HPHP::collections {
36 /////////////////////////////////////////////////////////////////////////////
38 #define COLLECTIONS_PAIRED_TYPES(MACRO) \
39 MACRO(Vector) MACRO(ImmVector) \
40 MACRO(Map) MACRO(ImmMap) \
41 MACRO(Set) MACRO(ImmSet)
43 #define COLLECTIONS_ALL_TYPES(MACRO) \
44 MACRO(Pair) \
45 COLLECTIONS_PAIRED_TYPES(MACRO)
47 #define X(type) extern const StaticString s_##type;
48 COLLECTIONS_ALL_TYPES(X)
49 #undef X
51 /////////////////////////////////////////////////////////////////////////////
52 // Constructor/Initializer
54 using newEmptyInstanceFunc = ObjectData* (*)();
55 using newFromArrayFunc = ObjectData* (*)(ArrayData* arr);
58 * Get a constructor for the collections class.
60 * This is primarily used by the JIT to burn the initializer into the TC.
61 * The newFromArrayFunc result requires that its input is a vanilla array-like.
63 newEmptyInstanceFunc allocEmptyFunc(CollectionType ctype);
64 newFromArrayFunc allocFromArrayFunc(CollectionType ctype);
67 * Create a new empty collection, with refcount set to 1.
69 inline ObjectData* alloc(CollectionType ctype) {
70 return allocEmptyFunc(ctype)();
74 * Create a collection from an array, with refcount set to 1.
76 * Pre: The array must have a kind that's compatible with the collection type
77 * we're creating. However it MAY have a "bespoke" layout.
79 ObjectData* alloc(CollectionType ctype, ArrayData* arr);
82 * Creates a Pair. Takes ownership of the TypedValues passed in.
84 ObjectData* allocPair(TypedValue c1, TypedValue c2);
86 /////////////////////////////////////////////////////////////////////////////
87 // Casting and Cloning
89 bool isType(const Class* cls, CollectionType type);
90 template<typename ...Args>
91 bool isType(const Class* cls, CollectionType type, Args... args) {
92 return isType(cls, type) || isType(cls, args...);
95 template <IntishCast IC = IntishCast::None>
96 Array toArray(const ObjectData* obj);
98 bool toBool(const ObjectData* obj);
99 ObjectData* clone(ObjectData* obj);
101 void deepCopy(tv_lval tv);
104 * Return the inner-array for array-backed collections, and nullptr if it's a
105 * Pair. The returned array pointer is not incref'd.
107 ArrayData* asArray(ObjectData* obj);
108 inline const ArrayData* asArray(const ObjectData* obj) {
109 return asArray(const_cast<ObjectData*>(obj));
113 * Replace the inner-array for array-backed collections. May not be called on
114 * non-array-backed collections. This method is dangerous - take care!
116 void replaceArray(ObjectData* obj, ArrayData* ad);
118 /////////////////////////////////////////////////////////////////////////////
119 // Read/Write
121 /* at() and get() retrieve a collection element for reading.
122 * If the key does not exist in the collection, at() will throw an exception
123 * while get() will return nullptr
125 tv_lval at(ObjectData* obj, const TypedValue* key);
126 tv_lval get(ObjectData* obj, const TypedValue* key);
128 /* atLval() is used to get the address of an element when the
129 * caller is NOT going to do direct write per se, but it intends to use
130 * the element as the base of a member operation in an "lvalue" context
131 * (which could mutate the element in various ways).
133 tv_lval atLval(ObjectData* obj, const TypedValue* key);
135 /* atRw() is used to get the address of an element for reading
136 * and writing. It is typically used for read-modify-write operations (the
137 * SetOp* and IncDec* instructions).
139 tv_lval atRw(ObjectData* obj, const TypedValue* key);
141 /* Check for {key} within {obj} Collection
142 * `contains` merely need to exist
143 * `isset` needs to exist and not be null
145 bool contains(ObjectData* obj, const Variant& offset);
146 bool (isset)(ObjectData* obj, const TypedValue* key);
148 /* Remove element {key} from Collection {obj} */
149 void unset(ObjectData* obj, const TypedValue* key);
151 /* Add element {val} to Collection {obj} at {key} or the next slot */
152 void append(ObjectData* obj, TypedValue* val);
153 void set(ObjectData* obj, const TypedValue* key, const TypedValue* val);
155 /* Compare two collections.
156 * Only collections of the same type with the same elements are equal.
157 * Whether elements must be in the same order is CollectionType dependent.
159 bool equals(const ObjectData* obj1, const ObjectData* obj2);
161 /* Take element from end(pop) or beginning(shift) of a mutable collection */
162 Variant pop(ObjectData* obj);
163 Variant shift(ObjectData* obj);
165 /////////////////////////////////////////////////////////////////////////////
166 // CollectionType <-> Human-readable name conversions
169 * Returns a collection type name given a CollectionType.
171 inline StringData* typeToString(CollectionType ctype) {
172 switch (ctype) {
173 #define X(type) case CollectionType::type: return s_##type.get();
174 COLLECTIONS_ALL_TYPES(X)
175 #undef X
177 not_reached();
181 * Returns a CollectionType given a name, std::nullopt if name is not a
182 * collection type.
184 inline Optional<CollectionType> stringToType(const StringData* name) {
185 #define X(type) if (name->tsame(s_##type.get())) return CollectionType::type;
186 COLLECTIONS_ALL_TYPES(X)
187 #undef X
188 return std::nullopt;
191 inline Optional<CollectionType> stringToType(const std::string& s) {
192 return stringToType(
193 req::ptr<StringData>::attach(StringData::Make(s)).get()
197 inline bool isTypeName(const StringData* str) {
198 return stringToType(str).has_value();
201 /////////////////////////////////////////////////////////////////////////////