1 /*
2 * Copyright (c) 2021 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_vm.h"
17 #include "ecmascript/ic/invoke_cache.h"
18 #include "ecmascript/object_factory.h"
19 #include "ecmascript/tests/test_helper.h"
20
21 using namespace panda::ecmascript;
22 namespace panda::test {
23 class ICInvokeTest : public testing::Test {
24 public:
SetUpTestCase()25 static void SetUpTestCase()
26 {
27 GTEST_LOG_(INFO) << "SetUpTestCase";
28 }
29
TearDownTestCase()30 static void TearDownTestCase()
31 {
32 GTEST_LOG_(INFO) << "TearDownCase";
33 }
34
SetUp()35 void SetUp() override
36 {
37 TestHelper::CreateEcmaVMWithScope(ecmaVm, thread, scope);
38 }
39
TearDown()40 void TearDown() override
41 {
42 TestHelper::DestroyEcmaVMWithScope(ecmaVm, scope);
43 }
44
45 EcmaVM *ecmaVm = nullptr;
46 EcmaHandleScope *scope {nullptr};
47 JSThread *thread {nullptr};
48 };
49
HWTEST_F_L0(ICInvokeTest,SetMonoConstuctCacheSlot)50 HWTEST_F_L0(ICInvokeTest, SetMonoConstuctCacheSlot)
51 {
52 auto globalEnv = ecmaVm->GetGlobalEnv();
53 auto factory = ecmaVm->GetFactory();
54 JSHandle<JSFunction> func = factory->NewJSFunction(globalEnv);
55 func.GetTaggedValue().GetTaggedObject()->GetClass()->SetClassConstructor(true);
56
57 JSHandle<TaggedArray> array = factory->NewTaggedArray(10);
58 uint32_t slotId = 5;
59 bool setResult = InvokeCache::SetMonoConstuctCacheSlot(
60 thread, static_cast<ProfileTypeInfo *>(*array), slotId, func.GetTaggedValue(), JSTaggedValue(123));
61 ASSERT_TRUE(setResult);
62 ASSERT_EQ(array->Get(thread, slotId), func.GetTaggedValue());
63 ASSERT_EQ(array->Get(thread, slotId + 1), JSTaggedValue(123));
64 }
65
HWTEST_F_L0(ICInvokeTest,SetPolyConstuctCacheSlot)66 HWTEST_F_L0(ICInvokeTest, SetPolyConstuctCacheSlot)
67 {
68 auto globalEnv = ecmaVm->GetGlobalEnv();
69 auto factory = ecmaVm->GetFactory();
70 JSHandle<TaggedArray> array1 = factory->NewTaggedArray(3);
71 JSHandle<TaggedArray> array2 = factory->NewTaggedArray(3);
72
73 JSHandle<JSFunction> func0 = factory->NewJSFunction(globalEnv);
74 func0.GetTaggedValue().GetTaggedObject()->GetClass()->SetClassConstructor(true);
75 array1->Set(thread, 0, func0.GetTaggedValue());
76 array2->Set(thread, 0, JSTaggedValue(123));
77 JSHandle<JSFunction> func1 = factory->NewJSFunction(globalEnv);
78 func1.GetTaggedValue().GetTaggedObject()->GetClass()->SetClassConstructor(true);
79 array1->Set(thread, 1, func1.GetTaggedValue());
80 array2->Set(thread, 1, JSTaggedValue(456));
81 JSHandle<JSFunction> func2 = factory->NewJSFunction(globalEnv);
82 func2.GetTaggedValue().GetTaggedObject()->GetClass()->SetClassConstructor(true);
83 array1->Set(thread, 2, func2.GetTaggedValue());
84 array2->Set(thread, 2, JSTaggedValue(789));
85
86 JSHandle<TaggedArray> array = factory->NewTaggedArray(10);
87 uint32_t slotId = 5;
88 bool setResult = InvokeCache::SetPolyConstuctCacheSlot(
89 thread, static_cast<ProfileTypeInfo *>(*array), slotId, 3, array1.GetTaggedValue(), array2.GetTaggedValue());
90 ASSERT_TRUE(setResult);
91 JSTaggedValue slot = array->Get(thread, slotId);
92 ASSERT_TRUE(slot.IsTaggedArray());
93 JSHandle<TaggedArray> slotArray(thread, slot);
94 ASSERT_EQ(slotArray->Get(thread, 0), func0.GetTaggedValue());
95 ASSERT_EQ(slotArray->Get(thread, 1), JSTaggedValue(123));
96 ASSERT_EQ(slotArray->Get(thread, 2), func1.GetTaggedValue());
97 ASSERT_EQ(slotArray->Get(thread, 3), JSTaggedValue(456));
98 ASSERT_EQ(slotArray->Get(thread, 4), func2.GetTaggedValue());
99 ASSERT_EQ(slotArray->Get(thread, 5), JSTaggedValue(789));
100 ASSERT_EQ(array->Get(thread, slotId + 1), JSTaggedValue::Hole());
101 }
102
HWTEST_F_L0(ICInvokeTest,CheckPolyInvokeCache)103 HWTEST_F_L0(ICInvokeTest, CheckPolyInvokeCache)
104 {
105 auto globalEnv = ecmaVm->GetGlobalEnv();
106 auto factory = ecmaVm->GetFactory();
107 JSHandle<TaggedArray> array = factory->NewTaggedArray(6);
108
109 JSHandle<JSFunction> func0 = factory->NewJSFunction(globalEnv);
110 JSHandle<JSFunction> func1 = factory->NewJSFunction(globalEnv);
111 JSHandle<JSFunction> func2 = factory->NewJSFunction(globalEnv);
112 JSHandle<JSFunction> func3 = factory->NewJSFunction(globalEnv);
113 array->Set(thread, 0, func0.GetTaggedValue());
114 array->Set(thread, 1, JSTaggedValue(123));
115 array->Set(thread, 2, func1.GetTaggedValue());
116 array->Set(thread, 3, JSTaggedValue(456));
117 array->Set(thread, 4, func2.GetTaggedValue());
118 array->Set(thread, 5, JSTaggedValue(789));
119
120 JSTaggedValue testValue0 = InvokeCache::CheckPolyInvokeCache(array.GetTaggedValue(), func0.GetTaggedValue());
121 ASSERT_EQ(testValue0, JSTaggedValue(123));
122 JSTaggedValue testValue1 = InvokeCache::CheckPolyInvokeCache(array.GetTaggedValue(), func1.GetTaggedValue());
123 ASSERT_EQ(testValue1, JSTaggedValue(456));
124 JSTaggedValue testValue2 = InvokeCache::CheckPolyInvokeCache(array.GetTaggedValue(), func2.GetTaggedValue());
125 ASSERT_EQ(testValue2, JSTaggedValue(789));
126 JSTaggedValue testValue3 = InvokeCache::CheckPolyInvokeCache(array.GetTaggedValue(), func3.GetTaggedValue());
127 ASSERT_EQ(testValue3, JSTaggedValue::Hole());
128 }
129 } // namespace panda::test