• 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_TAGGED_ARRAY_H
17 #define ECMASCRIPT_TAGGED_ARRAY_H
18 
19 #include "ecmascript/js_hclass.h"
20 #include "ecmascript/js_tagged_value.h"
21 #include "ecmascript/js_thread.h"
22 
23 namespace panda::ecmascript {
24 class ObjectFactory;
25 
26 class TaggedArray : public TaggedObject {
27 public:
28     static constexpr uint32_t MAX_ARRAY_INDEX = std::numeric_limits<uint32_t>::max();
29     static constexpr uint32_t MAX_END_UNUSED = 4;
30 
Cast(ObjectHeader * obj)31     inline static TaggedArray *Cast(ObjectHeader *obj)
32     {
33         ASSERT(JSTaggedValue(obj).IsTaggedArray());
34         return static_cast<TaggedArray *>(obj);
35     }
36 
37     JSTaggedValue Get(uint32_t idx) const;
38 
39     uint32_t GetIdx(const JSTaggedValue &value) const;
40 
41     template<typename T>
42     void Set(const JSThread *thread, uint32_t idx, const JSHandle<T> &value);
43 
44     JSTaggedValue Get(const JSThread *thread, uint32_t idx) const;
45 
46     void Set(const JSThread *thread, uint32_t idx, const JSTaggedValue &value);
47 
48     static inline JSHandle<TaggedArray> Append(const JSThread *thread, const JSHandle<TaggedArray> &first,
49                                                const JSHandle<TaggedArray> &second);
50     static inline JSHandle<TaggedArray> AppendSkipHole(const JSThread *thread, const JSHandle<TaggedArray> &first,
51                                                        const JSHandle<TaggedArray> &second, uint32_t copyLength);
52 
ComputeSize(size_t elemSize,uint32_t length)53     static inline size_t ComputeSize(size_t elemSize, uint32_t length)
54     {
55         ASSERT(elemSize != 0);
56         size_t size = DATA_OFFSET + elemSize * length;
57 #ifdef PANDA_TARGET_32
58         size_t sizeLimit = (std::numeric_limits<size_t>::max() - DATA_OFFSET) / elemSize;
59         if (UNLIKELY(sizeLimit < static_cast<size_t>(length))) {
60             return 0;
61         }
62 #endif
63         return size;
64     }
65 
GetData()66     inline JSTaggedType *GetData() const
67     {
68         return reinterpret_cast<JSTaggedType *>(ToUintPtr(this) + DATA_OFFSET);
69     }
70 
71     inline bool IsDictionaryMode() const;
72 
73     bool HasDuplicateEntry() const;
74 
75     static JSHandle<TaggedArray> SetCapacity(const JSThread *thread, const JSHandle<TaggedArray> &array,
76                                              uint32_t capa);
77 
78     inline void InitializeWithSpecialValue(JSTaggedValue initValue, uint32_t length);
79 
ShouldTrim(JSThread * thread,uint32_t oldLength,uint32_t newLength)80     static inline bool ShouldTrim(JSThread *thread, uint32_t oldLength, uint32_t newLength)
81     {
82         return (oldLength - newLength > MAX_END_UNUSED);
83     }
84     inline void Trim(JSThread *thread, uint32_t newLength);
85 
86     static constexpr size_t LENGTH_OFFSET = TaggedObjectSize();
87     ACCESSORS_PRIMITIVE_FIELD(Length, uint32_t, LENGTH_OFFSET, LAST_OFFSET)
88     DEFINE_ALIGN_SIZE(LAST_OFFSET);
89     static constexpr size_t DATA_OFFSET = SIZE;  // DATA_OFFSET equal to Empty Array size
90 
91     DECL_VISIT_ARRAY(DATA_OFFSET, GetLength());
92 
93 private:
94     friend class ObjectFactory;
95 };
96 
97 static_assert(TaggedArray::LENGTH_OFFSET == sizeof(TaggedObject));
98 static_assert((TaggedArray::DATA_OFFSET % static_cast<uint8_t>(MemAlignment::MEM_ALIGN_OBJECT)) == 0);
99 }  // namespace panda::ecmascript
100 #endif  // ECMASCRIPT_TAGGED_ARRAY_H
101