• 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_PROPERTY_ATTRIBUTES_H
17 #define ECMASCRIPT_PROPERTY_ATTRIBUTES_H
18 
19 #include "ecmascript/js_tagged_value.h"
20 
21 #include "libpandabase/utils/bit_field.h"
22 
23 namespace panda::ecmascript {
24 class PropertyDescriptor;
25 
26 enum class Representation {
27     NONE,
28     INT,
29     DOUBLE,
30     NUMBER,
31     OBJECT,
32     MIXED,
33 };
34 
35 enum class PropertyBoxType {
36     // Meaningful when a property cell does not contain the hole.
37     UNDEFINED,     // The PREMONOMORPHIC of property cells.
38     CONSTANT,      // Cell has been assigned only once.
39     CONSTANTTYPE,  // Cell has been assigned only one type.
40     MUTABLE,       // Cell will no longer be tracked as constant.
41 
42     // Meaningful when a property cell contains the hole.
43     UNINITIALIZED = UNDEFINED,  // Cell has never been initialized.
44     INVALIDATED = CONSTANT,     // Cell has been deleted, invalidated or never existed.
45 };
46 
47 class PropertyAttributes {
48 public:
49     explicit PropertyAttributes() = default;
50     ~PropertyAttributes() = default;
51 
52     DEFAULT_NOEXCEPT_MOVE_SEMANTIC(PropertyAttributes);
53     DEFAULT_COPY_SEMANTIC(PropertyAttributes);
54 
PropertyAttributes(uint32_t v)55     explicit PropertyAttributes(uint32_t v) : value_(v) {}
PropertyAttributes(int32_t v)56     explicit PropertyAttributes(int32_t v) : value_(static_cast<uint32_t>(v)) {}
PropertyAttributes(JSTaggedValue v)57     explicit PropertyAttributes(JSTaggedValue v) : value_(v.GetInt()) {}
58     explicit PropertyAttributes(const PropertyDescriptor &desc);
59 
60     static constexpr uint32_t DICTIONARY_ORDER_NUM = 20;
61     static constexpr uint32_t OFFSET_BITFIELD_NUM = 10;
62     static constexpr uint32_t MAX_CAPACITY_OF_PROPERTIES = (1U << OFFSET_BITFIELD_NUM) - 1;
63 
64     using PropertyMetaDataField = BitField<int, 0, 4>;    // 4: property metaData field occupies 4 bits
65     using AttributesField = BitField<int, 0, 4>;         // 4: attributes field occupies 4 bits
66     using DefaultAttributesField = BitField<int, 0, 3>;  // 3: default attributes field occupies 3 bits
67     using WritableField = BitField<bool, 0, 1>;          // 1: writable field occupies 1 bits
68     using EnumerableField = WritableField::NextFlag;
69     using ConfigurableField = EnumerableField::NextFlag;
70     using IsAccessorField = ConfigurableField::NextFlag;  // 4
71 
72     // fast mode
73     using IsInlinedPropsField = PropertyMetaDataField::NextFlag;                         // 5
74     using RepresentationField = IsInlinedPropsField::NextField<Representation, 3>;      // 3: 3 bits, 6-8
75     using OffsetField = RepresentationField::NextField<uint32_t, OFFSET_BITFIELD_NUM>;  // 18
76 
77     static constexpr uint32_t NORMAL_ATTR_BITS = 18;
78     using NormalAttrField = BitField<int, 0, NORMAL_ATTR_BITS>;
79     using SortedIndexField = OffsetField::NextField<uint32_t, OFFSET_BITFIELD_NUM>;  // 28
80     using IsConstPropsField = SortedIndexField::NextFlag;                            // 29
81     // dictionary mode, include global
82     using PropertyBoxTypeField = PropertyMetaDataField::NextField<PropertyBoxType, 2>;              // 2: 2 bits, 5-6
83     using DictionaryOrderField = PropertyBoxTypeField::NextField<uint32_t, DICTIONARY_ORDER_NUM>;  // 26
84 
85     static constexpr uint32_t BIT_SIZE = 28;
86     static constexpr int INITIAL_PROPERTY_INDEX = 0;
87 
GetPropertyMetaData()88     inline int GetPropertyMetaData() const
89     {
90         return PropertyMetaDataField::Get(value_);
91     }
92 
Default()93     static PropertyAttributes Default()
94     {
95         return PropertyAttributes(GetDefaultAttributes());
96     }
97 
98     static PropertyAttributes Default(bool w, bool e, bool c, bool isAccessor = false)
99     {
100         uint32_t value = WritableField::Encode(w) | EnumerableField::Encode(e) | ConfigurableField::Encode(c) |
101                          IsAccessorField::Encode(isAccessor);
102         return PropertyAttributes(value);
103     }
104 
DefaultAccessor(bool w,bool e,bool c)105     static PropertyAttributes DefaultAccessor(bool w, bool e, bool c)
106     {
107         uint32_t value = WritableField::Encode(w) | EnumerableField::Encode(e) | ConfigurableField::Encode(c) |
108                          IsAccessorField::Encode(true);
109         return PropertyAttributes(value);
110     }
111 
SetDefaultAttributes()112     inline void SetDefaultAttributes()
113     {
114         AttributesField::Set<uint32_t>(DefaultAttributesField::Mask(), &value_);
115     }
116 
GetDefaultAttributes()117     static inline int GetDefaultAttributes()
118     {
119         return DefaultAttributesField::Mask();
120     }
121 
TaggedToRepresentation(JSTaggedValue value)122     static inline Representation TaggedToRepresentation(JSTaggedValue value)
123     {
124         if (value.IsInt()) {
125             return Representation::INT;
126         }
127         if (value.IsDouble()) {
128             return Representation::DOUBLE;
129         }
130 
131         return Representation::OBJECT;
132     }
133 
UpdateRepresentation(Representation oldRep,JSTaggedValue value)134     static Representation UpdateRepresentation(Representation oldRep, JSTaggedValue value)
135     {
136         if (oldRep == Representation::MIXED) {
137             return oldRep;
138         }
139 
140         Representation newRep = TaggedToRepresentation(value);
141         if (oldRep == Representation::NONE) {
142             return newRep;
143         }
144         if (oldRep == newRep) {
145             return oldRep;
146         }
147 
148         switch (oldRep) {
149             case Representation::INT:
150             case Representation::DOUBLE:
151             case Representation::NUMBER:
152                 if (newRep != Representation::OBJECT) {
153                     return Representation::NUMBER;
154                 }
155                 return Representation::MIXED;
156             case Representation::OBJECT:
157                 return Representation::MIXED;
158             default:
159                 UNREACHABLE();
160         }
161     }
162 
IsDefaultAttributes()163     inline bool IsDefaultAttributes() const
164     {
165         return AttributesField::Get(value_) == static_cast<int>(DefaultAttributesField::Mask());
166     }
167 
SetNoneAttributes()168     inline void SetNoneAttributes()
169     {
170         AttributesField::Set<uint32_t>(0U, &value_);
171     }
172 
IsNoneAttributes()173     inline bool IsNoneAttributes() const
174     {
175         return AttributesField::Get(value_) == 0;
176     }
177 
SetWritable(bool flag)178     inline void SetWritable(bool flag)
179     {
180         WritableField::Set<uint32_t>(flag, &value_);
181     }
IsWritable()182     inline bool IsWritable() const
183     {
184         return WritableField::Get(value_);
185     }
SetEnumerable(bool flag)186     inline void SetEnumerable(bool flag)
187     {
188         EnumerableField::Set<uint32_t>(flag, &value_);
189     }
IsEnumerable()190     inline bool IsEnumerable() const
191     {
192         return EnumerableField::Get(value_);
193     }
SetConfigurable(bool flag)194     inline void SetConfigurable(bool flag)
195     {
196         ConfigurableField::Set<uint32_t>(flag, &value_);
197     }
IsConfigurable()198     inline bool IsConfigurable() const
199     {
200         return ConfigurableField::Get(value_);
201     }
202 
SetIsAccessor(bool flag)203     inline void SetIsAccessor(bool flag)
204     {
205         IsAccessorField::Set<uint32_t>(flag, &value_);
206     }
207 
IsAccessor()208     inline bool IsAccessor() const
209     {
210         return IsAccessorField::Get(value_);
211     }
212 
SetIsInlinedProps(bool flag)213     inline void SetIsInlinedProps(bool flag)
214     {
215         IsInlinedPropsField::Set<uint32_t>(flag, &value_);
216     }
217 
IsInlinedProps()218     inline bool IsInlinedProps() const
219     {
220         return IsInlinedPropsField::Get(value_);
221     }
222 
SetIsConstProps(bool flag)223     inline void SetIsConstProps(bool flag)
224     {
225         IsConstPropsField::Set<uint32_t>(flag, &value_);
226     }
227 
IsConstProps()228     inline bool IsConstProps() const
229     {
230         return IsConstPropsField::Get(value_);
231     }
232 
SetRepresentation(Representation representation)233     inline void SetRepresentation(Representation representation)
234     {
235         RepresentationField::Set<uint32_t>(representation, &value_);
236     }
GetRepresentation()237     inline Representation GetRepresentation() const
238     {
239         return RepresentationField::Get(value_);
240     }
241 
SetDictionaryOrder(uint32_t order)242     inline void SetDictionaryOrder(uint32_t order)
243     {
244         DictionaryOrderField::Set<uint32_t>(order, &value_);
245     }
GetDictionaryOrder()246     inline uint32_t GetDictionaryOrder() const
247     {
248         return DictionaryOrderField::Get(value_);
249     }
250 
SetOffset(uint32_t offset)251     inline void SetOffset(uint32_t offset)
252     {
253         OffsetField::Set<uint32_t>(offset, &value_);
254     }
GetOffset()255     inline uint32_t GetOffset() const
256     {
257         return OffsetField::Get(value_);
258     }
259 
SetSortedIndex(uint32_t sortedIndex)260     inline void SetSortedIndex(uint32_t sortedIndex)
261     {
262         SortedIndexField::Set<uint32_t>(sortedIndex, &value_);
263     }
GetSortedIndex()264     inline uint32_t GetSortedIndex() const
265     {
266         return SortedIndexField::Get(value_);
267     }
268 
SetNormalAttr(uint32_t normalAttr)269     inline void SetNormalAttr(uint32_t normalAttr)
270     {
271         NormalAttrField::Set<uint32_t>(normalAttr, &value_);
272     }
273 
GetNormalAttr()274     inline uint32_t GetNormalAttr() const
275     {
276         return NormalAttrField::Get(value_);
277     }
278 
GetNormalTagged()279     inline JSTaggedValue GetNormalTagged() const
280     {
281         return JSTaggedValue(static_cast<int>(GetNormalAttr()));
282     }
283 
GetValue()284     inline uint32_t GetValue() const
285     {
286         return value_;
287     }
288 
SetBoxType(PropertyBoxType cellType)289     inline void SetBoxType(PropertyBoxType cellType)
290     {
291         PropertyBoxTypeField::Set<uint32_t>(cellType, &value_);
292     }
293 
GetBoxType()294     inline PropertyBoxType GetBoxType() const
295     {
296         return PropertyBoxTypeField::Get(value_);
297     }
298 
IsValidIndex(int index)299     inline static bool IsValidIndex(int index)
300     {
301         return DictionaryOrderField::IsValid(index);
302     }
303 
GetTaggedValue()304     inline JSTaggedValue GetTaggedValue() const
305     {
306         return JSTaggedValue(static_cast<int>(value_));
307     }
308 
309 private:
310     uint32_t value_{0};
311 };
312 }  // namespace panda::ecmascript
313 #endif  // ECMASCRIPT_PROPERTY_ATTRIBUTES_H
314