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