• 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/metadata_core.h"
18 #include "libabckit/include/c/ir_core.h"
19 
20 #include "helpers/helpers_runtime.h"
21 #include "helpers/helpers.h"
22 
23 #include <gtest/gtest.h>
24 
25 namespace libabckit::test {
26 
27 namespace {
28 auto g_impl = AbckitGetApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
29 auto g_implI = AbckitGetInspectApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
30 auto g_implM = AbckitGetModifyApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
31 auto g_implG = AbckitGetGraphApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
32 auto g_statG = AbckitGetIsaApiStaticImpl(ABCKIT_VERSION_RELEASE_1_0_0);
33 
TransformIrNegativeInst(AbckitGraph * graph,AbckitFile * file,AbckitCoreClass * classA)34 void TransformIrNegativeInst(AbckitGraph *graph, AbckitFile *file, AbckitCoreClass *classA)
35 {
36     AbckitInst *initObj = helpers::FindFirstInst(graph, ABCKIT_ISA_API_STATIC_OPCODE_INITOBJECT);
37     ASSERT_NE(initObj, nullptr);
38     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
39 
40     AbckitInst *ret = helpers::FindFirstInst(graph, ABCKIT_ISA_API_STATIC_OPCODE_RETURN);
41     ASSERT_NE(ret, nullptr);
42     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
43 
44     auto *type = g_implM->createReferenceType(file, classA);
45     ASSERT_NE(type, nullptr);
46     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
47 
48     AbckitInst *isInstance = g_statG->iCreateIsInstance(graph, initObj, type);
49     ASSERT_NE(isInstance, nullptr);
50     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
51 
52     AbckitInst *idx = g_implG->gFindOrCreateConstantI64(graph, 1);
53     g_implG->iSetInput(isInstance, idx, 0);
54     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
55 
56     g_implG->iInsertAfter(isInstance, initObj);
57     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
58 
59     helpers::ReplaceInst(ret, g_statG->iCreateReturn(graph, isInstance));
60     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
61 }
62 
TransformIrNegativeBB(AbckitGraph * graph)63 void TransformIrNegativeBB(AbckitGraph *graph)
64 {
65     AbckitBasicBlock *bbEnd = g_implG->gGetEndBasicBlock(graph);
66     AbckitBasicBlock *bb2 = g_implG->gGetBasicBlock(graph, 2);
67     g_implG->bbAppendSuccBlock(bbEnd, bb2);
68     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
69 }
70 
TransformIrNegativeBinInst(AbckitGraph * graph)71 void TransformIrNegativeBinInst(AbckitGraph *graph)
72 {
73     AbckitInst *loadString = helpers::FindFirstInst(graph, ABCKIT_ISA_API_STATIC_OPCODE_LOADSTRING);
74     ASSERT_NE(loadString, nullptr);
75     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
76 
77     AbckitInst *ret = helpers::FindFirstInst(graph, ABCKIT_ISA_API_STATIC_OPCODE_RETURN);
78     ASSERT_NE(ret, nullptr);
79     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
80 
81     AbckitInst *idx = g_implG->gFindOrCreateConstantI64(graph, 5);
82     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
83 
84     AbckitInst *addInst = g_statG->iCreateAdd(graph, loadString, idx);
85     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
86 
87     g_implG->iInsertBefore(addInst, ret);
88     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
89 }
90 
91 }  // namespace
92 
93 class LibAbcKitGraphVerifierTest : public ::testing::Test {};
94 
95 // Test: test-kind=internal, abc-kind=ArkTS2, category=internal
TEST_F(LibAbcKitGraphVerifierTest,LibAbcKitTestGraphVerifierInst)96 TEST_F(LibAbcKitGraphVerifierTest, LibAbcKitTestGraphVerifierInst)
97 {
98     constexpr auto INPUT_PATH = ABCKIT_ABC_DIR "ut/ir_core/graph_verifier/graph_verifier.abc";
99     auto output = helpers::ExecuteStaticAbc(INPUT_PATH, "graph_verifier/ETSGLOBAL", "main");
100     EXPECT_TRUE(helpers::Match(output, "123\nfalse\n"));
101 
102     AbckitFile *file = g_impl->openAbc(INPUT_PATH, strlen(INPUT_PATH));
103     auto *method = helpers::FindMethodByName(file, "foo");
104     ASSERT_NE(method, nullptr);
105     auto *module = g_implI->functionGetModule(method);
106     helpers::ClassByNameContext classCtxFinder = {nullptr, "A"};
107     g_implI->moduleEnumerateClasses(module, &classCtxFinder, helpers::ClassByNameFinder);
108     ASSERT_NE(classCtxFinder.klass, nullptr);
109 
110     AbckitGraph *graph = g_implI->createGraphFromFunction(method);
111     TransformIrNegativeInst(graph, g_implI->functionGetFile(method), classCtxFinder.klass);
112     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
113     g_implM->functionSetGraph(method, graph);
114     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_BAD_ARGUMENT);
115     g_impl->destroyGraph(graph);
116 
117     g_impl->closeFile(file);
118 }
119 
120 // Test: test-kind=internal, abc-kind=ArkTS2, category=internal
TEST_F(LibAbcKitGraphVerifierTest,LibAbcKitTestGraphVerifierBB)121 TEST_F(LibAbcKitGraphVerifierTest, LibAbcKitTestGraphVerifierBB)
122 {
123     constexpr auto INPUT_PATH = ABCKIT_ABC_DIR "ut/ir_core/graph_verifier/graph_verifier.abc";
124     auto output = helpers::ExecuteStaticAbc(INPUT_PATH, "graph_verifier/ETSGLOBAL", "main");
125     EXPECT_TRUE(helpers::Match(output, "123\nfalse\n"));
126 
127     AbckitFile *file = g_impl->openAbc(INPUT_PATH, strlen(INPUT_PATH));
128     auto *method = helpers::FindMethodByName(file, "bar");
129     ASSERT_NE(method, nullptr);
130 
131     AbckitGraph *graph = g_implI->createGraphFromFunction(method);
132     TransformIrNegativeBB(graph);
133     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
134     g_implM->functionSetGraph(method, graph);
135     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_BAD_ARGUMENT);
136     g_impl->destroyGraph(graph);
137 
138     g_impl->closeFile(file);
139 }
140 
141 // Test: test-kind=internal, abc-kind=ArkTS2, category=internal
TEST_F(LibAbcKitGraphVerifierTest,DISABLED_LibAbcKitTestGraphVerifierBinInst)142 TEST_F(LibAbcKitGraphVerifierTest, DISABLED_LibAbcKitTestGraphVerifierBinInst)
143 {
144     constexpr auto INPUT_PATH = ABCKIT_ABC_DIR "ut/ir_core/graph_verifier/graph_verifier.abc";
145     auto output = helpers::ExecuteStaticAbc(INPUT_PATH, "graph_verifier/ETSGLOBAL", "main");
146     EXPECT_TRUE(helpers::Match(output, "123\nfalse\n"));
147 
148     AbckitFile *file = g_impl->openAbc(INPUT_PATH, strlen(INPUT_PATH));
149     auto *method = helpers::FindMethodByName(file, "foo");
150     ASSERT_NE(method, nullptr);
151 
152     AbckitGraph *graph = g_implI->createGraphFromFunction(method);
153     TransformIrNegativeBinInst(graph);
154     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
155     g_implM->functionSetGraph(method, graph);
156     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_BAD_ARGUMENT);
157     g_impl->destroyGraph(graph);
158 
159     g_impl->closeFile(file);
160 }
161 
162 }  // namespace libabckit::test
163