• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 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_JS_API_JS_API_LIGHTWEIGHTMAP_H
17 #define ECMASCRIPT_JS_API_JS_API_LIGHTWEIGHTMAP_H
18 
19 #include "ecmascript/js_object.h"
20 #include "ecmascript/js_tagged_value-inl.h"
21 
22 namespace panda::ecmascript {
23 enum class AccossorsKind { HASH = 0, KEY, VALUE };
24 struct HashParams {
25     JSHandle<TaggedArray> hashArray;
26     JSHandle<TaggedArray> keyArray;
27     JSTaggedValue *key;
28 };
29 
30 // The status of the KEY in the container, including whether the KEY exists,
31 // the HASH corresponding to the KEY, and the INDEX where the KEY is located or will be inserted.
32 struct KeyState {
33     bool existed;
34     int32_t hash;
35     int32_t index;
36 };
37 class JSAPILightWeightMap : public JSObject {
38 public:
39     static constexpr int DEFAULT_CAPACITY_LENGTH = 8;
40     static constexpr int32_t HASH_REBELLION = 0xFFFFFFFF;
Cast(TaggedObject * object)41     static JSAPILightWeightMap *Cast(TaggedObject *object)
42     {
43         ASSERT(JSTaggedValue(object).IsJSAPILightWeightMap());
44         return static_cast<JSAPILightWeightMap *>(object);
45     }
46     static void InsertValue(const JSThread *thread, const JSHandle<JSAPILightWeightMap> &lightWeightMap,
47                             int32_t index, const JSHandle<JSTaggedValue> &value, AccossorsKind kind);
48     static void ReplaceValue(const JSThread *thread, const JSHandle<JSAPILightWeightMap> &lightWeightMap,
49                              int32_t index, const JSHandle<JSTaggedValue> &value, AccossorsKind kind);
50     static void Set(JSThread *thread, const JSHandle<JSAPILightWeightMap> &lightWeightMap,
51                     const JSHandle<JSTaggedValue> &key, const JSHandle<JSTaggedValue> &value);
52     static JSTaggedValue Get(JSThread *thread, const JSHandle<JSAPILightWeightMap> &lightWeightMap,
53                              const JSHandle<JSTaggedValue> &key);
54     static JSTaggedValue HasAll(JSThread *thread, const JSHandle<JSAPILightWeightMap> &lightWeightMap,
55                                 const JSHandle<JSAPILightWeightMap> &newLightWeightMap);
56     static JSTaggedValue HasKey(JSThread *thread, const JSHandle<JSAPILightWeightMap> &lightWeightMap,
57                                 const JSHandle<JSTaggedValue> &key);
58     static JSTaggedValue HasValue(JSThread *thread, const JSHandle<JSAPILightWeightMap> &lightWeightMap,
59                                   const JSHandle<JSTaggedValue> &value);
60     static int32_t GetIndexOfKey(JSThread *thread, const JSHandle<JSAPILightWeightMap> &lightWeightMap,
61                                  const JSHandle<JSTaggedValue> &key);
62     static KeyState GetStateOfKey(JSThread *thread, const JSHandle<JSAPILightWeightMap> &lightWeightMap,
63                                   const JSHandle<JSTaggedValue> &key);
64     static int32_t GetIndexOfValue(JSThread *thread, const JSHandle<JSAPILightWeightMap> &lightWeightMap,
65                                    const JSHandle<JSTaggedValue> &value);
66     static JSTaggedValue GetKeyAt(JSThread *thread, const JSHandle<JSAPILightWeightMap> &lightWeightMap, int32_t index);
67     static void SetAll(JSThread *thread, const JSHandle<JSAPILightWeightMap> &lightWeightMap,
68                        const JSHandle<JSAPILightWeightMap> &newLightWeightMap);
69     static JSTaggedValue Remove(JSThread *thread, const JSHandle<JSAPILightWeightMap> &lightWeightMap,
70                                 const JSHandle<JSTaggedValue> &key);
71     static JSTaggedValue RemoveAt(JSThread *thread, const JSHandle<JSAPILightWeightMap> &lightWeightMap, int32_t index);
72     static void Clear(JSThread *thread, const JSHandle<JSAPILightWeightMap> &lightWeightMap);
73     static JSTaggedValue SetValueAt(JSThread *thread, const JSHandle<JSAPILightWeightMap> &lightWeightMap,
74                                     int32_t index, const JSHandle<JSTaggedValue> &value);
75     static JSTaggedValue IncreaseCapacityTo(JSThread *thread, const JSHandle<JSAPILightWeightMap> &lightWeightMap,
76                                             int32_t index);
77     static JSTaggedValue ToString(JSThread *thread, const JSHandle<JSAPILightWeightMap> &lightWeightMap);
78     static JSTaggedValue GetValueAt(JSThread *thread, const JSHandle<JSAPILightWeightMap> &lightWeightMap,
79                                     int32_t index);
80     static JSTaggedValue GetIteratorObj(JSThread *thread, const JSHandle<JSAPILightWeightMap> &obj, IterationKind type);
81     static bool GetOwnProperty(JSThread *thread, const JSHandle<JSAPILightWeightMap> &map,
82                                const JSHandle<JSTaggedValue> &key,
83                                PropertyDescriptor &desc);
84     JSTaggedValue IsEmpty();
GetSize()85     inline uint32_t GetSize() const
86     {
87         return GetLength();
88     }
89 
90     static constexpr size_t LWP_HASHES_OFFSET = JSObject::SIZE;
91     ACCESSORS(Hashes, LWP_HASHES_OFFSET, LWP_KEYS_OFFSET);
92     ACCESSORS(Keys, LWP_KEYS_OFFSET, LWP_VALUES_OFFSET);
93     ACCESSORS(Values, LWP_VALUES_OFFSET, LWP_LENGTH_OFFSET);
94     ACCESSORS_PRIMITIVE_FIELD(Length, uint32_t, LWP_LENGTH_OFFSET, LAST_OFFSET);
95     DEFINE_ALIGN_SIZE(LAST_OFFSET);
96 
DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject,LWP_HASHES_OFFSET,LWP_LENGTH_OFFSET)97     DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, LWP_HASHES_OFFSET, LWP_LENGTH_OFFSET)
98     DECL_DUMP()
99 
100 private:
101     static inline uint32_t ComputeCapacity(uint32_t oldCapacity)
102     {
103         uint32_t newCapacity = oldCapacity + (oldCapacity >> 1U);
104         return newCapacity > DEFAULT_CAPACITY_LENGTH ? newCapacity : DEFAULT_CAPACITY_LENGTH;
105     };
106     static JSHandle<TaggedArray> GrowCapacity(const JSThread *thread, JSHandle<TaggedArray> &oldArray,
107                                               uint32_t needCapacity);
108     static void SetArrayByKind(const JSThread *thread,
109                                const JSHandle<JSAPILightWeightMap> &lightWeightMap,
110                                const JSHandle<TaggedArray> &array,
111                                AccossorsKind kind);
112     static void RemoveValue(const JSThread *thread, const JSHandle<JSAPILightWeightMap> &lightWeightMap, uint32_t index,
113                             AccossorsKind kind);
114     static void SetValue(const JSThread *thread, const JSHandle<JSAPILightWeightMap> &lightWeightMap,
115                          int32_t index, const JSHandle<JSTaggedValue> &value, AccossorsKind kind);
116     static int32_t Hash(JSTaggedValue key);
117     static int32_t BinarySearchHashes(JSHandle<TaggedArray> &array, int32_t hash, int32_t size);
118     static JSHandle<TaggedArray> GetArrayByKind(const JSThread *thread,
119                                                 const JSHandle<JSAPILightWeightMap> &lightWeightMap,
120                                                 AccossorsKind kind);
121     static int32_t AvoidHashCollision(HashParams &params, int32_t index, uint32_t size, int32_t hash);
122 };
123 }  // namespace panda::ecmascript
124 
125 #endif  // ECMASCRIPT_JS_API_JS_API_LIGHTWEIGHTMAP_H
126