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 "libabckit/include/c/metadata_core.h"
18 #include "libabckit/include/c/ir_core.h"
19
20 #include "helpers/helpers_runtime.h"
21 #include "helpers/helpers.h"
22 #include "libabckit/src/logger.h"
23 #include <gtest/gtest.h>
24
25 // libabckit::Logger *libabckit::Logger::Logger_ = nullptr;
26
27 // NOLINTBEGIN(readability-magic-numbers)
28 namespace libabckit::test {
29
30 namespace {
31
32 auto g_impl = AbckitGetApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
33 auto g_implI = AbckitGetInspectApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
34 auto g_implM = AbckitGetModifyApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
35 auto g_implG = AbckitGetGraphApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
36 auto g_statG = AbckitGetIsaApiStaticImpl(ABCKIT_VERSION_RELEASE_1_0_0);
37
38 struct TransformStoreArrayByIdxArgs {
39 AbckitGraph *graph = nullptr;
40 enum AbckitStatus expectedStatus = ABCKIT_STATUS_BAD_ARGUMENT;
41 AbckitInst *idx = nullptr;
42 AbckitInst *newValue = nullptr;
43 enum AbckitTypeId valueTypeId = ABCKIT_TYPE_ID_INVALID;
44 };
45
TransformStoreArrayByIdx(TransformStoreArrayByIdxArgs & args,AbckitInst * (* icreateStoreArray)(AbckitGraph *,AbckitInst *,AbckitInst *,AbckitInst *,enum AbckitTypeId))46 void TransformStoreArrayByIdx(TransformStoreArrayByIdxArgs &args,
47 AbckitInst *(*icreateStoreArray)(AbckitGraph *, AbckitInst *, AbckitInst *, AbckitInst *,
48 enum AbckitTypeId))
49 {
50 auto *graph = args.graph;
51 auto expectedStatus = args.expectedStatus;
52 auto *idx = args.idx;
53 auto *newValue = args.newValue;
54 auto valueTypeId = args.valueTypeId;
55
56 AbckitInst *arr = helpers::FindFirstInst(graph, ABCKIT_ISA_API_STATIC_OPCODE_NEWARRAY);
57 ASSERT_NE(arr, nullptr);
58
59 AbckitInst *store = icreateStoreArray(graph, arr, idx, newValue, valueTypeId);
60
61 if (expectedStatus != ABCKIT_STATUS_NO_ERROR && g_impl->getLastError() == expectedStatus) {
62 return;
63 }
64
65 ASSERT_NE(store, nullptr);
66
67 AbckitInst *ret = helpers::FindFirstInst(graph, ABCKIT_ISA_API_STATIC_OPCODE_RETURN);
68 ASSERT_NE(ret, nullptr);
69
70 g_implG->iInsertBefore(store, ret);
71 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
72 }
73 } // namespace
74
75 class LibAbcKitArrayStaticTest : public ::testing::Test {};
76
77 // Test: test-kind=api, api=IsaApiStaticImpl::iCreateStoreArrayWide, abc-kind=ArkTS2, category=positive, extension=c
TEST_F(LibAbcKitArrayStaticTest,LibAbcKitTestStoreArrayWide)78 TEST_F(LibAbcKitArrayStaticTest, LibAbcKitTestStoreArrayWide)
79 {
80 auto output = helpers::ExecuteStaticAbc(ABCKIT_ABC_DIR "ut/isa/isa_static/arrays/store_array_wide.abc",
81 "store_array_wide/ETSGLOBAL", "main");
82 EXPECT_TRUE(helpers::Match(output, "3\n"));
83 helpers::TransformMethod(
84 ABCKIT_ABC_DIR "ut/isa/isa_static/arrays/store_array_wide.abc",
85 ABCKIT_ABC_DIR "ut/isa/isa_static/arrays/store_array_wide_modified.abc", "store_element",
86 [](AbckitFile * /*file*/, AbckitCoreFunction * /*method*/, AbckitGraph *graph) {
87 AbckitTypeId valueTypeId = AbckitTypeId::ABCKIT_TYPE_ID_F64;
88
89 AbckitInst *newValue = g_implG->gFindOrCreateConstantF64(graph, 4);
90 ASSERT_NE(newValue, nullptr);
91 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
92
93 AbckitInst *idx = g_implG->gFindOrCreateConstantI64(graph, 2);
94 ASSERT_NE(idx, nullptr);
95 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
96
97 TransformStoreArrayByIdxArgs args {graph, ABCKIT_STATUS_NO_ERROR, idx, newValue, valueTypeId};
98 TransformStoreArrayByIdx(args, g_statG->iCreateStoreArrayWide);
99 },
100 []([[maybe_unused]] AbckitGraph *graph) {});
101 output = helpers::ExecuteStaticAbc(ABCKIT_ABC_DIR "ut/isa/isa_static/arrays/store_array_wide_modified.abc",
102 "store_array_wide/ETSGLOBAL", "main");
103 EXPECT_TRUE(helpers::Match(output, "4\n"));
104 }
105
106 // Test: test-kind=api, api=IsaApiStaticImpl::iCreateStoreArrayWide, abc-kind=ArkTS2, category=negative
TEST_F(LibAbcKitArrayStaticTest,LibAbcKitTestStoreArrayWideNeg)107 TEST_F(LibAbcKitArrayStaticTest, LibAbcKitTestStoreArrayWideNeg)
108 {
109 auto output = helpers::ExecuteStaticAbc(ABCKIT_ABC_DIR "ut/isa/isa_static/arrays/store_array.abc",
110 "store_array/ETSGLOBAL", "main");
111 EXPECT_TRUE(helpers::Match(output, "3\n"));
112 helpers::TransformMethod(
113 ABCKIT_ABC_DIR "ut/isa/isa_static/arrays/store_array.abc",
114 ABCKIT_ABC_DIR "ut/isa/isa_static/arrays/store_array_modified_neg.abc", "store_element",
115 [](AbckitFile * /*file*/, AbckitCoreFunction * /*method*/, AbckitGraph *graph) {
116 AbckitTypeId valueTypeId = AbckitTypeId::ABCKIT_TYPE_ID_F64;
117
118 AbckitInst *newValue = g_implG->gFindOrCreateConstantF64(graph, 4);
119 ASSERT_NE(newValue, nullptr);
120 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
121
122 AbckitInst *idx = g_implG->gFindOrCreateConstantF64(graph, 2); // idx's type should be I64 or I32
123 ASSERT_NE(idx, nullptr);
124 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
125
126 TransformStoreArrayByIdxArgs args {graph, ABCKIT_STATUS_BAD_ARGUMENT, idx, newValue, valueTypeId};
127 TransformStoreArrayByIdx(args, g_statG->iCreateStoreArrayWide);
128 },
129 []([[maybe_unused]] AbckitGraph *graph) {});
130 }
131
132 // Test: test-kind=api, api=IsaApiStaticImpl::iCreateStoreArray, abc-kind=ArkTS2, category=positive, extension=c
TEST_F(LibAbcKitArrayStaticTest,LibAbcKitTestStoreArray)133 TEST_F(LibAbcKitArrayStaticTest, LibAbcKitTestStoreArray)
134 {
135 auto output = helpers::ExecuteStaticAbc(ABCKIT_ABC_DIR "ut/isa/isa_static/arrays/store_array.abc",
136 "store_array/ETSGLOBAL", "main");
137 EXPECT_TRUE(helpers::Match(output, "3\n"));
138 helpers::TransformMethod(
139 ABCKIT_ABC_DIR "ut/isa/isa_static/arrays/store_array.abc",
140 ABCKIT_ABC_DIR "ut/isa/isa_static/arrays/store_array_modified.abc", "store_element",
141 [](AbckitFile * /*file*/, AbckitCoreFunction * /*method*/, AbckitGraph *graph) {
142 AbckitTypeId valueTypeId = AbckitTypeId::ABCKIT_TYPE_ID_I32;
143
144 AbckitInst *newValue = g_implG->gFindOrCreateConstantI32(graph, 4);
145 ASSERT_NE(newValue, nullptr);
146 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
147
148 AbckitInst *idx = g_implG->gFindOrCreateConstantI32(graph, 2);
149 ASSERT_NE(idx, nullptr);
150 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
151
152 TransformStoreArrayByIdxArgs args {graph, ABCKIT_STATUS_NO_ERROR, idx, newValue, valueTypeId};
153 TransformStoreArrayByIdx(args, g_statG->iCreateStoreArray);
154 },
155 []([[maybe_unused]] AbckitGraph *graph) {});
156 output = helpers::ExecuteStaticAbc(ABCKIT_ABC_DIR "ut/isa/isa_static/arrays/store_array_modified.abc",
157 "store_array/ETSGLOBAL", "main");
158 EXPECT_TRUE(helpers::Match(output, "4\n"));
159 }
160
161 // Test: test-kind=api, api=IsaApiStaticImpl::iCreateStoreArray, abc-kind=ArkTS2, category=negative
TEST_F(LibAbcKitArrayStaticTest,LibAbcKitTestStoreArrayNeg)162 TEST_F(LibAbcKitArrayStaticTest, LibAbcKitTestStoreArrayNeg)
163 {
164 auto output = helpers::ExecuteStaticAbc(ABCKIT_ABC_DIR "ut/isa/isa_static/arrays/store_array.abc",
165 "store_array/ETSGLOBAL", "main");
166 EXPECT_TRUE(helpers::Match(output, "3\n"));
167 helpers::TransformMethod(
168 ABCKIT_ABC_DIR "ut/isa/isa_static/arrays/store_array.abc",
169 ABCKIT_ABC_DIR "ut/isa/isa_static/arrays/store_array_modified_neg.abc", "store_element",
170 [](AbckitFile * /*file*/, AbckitCoreFunction * /*method*/, AbckitGraph *graph) {
171 AbckitTypeId valueTypeId = AbckitTypeId::ABCKIT_TYPE_ID_I32;
172
173 AbckitInst *newValue = g_implG->gFindOrCreateConstantI32(graph, 4);
174 ASSERT_NE(newValue, nullptr);
175 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
176
177 AbckitInst *idx = g_implG->gFindOrCreateConstantI64(graph, 2); // idx's type should be I32
178 ASSERT_NE(idx, nullptr);
179 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
180
181 TransformStoreArrayByIdxArgs args {graph, ABCKIT_STATUS_BAD_ARGUMENT, idx, newValue, valueTypeId};
182 TransformStoreArrayByIdx(args, g_statG->iCreateStoreArray);
183 },
184 []([[maybe_unused]] AbckitGraph *graph) {});
185 }
186
187 // Test: test-kind=api, api=IsaApiStaticImpl::iCreateLoadArray, abc-kind=ArkTS2, category=positive, extension=c
TEST_F(LibAbcKitArrayStaticTest,LibAbcKitTestLoadArray)188 TEST_F(LibAbcKitArrayStaticTest, LibAbcKitTestLoadArray)
189 {
190 auto output = helpers::ExecuteStaticAbc(ABCKIT_ABC_DIR "ut/isa/isa_static/arrays/load_array.abc",
191 "load_array/ETSGLOBAL", "main");
192 EXPECT_TRUE(helpers::Match(output, "1\n"));
193 helpers::TransformMethod(
194 ABCKIT_ABC_DIR "ut/isa/isa_static/arrays/load_array.abc",
195 ABCKIT_ABC_DIR "ut/isa/isa_static/arrays/load_array_modified.abc", "get_element",
196 [](AbckitFile * /*file*/, AbckitCoreFunction * /*method*/, AbckitGraph *graph) {
197 AbckitTypeId returnTypeId = AbckitTypeId::ABCKIT_TYPE_ID_F64;
198
199 AbckitInst *arr = helpers::FindFirstInst(graph, ABCKIT_ISA_API_STATIC_OPCODE_NEWARRAY);
200 ASSERT_NE(arr, nullptr);
201
202 AbckitInst *idx = g_implG->gFindOrCreateConstantI64(graph, 1);
203 ASSERT_NE(idx, nullptr);
204 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
205
206 AbckitInst *ld = g_statG->iCreateLoadArray(graph, arr, idx, returnTypeId);
207 ASSERT_NE(ld, nullptr);
208 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
209
210 AbckitInst *ret = helpers::FindFirstInst(graph, ABCKIT_ISA_API_STATIC_OPCODE_RETURN);
211 ASSERT_NE(ret, nullptr);
212
213 g_implG->iInsertBefore(ld, ret);
214 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
215 g_implG->iSetInput(ret, ld, 0);
216 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
217 },
218 []([[maybe_unused]] AbckitGraph *graph) {});
219 output = helpers::ExecuteStaticAbc(ABCKIT_ABC_DIR "ut/isa/isa_static/arrays/load_array_modified.abc",
220 "load_array/ETSGLOBAL", "main");
221 EXPECT_TRUE(helpers::Match(output, "2\n"));
222 }
223
224 // Test: test-kind=api, api=IsaApiStaticImpl::iCreateLoadArray, abc-kind=ArkTS2, category=negative
TEST_F(LibAbcKitArrayStaticTest,LibAbcKitTestLoadArrayNeg)225 TEST_F(LibAbcKitArrayStaticTest, LibAbcKitTestLoadArrayNeg)
226 {
227 auto output = helpers::ExecuteStaticAbc(ABCKIT_ABC_DIR "ut/isa/isa_static/arrays/load_array.abc",
228 "load_array/ETSGLOBAL", "main");
229 EXPECT_TRUE(helpers::Match(output, "1\n"));
230 helpers::TransformMethod(
231 ABCKIT_ABC_DIR "ut/isa/isa_static/arrays/load_array.abc",
232 ABCKIT_ABC_DIR "ut/isa/isa_static/arrays/load_array_modified_neg.abc", "get_element",
233 [](AbckitFile * /*file*/, AbckitCoreFunction * /*method*/, AbckitGraph *graph) {
234 AbckitTypeId returnTypeId = AbckitTypeId::ABCKIT_TYPE_ID_F64;
235
236 AbckitInst *fakeArr = g_implG->gFindOrCreateConstantI64(graph, 1);
237 ASSERT_NE(fakeArr, nullptr);
238
239 AbckitInst *idx = g_implG->gFindOrCreateConstantI64(graph, 1);
240 ASSERT_NE(idx, nullptr);
241 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
242
243 [[maybe_unused]] AbckitInst *ld = g_statG->iCreateLoadArray(graph, fakeArr, idx, returnTypeId);
244 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_BAD_ARGUMENT);
245 },
246 []([[maybe_unused]] AbckitGraph *graph) {});
247 }
248
249 // Test: test-kind=api, api=IsaApiStaticImpl::iCreateLenArray, abc-kind=ArkTS2, category=positive, extension=c
TEST_F(LibAbcKitArrayStaticTest,LibAbcKitTestLenArray)250 TEST_F(LibAbcKitArrayStaticTest, LibAbcKitTestLenArray)
251 {
252 auto output = helpers::ExecuteStaticAbc(ABCKIT_ABC_DIR "ut/isa/isa_static/arrays/len_array.abc",
253 "len_array/ETSGLOBAL", "main");
254 EXPECT_TRUE(helpers::Match(output, "1\n"));
255 helpers::TransformMethod(
256 ABCKIT_ABC_DIR "ut/isa/isa_static/arrays/len_array.abc",
257 ABCKIT_ABC_DIR "ut/isa/isa_static/arrays/len_array_modified.abc", "get_len",
258 [](AbckitFile * /*file*/, AbckitCoreFunction * /*method*/, AbckitGraph *graph) {
259 AbckitInst *arr = helpers::FindFirstInst(graph, ABCKIT_ISA_API_STATIC_OPCODE_NEWARRAY);
260 ASSERT_NE(arr, nullptr);
261
262 AbckitInst *len = g_statG->iCreateLenArray(graph, arr);
263 ASSERT_NE(len, nullptr);
264 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
265
266 AbckitInst *ret = helpers::FindFirstInst(graph, ABCKIT_ISA_API_STATIC_OPCODE_RETURN);
267 ASSERT_NE(ret, nullptr);
268
269 g_implG->iInsertBefore(len, ret);
270 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
271 g_implG->iSetInput(ret, len, 0);
272 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
273 },
274 []([[maybe_unused]] AbckitGraph *graph) {});
275 output = helpers::ExecuteStaticAbc(ABCKIT_ABC_DIR "ut/isa/isa_static/arrays/len_array_modified.abc",
276 "len_array/ETSGLOBAL", "main");
277 EXPECT_TRUE(helpers::Match(output, "4\n"));
278 }
279
280 // Test: test-kind=api, api=IsaApiStaticImpl::iCreateLenArray, abc-kind=ArkTS2, category=negative
TEST_F(LibAbcKitArrayStaticTest,LibAbcKitTestLenArrayNeg)281 TEST_F(LibAbcKitArrayStaticTest, LibAbcKitTestLenArrayNeg)
282 {
283 auto output = helpers::ExecuteStaticAbc(ABCKIT_ABC_DIR "ut/isa/isa_static/arrays/len_array.abc",
284 "len_array/ETSGLOBAL", "main");
285 EXPECT_TRUE(helpers::Match(output, "1\n"));
286 helpers::TransformMethod(
287 ABCKIT_ABC_DIR "ut/isa/isa_static/arrays/len_array.abc",
288 ABCKIT_ABC_DIR "ut/isa/isa_static/arrays/len_array_modified_neg.abc", "get_len",
289 [](AbckitFile * /*file*/, AbckitCoreFunction * /*method*/, AbckitGraph *graph) {
290 AbckitInst *fakeArr = g_implG->gFindOrCreateConstantI64(graph, 1);
291 ASSERT_NE(fakeArr, nullptr);
292
293 [[maybe_unused]] AbckitInst *len = g_statG->iCreateLenArray(graph, fakeArr);
294 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_BAD_ARGUMENT);
295 },
296 []([[maybe_unused]] AbckitGraph *graph) {});
297 }
298
299 // Test: test-kind=api, api=IsaApiStaticImpl::iCreateLoadConstArray, abc-kind=ArkTS2, category=positive, extension=c
TEST_F(LibAbcKitArrayStaticTest,LibAbcKitTestLoadConstArray)300 TEST_F(LibAbcKitArrayStaticTest, LibAbcKitTestLoadConstArray)
301 {
302 auto output = helpers::ExecuteStaticAbc(ABCKIT_ABC_DIR "ut/isa/isa_static/arrays/load_const_array.abc",
303 "load_const_array/ETSGLOBAL", "main");
304 EXPECT_TRUE(helpers::Match(output, "1\n"));
305 helpers::TransformMethod(
306 ABCKIT_ABC_DIR "ut/isa/isa_static/arrays/load_const_array.abc",
307 ABCKIT_ABC_DIR "ut/isa/isa_static/arrays/load_const_array_modified.abc", "getElement",
308 [](AbckitFile *file, AbckitCoreFunction * /*method*/, AbckitGraph *graph) {
309 auto arr = std::vector<AbckitLiteral *>({
310 g_implM->createLiteralU32(file, 4),
311 g_implM->createLiteralU32(file, 2),
312 g_implM->createLiteralU32(file, 3),
313 });
314 auto litArray = g_implM->createLiteralArray(file, arr.data(), arr.size());
315 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
316
317 auto *loadConstArray = g_statG->iCreateLoadConstArray(graph, litArray);
318 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
319
320 auto *ret = helpers::FindFirstInst(graph, ABCKIT_ISA_API_STATIC_OPCODE_RETURN);
321 ASSERT_NE(ret, nullptr);
322 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
323
324 g_implG->iInsertBefore(loadConstArray, ret);
325 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
326 g_implG->iSetInput(ret, loadConstArray, 0);
327 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
328
329 helpers::ReplaceInst(ret, g_statG->iCreateReturn(graph, loadConstArray));
330 },
331 []([[maybe_unused]] AbckitGraph *graph) {});
332 output = helpers::ExecuteStaticAbc(ABCKIT_ABC_DIR "ut/isa/isa_static/arrays/load_const_array_modified.abc",
333 "load_const_array/ETSGLOBAL", "main");
334 EXPECT_TRUE(helpers::Match(output, "4\n"));
335 }
336
337 } // namespace libabckit::test
338 // NOLINTEND(readability-magic-numbers)
339