1 /*
2 * Copyright (c) 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 #include "ecmascript/global_env.h"
17 #include "ecmascript/global_index_map.h"
18
19 namespace panda::ecmascript {
Initialize(const JSThread * thread,JSMutableHandle<PointerToIndexDictionary> globalIndexMap)20 void GlobalIndexMap::Initialize(const JSThread *thread,
21 JSMutableHandle<PointerToIndexDictionary> globalIndexMap)
22 {
23 // GlobalIndex map should be created when it is first used.
24 InitGlobalIndexMap(thread, globalIndexMap);
25
26 // Init GlobalIndex map
27 InitGlobalConst(thread, globalIndexMap);
28 InitGlobalEnv(thread, globalIndexMap);
29 InitBuiltinEntries(thread, globalIndexMap);
30 }
31
InitGlobalIndexMap(const JSThread * thread,JSMutableHandle<PointerToIndexDictionary> globalIndexMap)32 void GlobalIndexMap::InitGlobalIndexMap(const JSThread *thread,
33 JSMutableHandle<PointerToIndexDictionary> globalIndexMap)
34 {
35 if (globalIndexMap.GetTaggedValue().IsHeapObject()) {
36 return ;
37 }
38 globalIndexMap.Update(PointerToIndexDictionary::Create(thread));
39 }
40
InitGlobalConst(const JSThread * thread,JSMutableHandle<PointerToIndexDictionary> globalIndexMap)41 void GlobalIndexMap::InitGlobalConst(const JSThread *thread,
42 JSMutableHandle<PointerToIndexDictionary> globalIndexMap)
43 {
44 ASSERT_PRINT(globalIndexMap.GetTaggedValue().IsHeapObject(), "Global's IndexMap is not existed.");
45 auto globalConst = const_cast<GlobalEnvConstants *>(thread->GlobalConstants());
46 uint32_t constantCount = globalConst->GetConstantCount();
47 JSMutableHandle<PointerToIndexDictionary> globalIndexMapHandle(thread, globalIndexMap);
48 JSMutableHandle<JSTaggedValue> keyHandle(thread, JSTaggedValue::Undefined());
49 JSMutableHandle<JSTaggedValue> valueHandle(thread, JSTaggedValue::Undefined());
50 for (uint32_t index = 0; index < constantCount; index++) {
51 JSTaggedValue objectValue = globalConst->GetGlobalConstantObject(index);
52 if (objectValue.IsHeapObject() && !objectValue.IsString()) {
53 keyHandle.Update(objectValue);
54
55 GlobalIndex globalIndex;
56 globalIndex.UpdateGlobalConstId(index);
57 valueHandle.Update(JSTaggedValue(globalIndex.GetGlobalIndex()));
58 JSHandle<PointerToIndexDictionary> newDict =
59 PointerToIndexDictionary::PutIfAbsent(thread, globalIndexMapHandle, keyHandle, valueHandle);
60 globalIndexMapHandle.Update(newDict);
61 }
62 }
63 globalIndexMap.Update(globalIndexMapHandle);
64 }
65
InitGlobalEnv(const JSThread * thread,JSMutableHandle<PointerToIndexDictionary> globalIndexMap)66 void GlobalIndexMap::InitGlobalEnv(const JSThread *thread,
67 JSMutableHandle<PointerToIndexDictionary> globalIndexMap)
68 {
69 ASSERT_PRINT(globalIndexMap.GetTaggedValue().IsHeapObject(), "Global's IndexMap is not existed.");
70 auto globalEnv = thread->GetEcmaVM()->GetGlobalEnv();
71 uint32_t globalEnvFieldSize = globalEnv->GetGlobalEnvFieldSize();
72 JSMutableHandle<PointerToIndexDictionary> globalIndexMapHandle(thread, globalIndexMap);
73 JSMutableHandle<JSTaggedValue> keyHandle(thread, JSTaggedValue::Undefined());
74 JSMutableHandle<JSTaggedValue> valueHandle(thread, JSTaggedValue::Undefined());
75 for (uint32_t index = 0; index < globalEnvFieldSize; index++) {
76 JSTaggedValue objectValue = globalEnv->GetGlobalEnvObjectByIndex(index).GetTaggedValue();
77 if (objectValue.IsHeapObject()) {
78 keyHandle.Update(objectValue);
79
80 GlobalIndex globalIndex;
81 globalIndex.UpdateGlobalEnvId(index);
82 valueHandle.Update(JSTaggedValue(globalIndex.GetGlobalIndex()));
83 JSHandle<PointerToIndexDictionary> newDict =
84 PointerToIndexDictionary::PutIfAbsent(thread, globalIndexMapHandle, keyHandle, valueHandle);
85 globalIndexMapHandle.Update(newDict);
86 }
87 }
88 globalIndexMap.Update(globalIndexMapHandle);
89 }
90
InitBuiltinEntries(const JSThread * thread,JSMutableHandle<PointerToIndexDictionary> globalIndexMap)91 void GlobalIndexMap::InitBuiltinEntries(const JSThread *thread,
92 JSMutableHandle<PointerToIndexDictionary> globalIndexMap)
93 {
94 ASSERT_PRINT(globalIndexMap.GetTaggedValue().IsHeapObject(), "Global's IndexMap is not existed.");
95 auto builtinEntries = thread->GetBuiltinEntries();
96 uint32_t builtinEntriesCount = BuiltinEntries::COUNT;
97 JSMutableHandle<PointerToIndexDictionary> globalIndexMapHandle(thread, globalIndexMap);
98 JSMutableHandle<JSTaggedValue> keyHandle(thread, JSTaggedValue::Undefined());
99 JSMutableHandle<JSTaggedValue> valueHandle(thread, JSTaggedValue::Undefined());
100 for (uint32_t index = 0; index < builtinEntriesCount; index++) {
101 JSTaggedValue objectValue = builtinEntries.builtin_[index].hClass_;
102 keyHandle.Update(objectValue);
103 if (objectValue.IsHeapObject()) {
104 GlobalIndex globalIndex;
105 globalIndex.UpdateBuiltinEntriesId(index);
106 valueHandle.Update(JSTaggedValue(globalIndex.GetGlobalIndex()));
107 JSHandle<PointerToIndexDictionary> newDict =
108 PointerToIndexDictionary::PutIfAbsent(thread, globalIndexMapHandle, keyHandle, valueHandle);
109 globalIndexMapHandle.Update(newDict);
110 }
111 }
112 globalIndexMap.Update(globalIndexMapHandle);
113 }
114
FindGlobalIndex(JSHandle<PointerToIndexDictionary> globalIndexMap,JSTaggedValue objAddress,GlobalIndex * globalIndex)115 void GlobalIndexMap::FindGlobalIndex(JSHandle<PointerToIndexDictionary> globalIndexMap,
116 JSTaggedValue objAddress, GlobalIndex *globalIndex)
117 {
118 int entry = globalIndexMap->FindEntry(objAddress);
119 if (entry != -1) {
120 *globalIndex = GlobalIndex(globalIndexMap->GetValue(entry).GetInt());
121 }
122 }
123 } // namespace panda::ecmascript
124