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