• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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