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/builtin_entries.h"
17#include "ecmascript/ecma_context.h"
18#include "ecmascript/global_env.h"
19#include "ecmascript/global_env_constants.h"
20#include "ecmascript/global_index.h"
21#include "ecmascript/global_index_map.h"
22#include "ecmascript/tests/test_helper.h"
23
24using namespace panda::ecmascript;
25
26namespace panda::test {
27class GlobalIndexMapTest :  public BaseTestWithScope<false> {
28};
29
30/**
31 * @tc.name: InitGlobalIndexMap
32 * @tc.desc: Check whether InitGlobalIndexMap can initialize dictionary.
33 * @tc.type: FUNC
34 * @tc.require:
35 */
36HWTEST_F_L0(GlobalIndexMapTest, GlobalIndexMap_initGlobalIndexMap)
37{
38    JSMutableHandle<PointerToIndexDictionary> globalIndexMap(
39        GlobalIndexMap::GetGlobalIndexMap(thread->GetCurrentEcmaContext()).GetAddress());
40    EXPECT_NE(globalIndexMap.GetTaggedValue().IsHeapObject(), true);
41    GlobalIndexMap::InitGlobalIndexMap(thread, globalIndexMap);
42    globalIndexMap.Update(GlobalIndexMap::GetGlobalIndexMap(thread->GetCurrentEcmaContext()));
43    EXPECT_EQ(globalIndexMap.GetTaggedValue().IsHeapObject(), true);
44}
45
46/**
47 * @tc.name: InitGlobalConst
48 * @tc.desc: Check whether GlobalConst can be find in the GlobalMap.
49 * @tc.type: FUNC
50 * @tc.require:
51 */
52HWTEST_F_L0(GlobalIndexMapTest, GlobalIndexMap_initGlobalConst)
53{
54    JSMutableHandle<PointerToIndexDictionary> globalIndexMap(
55        GlobalIndexMap::GetGlobalIndexMap(thread->GetCurrentEcmaContext()).GetAddress());
56    EXPECT_NE(globalIndexMap.GetTaggedValue().IsHeapObject(), true);
57    GlobalIndexMap::InitGlobalIndexMap(thread, globalIndexMap);
58    GlobalIndexMap::InitGlobalConst(thread, globalIndexMap);
59    globalIndexMap.Update(GlobalIndexMap::GetGlobalIndexMap(thread->GetCurrentEcmaContext()));
60    EXPECT_EQ(globalIndexMap.GetTaggedValue().IsHeapObject(), true);
61    auto globalConst = const_cast<GlobalEnvConstants *>(thread->GlobalConstants());
62    uint32_t constantCount = globalConst->GetConstantCount();
63    for (uint32_t index = 0; index < constantCount; index++) {
64        JSTaggedValue objectValue = globalConst->GetGlobalConstantObject(index);
65        if (objectValue.IsHeapObject() && !objectValue.IsString()) {
66            GlobalIndex rootIndex;
67            GlobalIndexMap::FindGlobalIndex(globalIndexMap, objectValue, &rootIndex);
68            EXPECT_EQ(static_cast<int>(index), rootIndex.GetGlobalConstId());
69            GlobalIndex globalConstGlobalIndex;
70            globalConstGlobalIndex.UpdateGlobalConstId(index);
71            EXPECT_EQ(globalConstGlobalIndex, rootIndex);
72        }
73    }
74}
75
76/**
77 * @tc.name: InitGlobalEnv
78 * @tc.desc: Check whether GlobalEnv can be find in the GlobalMap.
79 * @tc.type: FUNC
80 * @tc.require:
81 */
82HWTEST_F_L0(GlobalIndexMapTest, GlobalIndexMap_initGlobalEnv)
83{
84    JSMutableHandle<PointerToIndexDictionary> globalIndexMap(
85        GlobalIndexMap::GetGlobalIndexMap(thread->GetCurrentEcmaContext()).GetAddress());
86    EXPECT_NE(globalIndexMap.GetTaggedValue().IsHeapObject(), true);
87    GlobalIndexMap::InitGlobalIndexMap(thread, globalIndexMap);
88    GlobalIndexMap::InitGlobalEnv(thread, globalIndexMap);
89    globalIndexMap.Update(GlobalIndexMap::GetGlobalIndexMap(thread->GetCurrentEcmaContext()));
90    EXPECT_EQ(globalIndexMap.GetTaggedValue().IsHeapObject(), true);
91    auto globalEnv = thread->GetEcmaVM()->GetGlobalEnv();
92    uint32_t globalEnvFieldSize = globalEnv->GetGlobalEnvFieldSize();
93    for (uint32_t index = 0; index < globalEnvFieldSize; index++) {
94        JSTaggedValue objectValue = globalEnv->GetGlobalEnvObjectByIndex(index).GetTaggedValue();
95        if (objectValue.IsHeapObject()) {
96            GlobalIndex rootIndex;
97            GlobalIndexMap::FindGlobalIndex(globalIndexMap, objectValue, &rootIndex);
98            EXPECT_EQ(static_cast<int>(index), rootIndex.GetGlobalEnvId());
99            if (index != rootIndex.GetGlobalEnvId()) {
100                objectValue.D();
101            }
102            GlobalIndex globalEnvGlobalIndex;
103            globalEnvGlobalIndex.UpdateGlobalEnvId(index);
104            EXPECT_EQ(globalEnvGlobalIndex, rootIndex);
105        }
106    }
107}
108} // namespace panda::test