• 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 "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