• 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/isa/isa_static.h"
17 #include "libabckit/include/c/metadata_core.h"
18 #include "libabckit/include/c/ir_core.h"
19 #include "libabckit/include/c/isa/isa_dynamic.h"
20 #include "libabckit/include/c/abckit.h"
21 
22 #include "helpers/helpers.h"
23 #include "helpers/helpers_runtime.h"
24 #include "libabckit/include/c/statuses.h"
25 
26 #include <gtest/gtest.h>
27 
28 // NOLINTBEGIN(readability-magic-numbers)
29 namespace libabckit::test {
30 
31 static auto g_impl = AbckitGetApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
32 static auto g_implI = AbckitGetInspectApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
33 static auto g_implM = AbckitGetModifyApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
34 static auto g_implG = AbckitGetGraphApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
35 static auto g_dynG = AbckitGetIsaApiDynamicImpl(ABCKIT_VERSION_RELEASE_1_0_0);
36 
37 class LibAbcKitCreateDynLexEnvVar : public ::testing::Test {};
38 
TransformIrMain(AbckitFile * file,AbckitGraph * graph,bool isWideMode,bool isWithName)39 static void TransformIrMain(AbckitFile *file, AbckitGraph *graph, bool isWideMode, bool isWithName)
40 {
41     auto *mainBB = g_implG->gGetBasicBlock(graph, 0);
42     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
43 
44     auto *firstConst = g_implG->gFindOrCreateConstantI32(graph, 0x1);
45     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
46     auto *secondConst = g_implG->gFindOrCreateConstantI32(graph, 0x3);
47     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
48 
49     AbckitInst *newlexenv = nullptr;
50     if (isWithName) {
51         std::array<AbckitLiteral *, 5U> statlitarr = {
52             g_implM->createLiteralU32(file, 2), g_implM->createLiteralString(file, "x", strlen("x")),
53             g_implM->createLiteralU32(file, 0), g_implM->createLiteralString(file, "y", strlen("x")),
54             g_implM->createLiteralU32(file, 1)};
55         AbckitLiteralArray *litarr = g_implM->createLiteralArray(file, statlitarr.data(), 5U);
56         newlexenv = isWideMode ? g_dynG->iCreateWideNewlexenvwithname(graph, 0x2, litarr)
57                                : g_dynG->iCreateNewlexenvwithname(graph, 0x2, litarr);
58     } else {
59         newlexenv = isWideMode ? g_dynG->iCreateWideNewlexenv(graph, 0x2) : g_dynG->iCreateNewlexenv(graph, 0x2);
60     }
61     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
62 
63     AbckitInst *firstStlexvar = nullptr;
64     if (isWideMode) {
65         firstStlexvar = g_dynG->iCreateWideStlexvar(graph, firstConst, 0x0, 0x0);
66     } else {
67         firstStlexvar = g_dynG->iCreateStlexvar(graph, firstConst, 0x0, 0x0);
68     }
69     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
70     AbckitInst *secondStlexvar = nullptr;
71     if (isWideMode) {
72         secondStlexvar = g_dynG->iCreateWideStlexvar(graph, secondConst, 0x0, 0x1);
73     } else {
74         secondStlexvar = g_dynG->iCreateStlexvar(graph, secondConst, 0x0, 0x1);
75     }
76     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
77 
78     auto *firstInstToInsert = helpers::FindFirstInst(graph, ABCKIT_ISA_API_DYNAMIC_OPCODE_TRYLDGLOBALBYNAME);
79     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
80 
81     g_implG->iInsertBefore(secondStlexvar, firstInstToInsert);
82     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
83     g_implG->iInsertBefore(firstStlexvar, secondStlexvar);
84     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
85 
86     g_implG->bbAddInstFront(mainBB, newlexenv);
87     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
88 
89     auto *ret = helpers::FindFirstInst(graph, ABCKIT_ISA_API_DYNAMIC_OPCODE_RETURNUNDEFINED);
90     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
91 
92     auto *poplexenv = g_dynG->iCreatePoplexenv(graph);
93     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
94 
95     g_implG->iInsertBefore(poplexenv, ret);
96     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
97 }
98 
TransformIrFuncs(AbckitFile * file,AbckitGraph * graph,uint32_t slot,bool isWideMode)99 static void TransformIrFuncs(AbckitFile *file, AbckitGraph *graph, uint32_t slot, bool isWideMode)
100 {
101     auto *firstConst = g_implG->gFindOrCreateConstantI32(graph, 0x1);
102     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
103 
104     AbckitInst *ldlexvar = nullptr;
105     if (isWideMode) {
106         ldlexvar = g_dynG->iCreateWideLdlexvar(graph, 0x0, slot);
107     } else {
108         ldlexvar = g_dynG->iCreateLdlexvar(graph, 0x0, slot);
109     }
110     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
111     AbckitString *name = nullptr;
112     if (slot == 0x0) {
113         name = g_implM->createString(file, "x", strlen("x"));
114     } else if (slot == 0x1) {
115         name = g_implM->createString(file, "y", strlen("y"));
116     }
117     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
118     auto *throwundef = g_dynG->iCreateThrowUndefinedifholewithname(graph, ldlexvar, name);
119     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
120     auto *add2 = g_dynG->iCreateAdd2(graph, firstConst, ldlexvar);
121     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
122 
123     auto *ret = helpers::FindFirstInst(graph, ABCKIT_ISA_API_DYNAMIC_OPCODE_RETURN);
124     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
125 
126     g_implG->iInsertBefore(add2, ret);
127     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
128     g_implG->iInsertBefore(throwundef, add2);
129     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
130     g_implG->iInsertBefore(ldlexvar, throwundef);
131     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
132 
133     g_implG->iSetInput(ret, add2, 0);
134     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
135 }
136 
ValidateIrMain(AbckitGraph * graph,bool isWideMode,bool isWithName)137 static void ValidateIrMain(AbckitGraph *graph, bool isWideMode, bool isWithName)
138 {
139     AbckitIsaApiDynamicOpcode newlexenv;
140     if (isWithName) {
141         newlexenv = isWideMode ? ABCKIT_ISA_API_DYNAMIC_OPCODE_WIDE_NEWLEXENVWITHNAME
142                                : ABCKIT_ISA_API_DYNAMIC_OPCODE_NEWLEXENVWITHNAME;
143     } else {
144         newlexenv = isWideMode ? ABCKIT_ISA_API_DYNAMIC_OPCODE_WIDE_NEWLEXENV : ABCKIT_ISA_API_DYNAMIC_OPCODE_NEWLEXENV;
145     }
146     AbckitIsaApiDynamicOpcode stlexvar =
147         isWideMode ? ABCKIT_ISA_API_DYNAMIC_OPCODE_WIDE_STLEXVAR : ABCKIT_ISA_API_DYNAMIC_OPCODE_STLEXVAR;
148     std::vector<helpers::BBSchema<AbckitIsaApiDynamicOpcode>> bbSchema = {
149         {{},
150          {1},
151          {
152              {0, ABCKIT_ISA_API_DYNAMIC_OPCODE_PARAMETER, {}},
153              {1, ABCKIT_ISA_API_DYNAMIC_OPCODE_PARAMETER, {}},
154              {2, ABCKIT_ISA_API_DYNAMIC_OPCODE_PARAMETER, {}},
155              {8, ABCKIT_ISA_API_DYNAMIC_OPCODE_CONSTANT, {}},
156              {10, ABCKIT_ISA_API_DYNAMIC_OPCODE_CONSTANT, {}},
157          }},
158         {{0},
159          {2},
160          {
161              {3, newlexenv, {}},
162              {6, ABCKIT_ISA_API_DYNAMIC_OPCODE_DEFINEFUNC, {}},
163              {7, ABCKIT_ISA_API_DYNAMIC_OPCODE_DEFINEFUNC, {}},
164              {9, stlexvar, {8}},
165              {11, stlexvar, {10}},
166              {12, ABCKIT_ISA_API_DYNAMIC_OPCODE_TRYLDGLOBALBYNAME, {}},
167              {13, ABCKIT_ISA_API_DYNAMIC_OPCODE_CALLARG0, {7}},
168              {14, ABCKIT_ISA_API_DYNAMIC_OPCODE_CALLARG1, {12, 13}},
169              {15, ABCKIT_ISA_API_DYNAMIC_OPCODE_TRYLDGLOBALBYNAME, {}},
170              {16, ABCKIT_ISA_API_DYNAMIC_OPCODE_CALLARG0, {6}},
171              {17, ABCKIT_ISA_API_DYNAMIC_OPCODE_CALLARG1, {15, 16}},
172              {18, ABCKIT_ISA_API_DYNAMIC_OPCODE_POPLEXENV, {}},
173              {19, ABCKIT_ISA_API_DYNAMIC_OPCODE_RETURNUNDEFINED, {}},
174          }},
175         {{1}, {}, {}}};
176 
177     helpers::VerifyGraph(graph, bbSchema);
178 }
179 
ValidateIrFuncs(AbckitGraph * graph,bool isWideMode)180 static void ValidateIrFuncs(AbckitGraph *graph, bool isWideMode)
181 {
182     AbckitIsaApiDynamicOpcode ldlexvar =
183         isWideMode ? ABCKIT_ISA_API_DYNAMIC_OPCODE_WIDE_LDLEXVAR : ABCKIT_ISA_API_DYNAMIC_OPCODE_LDLEXVAR;
184     std::vector<helpers::BBSchema<AbckitIsaApiDynamicOpcode>> bbSchema = {
185         {{},
186          {1},
187          {
188              {0, ABCKIT_ISA_API_DYNAMIC_OPCODE_PARAMETER, {}},
189              {1, ABCKIT_ISA_API_DYNAMIC_OPCODE_PARAMETER, {}},
190              {2, ABCKIT_ISA_API_DYNAMIC_OPCODE_PARAMETER, {}},
191              {5, ABCKIT_ISA_API_DYNAMIC_OPCODE_CONSTANT, {}},
192          }},
193         {{0},
194          {2},
195          {
196              {3, ldlexvar, {}},
197              {4, ABCKIT_ISA_API_DYNAMIC_OPCODE_THROW_UNDEFINEDIFHOLEWITHNAME, {3}},
198              {6, ABCKIT_ISA_API_DYNAMIC_OPCODE_ADD2, {5, 3}},
199              {7, ABCKIT_ISA_API_DYNAMIC_OPCODE_RETURN, {6}},
200          }},
201         {{1}, {}, {}}};
202 
203     helpers::VerifyGraph(graph, bbSchema);
204 }
205 
TestLexEnvVar(bool isWideMode,bool isWithName=false)206 static void TestLexEnvVar(bool isWideMode, bool isWithName = false)
207 {
208     auto output =
209         helpers::ExecuteDynamicAbc(ABCKIT_ABC_DIR "ut/isa/isa_dynamic/lexenv/lexenv_dynamic.abc", "lexenv_dynamic");
210     EXPECT_TRUE(helpers::Match(output, "0\n0\n"));
211 
212     helpers::TransformMethod(
213         ABCKIT_ABC_DIR "ut/isa/isa_dynamic/lexenv/lexenv_dynamic.abc",
214         ABCKIT_ABC_DIR "ut/isa/isa_dynamic/lexenv/lexenv_dynamic_modified.abc", "lexenv_dynamic.func_main_0",
215         [&](AbckitFile *file, AbckitCoreFunction * /*func*/, AbckitGraph *graph) {
216             TransformIrMain(file, graph, isWideMode, isWithName);
217         },
218         [&](AbckitGraph *graph) { ValidateIrMain(graph, isWideMode, isWithName); });
219 
220     helpers::TransformMethod(
221         ABCKIT_ABC_DIR "ut/isa/isa_dynamic/lexenv/lexenv_dynamic_modified.abc",
222         ABCKIT_ABC_DIR "ut/isa/isa_dynamic/lexenv/lexenv_dynamic_modified.abc", "lexenv_dynamic.foo",
223         [&](AbckitFile *file, AbckitCoreFunction * /*func*/, AbckitGraph *graph) {
224             TransformIrFuncs(file, graph, 0x0, isWideMode);
225         },
226         [&](AbckitGraph *graph) { ValidateIrFuncs(graph, isWideMode); });
227 
228     helpers::TransformMethod(
229         ABCKIT_ABC_DIR "ut/isa/isa_dynamic/lexenv/lexenv_dynamic_modified.abc",
230         ABCKIT_ABC_DIR "ut/isa/isa_dynamic/lexenv/lexenv_dynamic_modified.abc", "lexenv_dynamic.bar",
231         [&](AbckitFile *file, AbckitCoreFunction * /*func*/, AbckitGraph *graph) {
232             TransformIrFuncs(file, graph, 0x1, isWideMode);
233         },
234         [&](AbckitGraph *graph) { ValidateIrFuncs(graph, isWideMode); });
235 
236     output = helpers::ExecuteDynamicAbc(ABCKIT_ABC_DIR "ut/isa/isa_dynamic/lexenv/lexenv_dynamic_modified.abc",
237                                         "lexenv_dynamic");
238     EXPECT_TRUE(helpers::Match(output, "2\n4\n"));
239 }
240 
241 // Test: test-kind=api, api=IsaApiDynamicImpl::iCreateNewlexenv, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(LibAbcKitCreateDynLexEnvVar,NewLexenv)242 TEST_F(LibAbcKitCreateDynLexEnvVar, NewLexenv)
243 {
244     TestLexEnvVar(false);
245 }
246 
247 // Test: test-kind=api, api=IsaApiDynamicImpl::iCreateStlexvar, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(LibAbcKitCreateDynLexEnvVar,StLexvar)248 TEST_F(LibAbcKitCreateDynLexEnvVar, StLexvar)
249 {
250     TestLexEnvVar(false);
251 }
252 
253 // Test: test-kind=api, api=IsaApiDynamicImpl::iCreateLdlexvar, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(LibAbcKitCreateDynLexEnvVar,LdLexvar)254 TEST_F(LibAbcKitCreateDynLexEnvVar, LdLexvar)
255 {
256     TestLexEnvVar(false);
257 }
258 
259 // Test: test-kind=api, api=IsaApiDynamicImpl::iCreateWideNewlexenv, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(LibAbcKitCreateDynLexEnvVar,WideNewLexenv)260 TEST_F(LibAbcKitCreateDynLexEnvVar, WideNewLexenv)
261 {
262     TestLexEnvVar(true);
263 }
264 
265 // Test: test-kind=api, api=IsaApiDynamicImpl::iCreateWideStlexvar, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(LibAbcKitCreateDynLexEnvVar,WideStLexvar)266 TEST_F(LibAbcKitCreateDynLexEnvVar, WideStLexvar)
267 {
268     TestLexEnvVar(true);
269 }
270 
271 // Test: test-kind=api, api=IsaApiDynamicImpl::iCreateWideLdlexvar, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(LibAbcKitCreateDynLexEnvVar,WideLdLexvar)272 TEST_F(LibAbcKitCreateDynLexEnvVar, WideLdLexvar)
273 {
274     TestLexEnvVar(true);
275 }
276 
277 // Test: test-kind=api, api=IsaApiDynamicImpl::iCreateNewlexenvwithname, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(LibAbcKitCreateDynLexEnvVar,NewLexenvWithName)278 TEST_F(LibAbcKitCreateDynLexEnvVar, NewLexenvWithName)
279 {
280     TestLexEnvVar(false, true);
281 }
282 
283 // Test: test-kind=api, api=IsaApiDynamicImpl::iCreateWideNewlexenvwithname, abc-kind=ArkTS1, category=positive,
284 // extension=c
TEST_F(LibAbcKitCreateDynLexEnvVar,WideNewLexenvWithName)285 TEST_F(LibAbcKitCreateDynLexEnvVar, WideNewLexenvWithName)
286 {
287     TestLexEnvVar(true, true);
288 }
289 
290 // Test: test-kind=api, api=IsaApiDynamicImpl::iCreatePoplexenv, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(LibAbcKitCreateDynLexEnvVar,PopLexenv)291 TEST_F(LibAbcKitCreateDynLexEnvVar, PopLexenv)
292 {
293     TestLexEnvVar(false);
294 }
295 
296 }  // namespace libabckit::test
297 // NOLINTEND(readability-magic-numbers)
298