• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 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 "libabckit/include/c/abckit.h"
17 #include "ir_impl.h"
18 #include "libabckit/include/c/metadata_core.h"
19 #include "libabckit/include/c/ir_core.h"
20 #include "libabckit/include/c/isa/isa_dynamic.h"
21 
22 #include "helpers/helpers.h"
23 #include "helpers/helpers_runtime.h"
24 
25 #include <gtest/gtest.h>
26 
27 namespace libabckit::test {
28 
29 class AbckitScenarioTest : public ::testing::Test {};
30 
31 static auto g_impl = AbckitGetApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
32 static auto g_implI = AbckitGetInspectApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
33 static auto g_implM = AbckitGetModifyApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
34 static auto g_implG = AbckitGetGraphApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
35 static auto g_dynG = AbckitGetIsaApiDynamicImpl(ABCKIT_VERSION_RELEASE_1_0_0);
36 
37 struct UserData {
38     AbckitString *print = nullptr;
39     AbckitString *date = nullptr;
40     AbckitString *getTime = nullptr;
41     AbckitString *str = nullptr;
42     AbckitString *consume = nullptr;
43 };
44 
45 struct VisitData {
46     UserData *ud = nullptr;
47     AbckitInst *time = nullptr;
48 };
49 
CreateEpilog(AbckitInst * inst,AbckitBasicBlock * bb,UserData * userData,AbckitInst * time)50 static void CreateEpilog(AbckitInst *inst, AbckitBasicBlock *bb, UserData *userData, AbckitInst *time)
51 {
52     auto *graph = g_implG->bbGetGraph(bb);
53     while (inst != nullptr) {
54         if (g_dynG->iGetOpcode(inst) == ABCKIT_ISA_API_DYNAMIC_OPCODE_RETURNUNDEFINED) {
55             // Epilog
56             auto *dateClass2 = g_dynG->iCreateTryldglobalbyname(graph, userData->date);
57             ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
58             g_implG->iInsertBefore(dateClass2, inst);
59             ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
60             auto *dateObj2 = g_dynG->iCreateNewobjrange(graph, 1, dateClass2);
61             ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
62             g_implG->iInsertAfter(dateObj2, dateClass2);
63             ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
64             auto *getTime2 = g_dynG->iCreateLdobjbyname(graph, dateObj2, userData->getTime);
65             ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
66             g_implG->iInsertAfter(getTime2, dateObj2);
67             ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
68             auto *time2 = g_dynG->iCreateCallthis0(graph, getTime2, dateObj2);
69             ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
70             g_implG->iInsertAfter(time2, getTime2);
71             ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
72             auto *consume = g_dynG->iCreateLoadString(graph, userData->consume);
73             ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
74             g_implG->iInsertAfter(consume, time2);
75             ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
76 
77             auto *print2 = g_dynG->iCreateTryldglobalbyname(graph, userData->print);
78             ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
79             g_implG->iInsertAfter(print2, consume);
80             ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
81             auto *callArg2 = g_dynG->iCreateCallarg1(graph, print2, consume);
82             ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
83             g_implG->iInsertAfter(callArg2, print2);
84             ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
85             auto *sub = g_dynG->iCreateSub2(graph, time, time2);
86             ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
87             g_implG->iInsertAfter(sub, callArg2);
88             ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
89 
90             auto *print3 = g_dynG->iCreateTryldglobalbyname(graph, userData->print);
91             ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
92             g_implG->iInsertAfter(print3, sub);
93             ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
94             auto *callArg3 = g_dynG->iCreateCallarg1(graph, print3, sub);
95             ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
96             g_implG->iInsertAfter(callArg3, print3);
97             ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
98         }
99         inst = g_implG->iGetNext(inst);
100     }
101 }
102 
TransformIr(AbckitGraph * graph,UserData * userData)103 static void TransformIr(AbckitGraph *graph, UserData *userData)
104 {
105     AbckitBasicBlock *startBB = g_implG->gGetStartBasicBlock(graph);
106     std::vector<AbckitBasicBlock *> succBBs = helpers::BBgetSuccBlocks(startBB);
107     auto *bb = succBBs[0];
108 
109     // Prolog
110     auto *str = g_dynG->iCreateLoadString(graph, userData->str);
111     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
112     g_implG->bbAddInstFront(bb, str);
113     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
114     auto *print = g_dynG->iCreateTryldglobalbyname(graph, userData->print);
115     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
116     g_implG->iInsertAfter(print, str);
117     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
118     auto *callArg = g_dynG->iCreateCallarg1(graph, print, str);
119     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
120     g_implG->iInsertAfter(callArg, print);
121     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
122 
123     auto *dateClass = g_dynG->iCreateTryldglobalbyname(graph, userData->date);
124     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
125     g_implG->iInsertAfter(dateClass, callArg);
126     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
127     auto *dateObj = g_dynG->iCreateNewobjrange(graph, 1, dateClass);
128     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
129     g_implG->iInsertAfter(dateObj, dateClass);
130     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
131     auto *getTime = g_dynG->iCreateLdobjbyname(graph, dateObj, userData->getTime);
132     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
133     g_implG->iInsertAfter(getTime, dateObj);
134     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
135     auto *time = g_dynG->iCreateCallthis0(graph, getTime, dateObj);
136     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
137     g_implG->iInsertAfter(time, getTime);
138     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
139 
140     VisitData vd;
141     vd.ud = userData;
142     vd.time = time;
143 
144     g_implG->gVisitBlocksRpo(graph, &vd, [](AbckitBasicBlock *bb, void *data) {
145         auto *inst = g_implG->bbGetFirstInst(bb);
146 
147         auto *visitData = reinterpret_cast<VisitData *>(data);
148         CreateEpilog(inst, bb, visitData->ud, visitData->time);
149         return true;
150     });
151 }
152 
153 // CC-OFFNXT(G.FUN.01-CPP) test function
GetCorrectBBSchema()154 static std::vector<helpers::BBSchema<AbckitIsaApiDynamicOpcode>> GetCorrectBBSchema()
155 {
156     // NOLINTBEGIN(readability-magic-numbers)
157     std::vector<helpers::BBSchema<AbckitIsaApiDynamicOpcode>> bbSchemas(
158         {{{},
159           {1},
160           {
161               {0, ABCKIT_ISA_API_DYNAMIC_OPCODE_PARAMETER, {}},
162               {1, ABCKIT_ISA_API_DYNAMIC_OPCODE_PARAMETER, {}},
163               {2, ABCKIT_ISA_API_DYNAMIC_OPCODE_PARAMETER, {}},
164               {10, ABCKIT_ISA_API_DYNAMIC_OPCODE_CONSTANT, {}},
165               {11, ABCKIT_ISA_API_DYNAMIC_OPCODE_CONSTANT, {}},
166               {14, ABCKIT_ISA_API_DYNAMIC_OPCODE_CONSTANT, {}},
167           }},
168          {{0},
169           {3, 2},
170           {
171               {3, ABCKIT_ISA_API_DYNAMIC_OPCODE_LOADSTRING, {}},
172               {4, ABCKIT_ISA_API_DYNAMIC_OPCODE_TRYLDGLOBALBYNAME, {}},
173               {5, ABCKIT_ISA_API_DYNAMIC_OPCODE_CALLARG1, {4, 3}},
174               {6, ABCKIT_ISA_API_DYNAMIC_OPCODE_TRYLDGLOBALBYNAME, {}},
175               {7, ABCKIT_ISA_API_DYNAMIC_OPCODE_NEWOBJRANGE, {6}},
176               {8, ABCKIT_ISA_API_DYNAMIC_OPCODE_LDOBJBYNAME, {7}},
177               {9, ABCKIT_ISA_API_DYNAMIC_OPCODE_CALLTHIS0, {8, 7}},
178               {12, ABCKIT_ISA_API_DYNAMIC_OPCODE_LESS, {11, 10}},
179               {13, ABCKIT_ISA_API_DYNAMIC_OPCODE_IF, {12, 14}},
180           }},
181          {{1},
182           {4},
183           {
184               {15, ABCKIT_ISA_API_DYNAMIC_OPCODE_TRYLDGLOBALBYNAME, {}},
185               {16, ABCKIT_ISA_API_DYNAMIC_OPCODE_LOADSTRING, {}},
186               {17, ABCKIT_ISA_API_DYNAMIC_OPCODE_CALLARG1, {15, 16}},
187           }},
188          {{1},
189           {4},
190           {
191               {18, ABCKIT_ISA_API_DYNAMIC_OPCODE_TRYLDGLOBALBYNAME, {}},
192               {19, ABCKIT_ISA_API_DYNAMIC_OPCODE_LOADSTRING, {}},
193               {20, ABCKIT_ISA_API_DYNAMIC_OPCODE_CALLARG1, {18, 19}},
194           }},
195          {{2, 3},
196           {5},
197           {
198               {24, ABCKIT_ISA_API_DYNAMIC_OPCODE_TRYLDGLOBALBYNAME, {}},
199               {25, ABCKIT_ISA_API_DYNAMIC_OPCODE_NEWOBJRANGE, {24}},
200               {26, ABCKIT_ISA_API_DYNAMIC_OPCODE_LDOBJBYNAME, {25}},
201               {27, ABCKIT_ISA_API_DYNAMIC_OPCODE_CALLTHIS0, {26, 25}},
202               {28, ABCKIT_ISA_API_DYNAMIC_OPCODE_LOADSTRING, {}},
203               {29, ABCKIT_ISA_API_DYNAMIC_OPCODE_TRYLDGLOBALBYNAME, {}},
204               {30, ABCKIT_ISA_API_DYNAMIC_OPCODE_CALLARG1, {29, 28}},
205               {31, ABCKIT_ISA_API_DYNAMIC_OPCODE_SUB2, {9, 27}},
206               {32, ABCKIT_ISA_API_DYNAMIC_OPCODE_TRYLDGLOBALBYNAME, {}},
207               {33, ABCKIT_ISA_API_DYNAMIC_OPCODE_CALLARG1, {32, 31}},
208               {34, ABCKIT_ISA_API_DYNAMIC_OPCODE_RETURNUNDEFINED, {}},
209           }},
210          {{4}, {}, {}}});
211     return bbSchemas;
212 }
213 // CC-OFFNXT(huge_method, C_RULE_ID_FUNCTION_SIZE) test, solid logic
214 // Test: test-kind=scenario, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(AbckitScenarioTest,LibAbcKitTestDynamicAddLog)215 TEST_F(AbckitScenarioTest, LibAbcKitTestDynamicAddLog)
216 {
217     auto output = helpers::ExecuteDynamicAbc(ABCKIT_ABC_DIR "scenarios/add_log/add_log_dynamic.abc", "add_log_dynamic");
218     EXPECT_TRUE(helpers::Match(output, "abckit\n"));
219 
220     helpers::TransformMethod(
221         ABCKIT_ABC_DIR "scenarios/add_log/add_log_dynamic.abc",
222         ABCKIT_ABC_DIR "scenarios/add_log/add_log_dynamic_modified.abc", "handle",
223         [](AbckitFile *file, AbckitCoreFunction *, AbckitGraph *graph) {
224             UserData data = {};
225             data.print = g_implM->createString(file, "print", strlen("print"));
226             data.date = g_implM->createString(file, "Date", strlen("Date"));
227             data.getTime = g_implM->createString(file, "getTime", strlen("getTime"));
228             data.str = g_implM->createString(file, "file: src/MyClass, function: MyClass.handle",
229                                              strlen("file: src/MyClass, function: MyClass.handle"));
230             data.consume = g_implM->createString(file, "Ellapsed time:", strlen("Ellapsed time:"));
231 
232             TransformIr(graph, &data);
233         },
234         [](AbckitGraph *graph) {
235             // NOLINTEND(readability-magic-numbers)
236             helpers::VerifyGraph(graph, GetCorrectBBSchema());
237         });
238 
239     output =
240         helpers::ExecuteDynamicAbc(ABCKIT_ABC_DIR "scenarios/add_log/add_log_dynamic_modified.abc", "add_log_dynamic");
241     EXPECT_TRUE(helpers::Match(output,
242                                "file: src/MyClass, function: MyClass.handle\n"
243                                "abckit\n"
244                                "Ellapsed time:\n"
245                                "\\d+\n"));
246 }
247 
248 }  // namespace libabckit::test
249