• 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 #include "ecmascript/layout_info-inl.h"
17 #include "ecmascript/ecma_string.h"
18 #include "ecmascript/js_symbol.h"
19 #include "ecmascript/mem/assert_scope-inl.h"
20 
21 namespace panda::ecmascript {
AddKey(const JSThread * thread,int index,const JSTaggedValue & key,const PropertyAttributes & attr)22 void LayoutInfo::AddKey(const JSThread *thread, [[maybe_unused]] int index, const JSTaggedValue &key,
23                         const PropertyAttributes &attr)
24 {
25     DISALLOW_GARBAGE_COLLECTION;
26     int number = NumberOfElements();
27     ASSERT(attr.GetOffset() == static_cast<uint32_t>(number));
28     ASSERT(number + 1 <= GetPropertiesCapacity());
29     ASSERT(number == index);
30     SetNumberOfElements(thread, number + 1);
31     SetPropertyInit(thread, number, key, attr);
32 
33     uint32_t keyHash = key.GetKeyHashCode();
34     int insertIndex = number;
35     for (; insertIndex > 0; --insertIndex) {
36         JSTaggedValue prevKey = GetSortedKey(insertIndex - 1);
37         if (prevKey.GetKeyHashCode() <= keyHash) {
38             break;
39         }
40         SetSortedIndex(thread, insertIndex, GetSortedIndex(insertIndex - 1));
41     }
42     SetSortedIndex(thread, insertIndex, number);
43 }
44 
GetAllKeys(const JSThread * thread,int end,int offset,TaggedArray * keyArray)45 void LayoutInfo::GetAllKeys(const JSThread *thread, int end, int offset, TaggedArray *keyArray)
46 {
47     ASSERT(end <= NumberOfElements());
48     ASSERT_PRINT(offset + end <= static_cast<int>(keyArray->GetLength()),
49                  "keyArray capacity is not enough for dictionary");
50 
51     DISALLOW_GARBAGE_COLLECTION;
52     int enumKeys = 0;
53     for (int i = 0; i < end; i++) {
54         JSTaggedValue key = GetKey(i);
55         if (key.IsString()) {
56             keyArray->Set(thread, enumKeys + offset, key);
57             enumKeys++;
58         }
59     }
60 
61     if (enumKeys < end) {
62         for (int i = 0; i < end; i++) {
63             JSTaggedValue key = GetKey(i);
64             if (key.IsSymbol()) {
65                 keyArray->Set(thread, enumKeys + offset, key);
66                 enumKeys++;
67             }
68         }
69     }
70 }
71 
GetAllKeys(const JSThread * thread,int end,std::vector<JSTaggedValue> & keyVector)72 void LayoutInfo::GetAllKeys(const JSThread *thread, int end, std::vector<JSTaggedValue> &keyVector)
73 {
74     ASSERT(end <= NumberOfElements());
75     int enumKeys = 0;
76     for (int i = 0; i < end; i++) {
77         JSTaggedValue key = GetKey(i);
78         if (key.IsString()) {
79             keyVector.emplace_back(key);
80             enumKeys++;
81         }
82     }
83 }
84 
GetAllEnumKeys(const JSThread * thread,int end,int offset,TaggedArray * keyArray,uint32_t * keys)85 void LayoutInfo::GetAllEnumKeys(const JSThread *thread, int end, int offset, TaggedArray *keyArray,
86                                 uint32_t *keys)
87 {
88     ASSERT(end <= NumberOfElements());
89     ASSERT_PRINT(offset + end <= static_cast<int>(keyArray->GetLength()),
90                  "keyArray capacity is not enough for dictionary");
91 
92     DISALLOW_GARBAGE_COLLECTION;
93     int enumKeys = 0;
94     for (int i = 0; i < end; i++) {
95         JSTaggedValue key = GetKey(i);
96         if (key.IsString() && GetAttr(i).IsEnumerable()) {
97             keyArray->Set(thread, enumKeys + offset, key);
98             enumKeys++;
99         }
100     }
101     *keys += enumKeys;
102 }
103 
GetAllNames(const JSThread * thread,int end,const JSHandle<TaggedArray> & keyArray,uint32_t * length)104 void LayoutInfo::GetAllNames(const JSThread *thread, int end, const JSHandle<TaggedArray> &keyArray,
105                              uint32_t *length)
106 {
107     DISALLOW_GARBAGE_COLLECTION;
108     int arrayIndex = 0;
109     for (int i = 0; i < end; i++) {
110         JSTaggedValue key = GetKey(i);
111         if (key.IsString()) {
112             PropertyAttributes attr = GetAttr(i);
113             if (attr.IsEnumerable()) {
114                 keyArray->Set(thread, arrayIndex++, key);
115             }
116         }
117     }
118     *length += arrayIndex;
119 }
120 }  // namespace panda::ecmascript
121