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 <gtest/gtest.h>
17 #include <cstring>
18
19 #include "libabckit/include/c/abckit.h"
20 #include "libabckit/include/c/isa/isa_dynamic.h"
21 #include "helpers/helpers.h"
22 #include "helpers/helpers_runtime.h"
23 #include "libabckit/include/c/metadata_core.h"
24
25 namespace libabckit::test {
26
27 namespace {
28
29 auto g_impl = AbckitGetApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
30 auto g_implI = AbckitGetInspectApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
31 auto g_implM = AbckitGetModifyApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
32 auto g_implG = AbckitGetGraphApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
33 auto g_dynG = AbckitGetIsaApiDynamicImpl(ABCKIT_VERSION_RELEASE_1_0_0);
34 auto g_statG = AbckitGetIsaApiStaticImpl(ABCKIT_VERSION_RELEASE_1_0_0);
35
__anon76a6ab150202(AbckitGraph *graph) 36 auto g_dynamicCreateString2Lambda = [](AbckitGraph *graph) {
37 // NOLINTBEGIN(readability-magic-numbers)
38 std::vector<helpers::InstSchema<AbckitIsaApiDynamicOpcode>> insts1(
39 {{1, ABCKIT_ISA_API_DYNAMIC_OPCODE_PARAMETER, {}},
40 {2, ABCKIT_ISA_API_DYNAMIC_OPCODE_PARAMETER, {}},
41 {14, ABCKIT_ISA_API_DYNAMIC_OPCODE_PARAMETER, {}}});
42 helpers::BBSchema<AbckitIsaApiDynamicOpcode> bb1({{}, {1}, insts1});
43 std::vector<helpers::InstSchema<AbckitIsaApiDynamicOpcode>> insts2({
44 {3, ABCKIT_ISA_API_DYNAMIC_OPCODE_LOADSTRING, {}},
45 {4, ABCKIT_ISA_API_DYNAMIC_OPCODE_LDLEXVAR, {}},
46 {5, ABCKIT_ISA_API_DYNAMIC_OPCODE_CALLARG1, {4, 3}},
47 {6, ABCKIT_ISA_API_DYNAMIC_OPCODE_LOADSTRING, {}},
48 {7, ABCKIT_ISA_API_DYNAMIC_OPCODE_LDLEXVAR, {}},
49 {8, ABCKIT_ISA_API_DYNAMIC_OPCODE_CALLARG1, {7, 6}},
50 {9, ABCKIT_ISA_API_DYNAMIC_OPCODE_LOADSTRING, {}},
51 {10, ABCKIT_ISA_API_DYNAMIC_OPCODE_LDLEXVAR, {}},
52 {11, ABCKIT_ISA_API_DYNAMIC_OPCODE_CALLARG1, {10, 9}},
53 {12, ABCKIT_ISA_API_DYNAMIC_OPCODE_RETURNUNDEFINED, {}},
54 });
55 helpers::BBSchema<AbckitIsaApiDynamicOpcode> bb2({{0}, {2}, insts2});
56 helpers::BBSchema<AbckitIsaApiDynamicOpcode> bb3({{1}, {}, {}});
57 std::vector<helpers::BBSchema<AbckitIsaApiDynamicOpcode>> bbSchemas({bb1, bb2, bb3});
58 // NOLINTEND(readability-magic-numbers)
59 helpers::VerifyGraph(graph, bbSchemas);
60 };
61
62 } // namespace
63
64 class LibAbcKitModifyApiStringsTest : public ::testing::Test {};
65
66 struct UserData {
67 AbckitFile *file = nullptr;
68 };
69
70 // Test: test-kind=api, api=ModifyApiImpl::createString, abc-kind=ArkTS2, category=positive, extension=c
TEST_F(LibAbcKitModifyApiStringsTest,StaticCreateString)71 TEST_F(LibAbcKitModifyApiStringsTest, StaticCreateString)
72 {
73 UserData userData = {};
74 auto testImpl = [&userData]() {
75 auto abckitstr = g_implM->createString(userData.file, "newString", strlen("newString"));
76 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
77 ASSERT_NE(abckitstr, nullptr);
78
79 auto str = helpers::AbckitStringToString(abckitstr);
80 ASSERT_EQ(std::strncmp(str.data(), "newString", sizeof("newString")), 0);
81 };
82
83 helpers::TransformMethod(
84 ABCKIT_ABC_DIR "ut/metadata_core/modify_api/strings/strings_static.abc",
85 ABCKIT_ABC_DIR "ut/metadata_core/modify_api/strings/strings_static_modified.abc", "main",
86 [&](AbckitFile *, AbckitCoreFunction *method, AbckitGraph *) {
87 userData.file = g_implI->functionGetFile(method);
88 testImpl();
89 },
90 []([[maybe_unused]] AbckitGraph *graph) {});
91 }
92
93 // Test: test-kind=api, api=ModifyApiImpl::createString, abc-kind=ArkTS2, category=positive, extension=c
TEST_F(LibAbcKitModifyApiStringsTest,StaticCreateString2)94 TEST_F(LibAbcKitModifyApiStringsTest, StaticCreateString2)
95 {
96 UserData userData = {};
97 auto testImpl = [&userData](AbckitGraph *graph) {
98 AbckitInst *callOp = helpers::FindFirstInst(graph, ABCKIT_ISA_API_STATIC_OPCODE_CALL_STATIC);
99 auto consoleLogStr = helpers::FindMethodByName(userData.file, "ConsoleLogStr");
100
101 auto str1 = g_implM->createString(userData.file, "string1", strlen("string1"));
102 auto loadString1 = g_statG->iCreateLoadString(graph, str1);
103 g_implG->iInsertAfter(loadString1, callOp);
104 AbckitInst *log1 = g_statG->iCreateCallStatic(graph, consoleLogStr, 1, loadString1);
105 g_implG->iInsertAfter(log1, loadString1);
106
107 auto str2 = g_implM->createString(userData.file, "string2", strlen("string2"));
108 auto loadString2 = g_statG->iCreateLoadString(graph, str2);
109 g_implG->iInsertAfter(loadString2, log1);
110 AbckitInst *log2 = g_statG->iCreateCallStatic(graph, consoleLogStr, 1, loadString2);
111 g_implG->iInsertAfter(log2, loadString2);
112 };
113
114 helpers::TransformMethod(
115 ABCKIT_ABC_DIR "ut/metadata_core/modify_api/strings/strings_static.abc",
116 ABCKIT_ABC_DIR "ut/metadata_core/modify_api/strings/strings_static_modify.abc", "main",
117 [&](AbckitFile *, AbckitCoreFunction *method, AbckitGraph *graph) {
118 userData.file = g_implI->functionGetFile(method);
119
120 testImpl(graph);
121 },
122 [](AbckitGraph *graph) {
123 std::vector<helpers::BBSchema<AbckitIsaApiStaticOpcode>> bbSchemas(
124 {{{}, {1}, {}},
125 {{0},
126 {2},
127 {
128 {0, ABCKIT_ISA_API_STATIC_OPCODE_LOADSTRING, {}},
129 {1, ABCKIT_ISA_API_STATIC_OPCODE_CALL_STATIC, {0}},
130 {2, ABCKIT_ISA_API_STATIC_OPCODE_LOADSTRING, {}},
131 {3, ABCKIT_ISA_API_STATIC_OPCODE_CALL_STATIC, {2}},
132 {4, ABCKIT_ISA_API_STATIC_OPCODE_LOADSTRING, {}},
133 {5, ABCKIT_ISA_API_STATIC_OPCODE_CALL_STATIC, {4}},
134 {6, ABCKIT_ISA_API_STATIC_OPCODE_RETURN_VOID, {}},
135 }},
136 {{1}, {}, {}}});
137 helpers::VerifyGraph(graph, bbSchemas);
138 });
139 }
140
141 // Test: test-kind=api, api=ModifyApiImpl::createString, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(LibAbcKitModifyApiStringsTest,DynamicCreateString)142 TEST_F(LibAbcKitModifyApiStringsTest, DynamicCreateString)
143 {
144 UserData userData = {};
145 auto testImpl = [&userData]() {
146 auto abckitstr = g_implM->createString(userData.file, "newString", strlen("newString"));
147 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
148 ASSERT_NE(abckitstr, nullptr);
149
150 auto str = helpers::AbckitStringToString(abckitstr);
151 ASSERT_EQ(std::strncmp(str.data(), "newString", sizeof("newString")), 0);
152 };
153
154 helpers::TransformMethod(
155 ABCKIT_ABC_DIR "ut/metadata_core/modify_api/strings/strings_dynamic.abc",
156 ABCKIT_ABC_DIR "ut/metadata_core/modify_api/strings/strings_dynamic.abc", "main",
157 [&](AbckitFile *, AbckitCoreFunction *method, AbckitGraph *) {
158 userData.file = g_implI->functionGetFile(method);
159
160 testImpl();
161 },
162 []([[maybe_unused]] AbckitGraph *graph) {});
163 }
164
165 // CC-OFFNXT(huge_method, C_RULE_ID_FUNCTION_SIZE) test, solid logic
166 // Test: test-kind=api, api=ModifyApiImpl::createString, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(LibAbcKitModifyApiStringsTest,DynamicCreateString2)167 TEST_F(LibAbcKitModifyApiStringsTest, DynamicCreateString2)
168 {
169 auto output = helpers::ExecuteDynamicAbc(ABCKIT_ABC_DIR "ut/metadata_core/modify_api/strings/strings_dynamic.abc",
170 "strings_dynamic");
171 EXPECT_TRUE(helpers::Match(output, "testString\n"));
172
173 UserData userData = {};
174 auto testImpl = [&userData](AbckitGraph *graph) {
175 AbckitInst *callOp = helpers::FindFirstInst(graph, ABCKIT_ISA_API_DYNAMIC_OPCODE_CALLARG1);
176
177 auto str1 = g_implM->createString(userData.file, "string1", strlen("string1"));
178 auto str2 = g_implM->createString(userData.file, "string2", strlen("string2"));
179
180 auto loadString1 = g_dynG->iCreateLoadString(graph, str1);
181 g_implG->iInsertAfter(loadString1, callOp);
182 auto *consoleLog1 = g_dynG->iCreateLdlexvar(graph, 0, 0);
183 g_implG->iInsertAfter(consoleLog1, loadString1);
184 AbckitInst *log1 = g_dynG->iCreateCallarg1(graph, consoleLog1, loadString1);
185 g_implG->iInsertAfter(log1, consoleLog1);
186
187 auto loadString2 = g_dynG->iCreateLoadString(graph, str2);
188 g_implG->iInsertAfter(loadString2, log1);
189 auto *consoleLog2 = g_dynG->iCreateLdlexvar(graph, 0, 0);
190 g_implG->iInsertAfter(consoleLog2, loadString2);
191 AbckitInst *log2 = g_dynG->iCreateCallarg1(graph, consoleLog2, loadString2);
192 g_implG->iInsertAfter(log2, consoleLog2);
193 };
194
195 helpers::TransformMethod(
196 ABCKIT_ABC_DIR "ut/metadata_core/modify_api/strings/strings_dynamic.abc",
197 ABCKIT_ABC_DIR "ut/metadata_core/modify_api/strings/strings_dynamic_modified.abc", "main",
198 [&](AbckitFile *, AbckitCoreFunction *method, AbckitGraph *graph) {
199 userData.file = g_implI->functionGetFile(method);
200
201 testImpl(graph);
202 },
203 g_dynamicCreateString2Lambda);
204
205 // NOTE: ExecuteDynamicAbc
206 }
207
208 } // namespace libabckit::test
209