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