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