• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2024-2025 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 "libabckit/include/c/isa/isa_static.h"
18 #include "libabckit/include/c/metadata_core.h"
19 #include "libabckit/include/c/ir_core.h"
20 
21 #include "helpers/helpers_runtime.h"
22 #include "helpers/helpers.h"
23 
24 #include <gtest/gtest.h>
25 
26 // NOLINTBEGIN(readability-magic-numbers)
27 namespace libabckit::test {
28 
29 namespace {
30 auto g_impl = AbckitGetApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
31 auto g_implI = AbckitGetInspectApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
32 auto g_implM = AbckitGetModifyApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
33 auto g_implG = AbckitGetGraphApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
34 auto g_statG = AbckitGetIsaApiStaticImpl(ABCKIT_VERSION_RELEASE_1_0_0);
35 
TransformCallStaticIr(AbckitGraph * graph,AbckitCoreFunction * func)36 void TransformCallStaticIr(AbckitGraph *graph, AbckitCoreFunction *func)
37 {
38     auto *ret = helpers::FindFirstInst(graph, ABCKIT_ISA_API_STATIC_OPCODE_RETURN_VOID);
39     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
40 
41     auto *call = g_statG->iCreateCallStatic(graph, func, 0);
42     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
43 
44     g_implG->iInsertBefore(call, ret);
45     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
46 }
47 
TransformCallStaticIrArgs(AbckitGraph * graph,AbckitCoreFunction * func)48 void TransformCallStaticIrArgs(AbckitGraph *graph, AbckitCoreFunction *func)
49 {
50     auto *module = g_implI->functionGetModule(func);
51 
52     helpers::ClassByNameContext classCtxFinder1 = {nullptr, "B"};
53     g_implI->moduleEnumerateClasses(module, &classCtxFinder1, helpers::ClassByNameFinder);
54     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
55     ASSERT_NE(classCtxFinder1.klass, nullptr);
56 
57     helpers::ClassByNameContext classCtxFinder2 = {nullptr, "C"};
58     g_implI->moduleEnumerateClasses(module, &classCtxFinder2, helpers::ClassByNameFinder);
59     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
60     ASSERT_NE(classCtxFinder2.klass, nullptr);
61 
62     auto *ret = helpers::FindFirstInst(graph, ABCKIT_ISA_API_STATIC_OPCODE_RETURN_VOID);
63     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
64 
65     auto *obj1 = g_statG->iCreateNewObject(graph, classCtxFinder1.klass);
66     g_implG->iInsertBefore(obj1, ret);
67 
68     auto *obj2 = g_statG->iCreateNewObject(graph, classCtxFinder2.klass);
69     g_implG->iInsertBefore(obj2, ret);
70 
71     auto *call = g_statG->iCreateCallStatic(graph, func, 2, obj1, obj2);
72     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
73 
74     g_implG->iInsertBefore(call, ret);
75     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
76 }
77 
78 }  // namespace
79 
80 class LibAbcKitCallStaticStaticTest : public ::testing::Test {};
81 
82 // Test: test-kind=api, api=IsaApiStaticImpl::iCreateCallStatic, abc-kind=ArkTS2, category=positive, extension=c
TEST_F(LibAbcKitCallStaticStaticTest,LibAbcKitTestCallStatic1)83 TEST_F(LibAbcKitCallStaticStaticTest, LibAbcKitTestCallStatic1)
84 {
85     auto output = helpers::ExecuteStaticAbc(ABCKIT_ABC_DIR "ut/isa/isa_static/call/call_static_static.abc",
86                                             "call_static_static/ETSGLOBAL", "main");
87     EXPECT_TRUE(helpers::Match(output, ""));
88 
89     helpers::TransformMethod(
90         ABCKIT_ABC_DIR "ut/isa/isa_static/call/call_static_static.abc",
91         ABCKIT_ABC_DIR "ut/isa/isa_static/call/call_static_static_modified.abc", "main",
92         [](AbckitFile * /*file*/, AbckitCoreFunction *method, AbckitGraph *graph) {
93             auto *module = g_implI->functionGetModule(method);
94             helpers::ClassByNameContext classCtxFinder = {nullptr, "A"};
95             g_implI->moduleEnumerateClasses(module, &classCtxFinder, helpers::ClassByNameFinder);
96             ASSERT_NE(classCtxFinder.klass, nullptr);
97             helpers::MethodByNameContext methodCtxFinder = {nullptr, "foo"};
98             g_implI->classEnumerateMethods(classCtxFinder.klass, &methodCtxFinder, helpers::MethodByNameFinder);
99             ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
100             ASSERT_NE(methodCtxFinder.method, nullptr);
101             TransformCallStaticIr(graph, methodCtxFinder.method);
102         },
103         [](AbckitGraph *graph) {
104             helpers::BBSchema<AbckitIsaApiStaticOpcode> bb1({{}, {1}, {{}}});
105             std::vector<helpers::InstSchema<AbckitIsaApiStaticOpcode>> insts({
106                 {1, ABCKIT_ISA_API_STATIC_OPCODE_CALL_STATIC, {}},
107                 {0, ABCKIT_ISA_API_STATIC_OPCODE_RETURN_VOID, {}},
108             });
109             helpers::BBSchema<AbckitIsaApiStaticOpcode> bb2({{0}, {2}, insts});
110             helpers::BBSchema<AbckitIsaApiStaticOpcode> bb3({{1}, {}, {}});
111             std::vector<helpers::BBSchema<AbckitIsaApiStaticOpcode>> bbSchemas({bb1, bb2, bb3});
112             helpers::VerifyGraph(graph, bbSchemas);
113         });
114 
115     output = helpers::ExecuteStaticAbc(ABCKIT_ABC_DIR "ut/isa/isa_static/call/call_static_static_modified.abc",
116                                        "call_static_static/ETSGLOBAL", "main");
117     EXPECT_TRUE(helpers::Match(output, "A::foo\n"));
118 }
119 
120 // Test: test-kind=api, api=IsaApiStaticImpl::iCreateCallStatic, abc-kind=ArkTS2, category=positive, extension=c
TEST_F(LibAbcKitCallStaticStaticTest,LibAbcKitTestCallStatic2)121 TEST_F(LibAbcKitCallStaticStaticTest, LibAbcKitTestCallStatic2)
122 {
123     auto output = helpers::ExecuteStaticAbc(ABCKIT_ABC_DIR "ut/isa/isa_static/call/call_static_static.abc",
124                                             "call_static_static/ETSGLOBAL", "main");
125     EXPECT_TRUE(helpers::Match(output, ""));
126 
127     helpers::TransformMethod(
128         ABCKIT_ABC_DIR "ut/isa/isa_static/call/call_static_static.abc",
129         ABCKIT_ABC_DIR "ut/isa/isa_static/call/call_static_static_modified.abc", "main",
130         [](AbckitFile * /*file*/, AbckitCoreFunction *method, AbckitGraph *graph) {
131             auto *module = g_implI->functionGetModule(method);
132             helpers::MethodByNameContext methodCtxFinder = {nullptr, "bar"};
133             g_implI->moduleEnumerateTopLevelFunctions(module, &methodCtxFinder, helpers::MethodByNameFinder);
134             ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
135             ASSERT_NE(methodCtxFinder.method, nullptr);
136             TransformCallStaticIr(graph, methodCtxFinder.method);
137         },
138         [](AbckitGraph *graph) {
139             helpers::BBSchema<AbckitIsaApiStaticOpcode> bb1({{}, {1}, {{}}});
140             std::vector<helpers::InstSchema<AbckitIsaApiStaticOpcode>> insts({
141                 {1, ABCKIT_ISA_API_STATIC_OPCODE_CALL_STATIC, {}},
142                 {0, ABCKIT_ISA_API_STATIC_OPCODE_RETURN_VOID, {}},
143             });
144             helpers::BBSchema<AbckitIsaApiStaticOpcode> bb2({{0}, {2}, insts});
145             helpers::BBSchema<AbckitIsaApiStaticOpcode> bb3({{1}, {}, {}});
146             std::vector<helpers::BBSchema<AbckitIsaApiStaticOpcode>> bbSchemas({bb1, bb2, bb3});
147             helpers::VerifyGraph(graph, bbSchemas);
148         });
149 
150     output = helpers::ExecuteStaticAbc(ABCKIT_ABC_DIR "ut/isa/isa_static/call/call_static_static_modified.abc",
151                                        "call_static_static/ETSGLOBAL", "main");
152     EXPECT_TRUE(helpers::Match(output, "bar\n"));
153 }
154 
155 // Test: test-kind=api, api=IsaApiStaticImpl::iCreateCallStatic, abc-kind=ArkTS2, category=positive, extension=c
TEST_F(LibAbcKitCallStaticStaticTest,LibAbcKitTestCallStatic3)156 TEST_F(LibAbcKitCallStaticStaticTest, LibAbcKitTestCallStatic3)
157 {
158     auto output = helpers::ExecuteStaticAbc(ABCKIT_ABC_DIR "ut/isa/isa_static/call/call_static_static.abc",
159                                             "call_static_static/ETSGLOBAL", "main");
160     EXPECT_TRUE(helpers::Match(output, ""));
161 
162     helpers::TransformMethod(
163         ABCKIT_ABC_DIR "ut/isa/isa_static/call/call_static_static.abc",
164         ABCKIT_ABC_DIR "ut/isa/isa_static/call/call_static_static_modified.abc", "main",
165         [](AbckitFile * /*file*/, AbckitCoreFunction *method, AbckitGraph *graph) {
166             auto *module = g_implI->functionGetModule(method);
167             helpers::ClassByNameContext classCtxFinder = {nullptr, "A"};
168             g_implI->moduleEnumerateClasses(module, &classCtxFinder, helpers::ClassByNameFinder);
169             ASSERT_NE(classCtxFinder.klass, nullptr);
170             helpers::MethodByNameContext methodCtxFinder = {nullptr, "fooArgs"};
171             g_implI->classEnumerateMethods(classCtxFinder.klass, &methodCtxFinder, helpers::MethodByNameFinder);
172             ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
173             ASSERT_NE(methodCtxFinder.method, nullptr);
174             TransformCallStaticIrArgs(graph, methodCtxFinder.method);
175         },
176         [](AbckitGraph *graph) {
177             helpers::BBSchema<AbckitIsaApiStaticOpcode> bb1({{}, {1}, {{}}});
178             std::vector<helpers::InstSchema<AbckitIsaApiStaticOpcode>> insts({
179                 {0, ABCKIT_ISA_API_STATIC_OPCODE_NEWOBJECT, {}},
180                 {1, ABCKIT_ISA_API_STATIC_OPCODE_NEWOBJECT, {}},
181                 {3, ABCKIT_ISA_API_STATIC_OPCODE_CALL_STATIC, {0, 1}},
182                 {2, ABCKIT_ISA_API_STATIC_OPCODE_RETURN_VOID, {}},
183             });
184             helpers::BBSchema<AbckitIsaApiStaticOpcode> bb2({{0}, {2}, insts});
185             helpers::BBSchema<AbckitIsaApiStaticOpcode> bb3({{1}, {}, {}});
186             std::vector<helpers::BBSchema<AbckitIsaApiStaticOpcode>> bbSchemas({bb1, bb2, bb3});
187             helpers::VerifyGraph(graph, bbSchemas);
188         });
189 
190     output = helpers::ExecuteStaticAbc(ABCKIT_ABC_DIR "ut/isa/isa_static/call/call_static_static_modified.abc",
191                                        "call_static_static/ETSGLOBAL", "main");
192     EXPECT_TRUE(helpers::Match(output, "B::foo\nC::foo\n"));
193 }
194 
195 }  // namespace libabckit::test
196 // NOLINTEND(readability-magic-numbers)
197