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 20namespace panda::ecmascript { 21void 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 33void 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 42void 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 67void 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 92void 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 116void 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