• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef ECMASCRIPT_TS_TYPES_TS_OBJ_LAYOUT_INFO_H
17 #define ECMASCRIPT_TS_TYPES_TS_OBJ_LAYOUT_INFO_H
18 
19 #include "ecmascript/tagged_array-inl.h"
20 
21 namespace panda::ecmascript {
22 /*
23  * The TSObjLayoutInfo is organized as follows:
24  * The first position is used to store the number of properties.
25  * Store the key, gt and attribute of properties alternately starting from the second position.
26  * +---+-------+------+--------+-------+------+--------+-----+-------+------+--------+
27  * | N | key_1 | gt_1 | attr_1 | key_2 | gt_2 | attr_2 | ... | key_N | gt_N | attr_N |
28  * +---+-------+------+--------+-----=-+------+--------+-----+-------+------+--------+
29  */
30 class TSObjLayoutInfo : private TaggedArray {
31 public:
32     static constexpr int MIN_PROPERTIES_LENGTH = JSObject::MIN_PROPERTIES_LENGTH;
33     static constexpr int MAX_PROPERTIES_LENGTH = PropertyAttributes::MAX_FAST_PROPS_CAPACITY;
34     static constexpr int ELEMENTS_COUNT_INDEX = 0;
35     static constexpr int ELEMENTS_START_INDEX = 1;
36     static constexpr int ENTRY_SIZE = 3;
37     static constexpr int ENTRY_KEY_OFFSET = 0;
38     static constexpr int ENTRY_TYPE_OFFSET = 1;
39     static constexpr int ENTRY_ATTRIBUTE_OFFSET = 2;
40     static constexpr int DEFAULT_CAPACITY = 1;
41     static constexpr int INCREASE_CAPACITY_RATE = 1;
42     static constexpr int INVALID_INDEX = -1;
43 
Cast(TaggedObject * obj)44     inline static TSObjLayoutInfo *Cast(TaggedObject *obj)
45     {
46         ASSERT(JSTaggedValue(obj).IsTaggedArray());
47         return reinterpret_cast<TSObjLayoutInfo*>(obj);
48     }
49 
GetPropertiesCapacity()50     inline uint32_t GetPropertiesCapacity() const
51     {
52         ASSERT(GetLength() >= ELEMENTS_START_INDEX);
53         ASSERT((GetLength() - ELEMENTS_START_INDEX) % ENTRY_SIZE == 0);
54         return static_cast<uint32_t>((GetLength() - ELEMENTS_START_INDEX) / ENTRY_SIZE);
55     }
56 
SetNumOfProperties(const JSThread * thread,const uint32_t propertiesNum)57     inline void SetNumOfProperties(const JSThread *thread, const uint32_t propertiesNum)
58     {
59         return TaggedArray::Set(thread, ELEMENTS_COUNT_INDEX, JSTaggedValue(propertiesNum));
60     }
61 
GetNumOfProperties()62     inline uint32_t GetNumOfProperties() const
63     {
64         return TaggedArray::Get(ELEMENTS_COUNT_INDEX).GetInt();
65     }
66 
67     void AddProperty(const JSThread *thread, const JSTaggedValue key,
68                      const JSTaggedValue typeIdVal, const uint32_t attr = 0);
69 
70     void AddProperty(const JSThread *thread, const JSTaggedValue key,
71                      const JSTaggedValue typeIdVal, const JSTaggedValue attr);
72 
73     static JSHandle<TSObjLayoutInfo> PushBack(const JSThread *thread,
74                                               const JSHandle<TSObjLayoutInfo> &oldLayout,
75                                               const JSHandle<JSTaggedValue> &key,
76                                               const JSHandle<JSTaggedValue> &value);
77 
IsValidIndex(int index)78     static inline bool IsValidIndex(int index)
79     {
80         return index != INVALID_INDEX;
81     }
82 
GetLength()83     inline uint32_t GetLength() const
84     {
85         return TaggedArray::GetLength();
86     }
87 
ComputeGrowCapacity(const uint32_t oldCapacity)88     static inline uint32_t ComputeGrowCapacity(const uint32_t oldCapacity)
89     {
90         uint64_t newCapacity = (static_cast<uint64_t>(oldCapacity) << INCREASE_CAPACITY_RATE);
91         ASSERT(newCapacity <= static_cast<uint64_t>(MAX_PROPERTIES_LENGTH));
92         if (newCapacity > static_cast<uint64_t>(MAX_PROPERTIES_LENGTH)) {
93             return MAX_PROPERTIES_LENGTH;
94         }
95         return static_cast<uint32_t>(newCapacity);
96     }
97 
ComputeArrayLength(const uint32_t numOfProperties)98     static inline uint32_t ComputeArrayLength(const uint32_t numOfProperties)
99     {
100         return (numOfProperties * ENTRY_SIZE) + ELEMENTS_START_INDEX;
101     }
102 
103     bool Find(JSTaggedValue key) const;
104 
105     int GetElementIndexByKey(JSTaggedValue key) const;
106     void GetAccessorIndexByKey(JSTaggedValue key, std::vector<int> &vec);
107 
108     JSTaggedValue TryGetTypeByIndexSign(const uint32_t typeId);
109 
110 #define TSOBJLAYOUT_ACCESSOR_LIST(V)      \
111     V(Key, ENTRY_KEY_OFFSET)              \
112     V(TypeId, ENTRY_TYPE_OFFSET)          \
113     V(Attribute, ENTRY_ATTRIBUTE_OFFSET)
114 
115 #define TSOBJLAYOUT_ACCESSOR(NAME, OFFSET)                                                     \
116     inline void Set##NAME(const JSThread *thread, const int index, const JSTaggedValue key)    \
117     {                                                                                          \
118         uint32_t idxInArray = Get##NAME##Index(index);                                         \
119         TaggedArray::Set(thread, idxInArray, key);                                             \
120     }                                                                                          \
121                                                                                                \
122     inline JSTaggedValue Get##NAME(const int index) const                                      \
123     {                                                                                          \
124         uint32_t idxInArray = Get##NAME##Index(index);                                         \
125         return TaggedArray::Get(idxInArray);                                                   \
126     }                                                                                          \
127                                                                                                \
128     inline uint32_t Get##NAME##Index(const int index) const                                    \
129     {                                                                                          \
130         return ELEMENTS_START_INDEX + (static_cast<uint32_t>(index) * ENTRY_SIZE) + (OFFSET);  \
131     }
132 
133     TSOBJLAYOUT_ACCESSOR_LIST(TSOBJLAYOUT_ACCESSOR)
134 #undef TSOBJLAYOUT_ACCESSOR
135 
136 private:
137     static JSHandle<TSObjLayoutInfo> ExtendTSObjLayoutInfo(const JSThread *thread,
138                                                            const JSHandle<TSObjLayoutInfo> &old,
139                                                            JSTaggedValue initVal = JSTaggedValue::Hole());
140 };
141 }  // namespace panda::ecmascript
142 #endif  // ECMASCRIPT_TS_TYPES_TS_OBJ_LAYOUT_INFO_H
143