unrestrict-layout part 5: Eliminate set in place
[hiphop-php.git] / hphp / runtime / base / record-array.h
blob4239a1c39b8f5e1c76c627785e2e381fada79900
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 #ifndef incl_HPHP_RECORD_ARRAY_H_
18 #define incl_HPHP_RECORD_ARRAY_H_
20 #include "hphp/runtime/base/array-common.h"
21 #include "hphp/runtime/base/array-data.h"
22 #include "hphp/runtime/base/record-data.h"
23 #include "hphp/runtime/base/string-hash-map.h"
25 namespace HPHP {
27 ///////////////////////////////////////////////////////////////////////////////
28 struct MixedArray;
30 struct RecordArray : ArrayData,
31 RecordBase,
32 type_scan::MarkCollectable<RecordArray> {
33 explicit RecordArray(const RecordDesc*);
34 RecordArray(const RecordArray&) = delete;
35 RecordArray& operator=(const RecordArray&) = delete;
36 ~RecordArray() = delete;
39 static size_t sizeWithFields(const RecordDesc* rec) {
40 return sizeof(RecordArray) + fieldSize(rec) + sizeof(ExtraFieldMapPtr);
42 size_t heapSize() const;
43 bool kindIsValid() const;
45 void scan(type_scan::Scanner&) const;
47 static RecordArray* newRecordArray(const RecordDesc*,
48 uint32_t initSize,
49 const StringData* const* keys,
50 const TypedValue* values);
51 RecordArray* copyRecordArray(AllocMode) const;
53 // Array interface
54 static void Release(ArrayData*);
55 static tv_rval NvGetInt(const ArrayData*, int64_t key);
56 static constexpr auto NvTryGetInt = &NvGetInt;
57 static tv_rval NvGetStr(const ArrayData*, const StringData*);
58 static constexpr auto NvTryGetStr = &NvGetStr;
59 static ssize_t NvGetIntPos(const ArrayData*, int64_t k);
60 static ssize_t NvGetStrPos(const ArrayData*, const StringData* k);
61 static TypedValue NvGetKey(const ArrayData*, ssize_t pos);
62 static ArrayData* SetInt(ArrayData*, int64_t key, TypedValue v);
63 static ArrayData* SetIntMove(ArrayData*, int64_t key, TypedValue v);
64 static ArrayData* SetStr(ArrayData*, StringData*, TypedValue v);
65 static ArrayData* SetStrMove(ArrayData*, StringData*, TypedValue v);
66 static size_t Vsize(const ArrayData*);
67 static tv_rval RvalPos(const ArrayData*, ssize_t pos);
68 static bool IsVectorData(const ArrayData*);
69 static bool ExistsInt(const ArrayData*, int64_t key);
70 static bool ExistsStr(const ArrayData*, const StringData*);
71 static arr_lval LvalInt(ArrayData*, int64_t k, bool copy);
72 static arr_lval LvalStr(ArrayData*, StringData* key, bool copy);
73 static arr_lval LvalSilentInt(ArrayData*, int64_t k, bool copy);
74 static arr_lval LvalSilentStr(ArrayData*, StringData* key, bool copy);
75 static arr_lval LvalForceNew(ArrayData*, bool copy);
76 static ArrayData* RemoveInt(ArrayData*, int64_t key);
77 static ArrayData* RemoveStr(ArrayData*, const StringData*);
78 static ssize_t IterEnd(const ArrayData*);
79 static ssize_t IterBegin(const ArrayData*);
80 static ssize_t IterLast(const ArrayData*);
81 static ssize_t IterAdvance(const ArrayData*, ssize_t pos);
82 static ssize_t IterRewind(const ArrayData*, ssize_t pos);
83 static ArrayData* EscalateForSort(ArrayData*, SortFunction);
84 static void Ksort(ArrayData*, int sort_flags, bool ascending);
85 static void Sort(ArrayData*, int sort_flags, bool ascending);
86 static void Asort(ArrayData*, int sort_flags, bool ascending);
87 static bool Uksort(ArrayData*, const Variant&);
88 static bool Usort(ArrayData*, const Variant&);
89 static bool Uasort(ArrayData*, const Variant&);
90 static ArrayData* Copy(const ArrayData*);
91 static ArrayData* CopyStatic(const ArrayData*);
92 static ArrayData* Append(ArrayData*, TypedValue v);
93 static ArrayData* PlusEq(ArrayData*, const ArrayData* elems);
94 static ArrayData* Merge(ArrayData*, const ArrayData* elems);
95 static ArrayData* Pop(ArrayData*, Variant& value);
96 static ArrayData* Dequeue(ArrayData*, Variant& value);
97 static ArrayData* Prepend(ArrayData*, TypedValue v);
98 static void Renumber(ArrayData*);
99 static void OnSetEvalScalar(ArrayData*);
100 static ArrayData* ToPHPArray(ArrayData*, bool);
101 static constexpr auto ToPHPArrayIntishCast = &ToPHPArray;
102 static constexpr auto ToDict = &ArrayCommon::ToDict;
103 static constexpr auto ToVec = &ArrayCommon::ToVec;
104 static constexpr auto ToKeyset = &ArrayCommon::ToKeyset;
105 static constexpr auto ToVArray = &ArrayCommon::ToVArray;
106 static constexpr auto ToDArray = &ArrayCommon::ToDArray;
108 static RecordArray* asRecordArray(ArrayData*);
109 static const RecordArray* asRecordArray(const ArrayData*);
111 static MixedArray* ToMixed(const ArrayData*);
113 private:
114 using ExtraFieldMapPtr = MixedArray*;
115 ExtraFieldMapPtr& extraFieldMap() const;
116 bool checkInvariants() const;
118 * Returns index of the field with name `key` if it exists and
119 * `val` passes the typehint for the field.
120 * Returns kInvalidSlot if the field does not exist.
121 * Raises a typehint error if the field exists but the type check fails.
123 Slot checkFieldForWrite(const StringData* key, TypedValue val) const;
125 * Updates the field at idx if idx is valid. Otherwise inserts key, val pair
126 * in the extra field map.
128 void updateField(StringData* key, TypedValue val, Slot idx);
130 static MixedArray* ToMixedHeader(const RecordArray*);
133 ///////////////////////////////////////////////////////////////////////////////
137 #endif // incl_HPHP_RECORD_ARRAY_H_