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/metadata_core.h"
17 #include "libabckit/include/c/ir_core.h"
18 #include "libabckit/include/c/isa/isa_dynamic.h"
19 #include "libabckit/include/c/abckit.h"
20
21 #include "helpers/helpers.h"
22 #include "helpers/helpers_runtime.h"
23
24 #include <gtest/gtest.h>
25
26 // NOLINTBEGIN(readability-magic-numbers)
27 namespace libabckit::test {
28
29 static auto g_impl = AbckitGetApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
30 static auto g_implI = AbckitGetInspectApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
31 static auto g_implM = AbckitGetModifyApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
32 static auto g_implG = AbckitGetGraphApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
33 static auto g_dynG = AbckitGetIsaApiDynamicImpl(ABCKIT_VERSION_RELEASE_1_0_0);
34
35 class LibAbcKitCreateDynDefineClass : public ::testing::Test {};
36
37 // Test: test-kind=api, api=IsaApiDynamicImpl::iCreateDefineclasswithbuffer, abc-kind=ArkTS1, category=positive,
38 // extension=c
TEST_F(LibAbcKitCreateDynDefineClass,IcreateDefineclasswithbuffer_1)39 TEST_F(LibAbcKitCreateDynDefineClass, IcreateDefineclasswithbuffer_1)
40 {
41 auto output = helpers::ExecuteDynamicAbc(
42 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/define/defineclasswithbuffer_dynamic.abc", "defineclasswithbuffer_dynamic");
43 EXPECT_TRUE(helpers::Match(output, ""));
44
45 helpers::TransformMethod(
46 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/define/defineclasswithbuffer_dynamic.abc",
47 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/define/defineclasswithbuffer_dynamic_modified.abc", "func_main_0",
48 [&](AbckitFile *file, AbckitCoreFunction * /*method*/, AbckitGraph *graph) {
49 auto *inst = helpers::FindFirstInst(graph, ABCKIT_ISA_API_DYNAMIC_OPCODE_DEFINECLASSWITHBUFFER);
50 auto *litArr = g_implG->iGetLiteralArray(inst);
51 auto *input = g_implG->iGetInput(inst, 0);
52 auto *user = g_implG->iGetNext(inst);
53
54 g_implG->iRemove(inst);
55 g_implG->iRemove(user);
56
57 auto *classMethod = helpers::FindMethodByName(file, "A");
58 ASSERT_NE(classMethod, nullptr);
59
60 auto *instDefine = g_dynG->iCreateDefineclasswithbuffer(graph, classMethod, litArr, 0x0, input);
61 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
62 auto *stringProt = g_implM->createString(file, "prototype", strlen("prototype"));
63 auto *ldobjbyname = g_dynG->iCreateLdobjbyname(graph, instDefine, stringProt);
64 auto *returnundefined = helpers::FindFirstInst(graph, ABCKIT_ISA_API_DYNAMIC_OPCODE_RETURNUNDEFINED);
65 auto *newobj = helpers::FindFirstInst(graph, ABCKIT_ISA_API_DYNAMIC_OPCODE_NEWOBJRANGE);
66 g_implG->iSetInput(newobj, instDefine, 0x0);
67 auto *definefunc = helpers::FindFirstInst(graph, ABCKIT_ISA_API_DYNAMIC_OPCODE_DEFINEFUNC);
68 auto *callarg1 = g_dynG->iCreateCallarg1(graph, definefunc, newobj);
69 g_implG->iInsertBefore(instDefine, newobj);
70 g_implG->iInsertBefore(ldobjbyname, newobj);
71 g_implG->iInsertBefore(callarg1, returnundefined);
72 });
73
74 output = helpers::ExecuteDynamicAbc(ABCKIT_ABC_DIR
75 "ut/isa/isa_dynamic/define/defineclasswithbuffer_dynamic_modified.abc",
76 "defineclasswithbuffer_dynamic");
77 EXPECT_TRUE(helpers::Match(output, "\\[object Object\\]\n"));
78 }
79
80 // Test: test-kind=api, api=IsaApiDynamicImpl::iCreateDefineclasswithbuffer, abc-kind=ArkTS1, category=positive,
81 // extension=c
TEST_F(LibAbcKitCreateDynDefineClass,IcreateDefineclasswithbuffer_2)82 TEST_F(LibAbcKitCreateDynDefineClass, IcreateDefineclasswithbuffer_2)
83 {
84 auto output = helpers::ExecuteDynamicAbc(
85 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/define/defineclasswithbuffer_dynamic.abc", "defineclasswithbuffer_dynamic");
86 EXPECT_TRUE(helpers::Match(output, ""));
87
88 helpers::TransformMethod(
89 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/define/defineclasswithbuffer_dynamic.abc",
90 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/define/defineclasswithbuffer_dynamic_modified.abc", "func_main_0",
91 [&](AbckitFile *file, AbckitCoreFunction * /*method*/, AbckitGraph *graph) {
92 auto *inst = helpers::FindFirstInst(graph, ABCKIT_ISA_API_DYNAMIC_OPCODE_DEFINECLASSWITHBUFFER);
93 auto *input = g_implG->iGetInput(inst, 0);
94
95 auto *classConstr = helpers::FindMethodByName(file, "newClassConstr");
96 ASSERT_NE(classConstr, nullptr);
97 auto arr = std::vector<AbckitLiteral *>();
98 arr.emplace_back(g_implM->createLiteralU32(file, 0));
99 auto *litArr = g_implM->createLiteralArray(file, arr.data(), arr.size());
100
101 auto *instDefine = g_dynG->iCreateDefineclasswithbuffer(graph, classConstr, litArr, 0x0, input);
102 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
103 auto *stringProt = g_implM->createString(file, "prototype", strlen("prototype"));
104 auto *ldobjbyname = g_dynG->iCreateLdobjbyname(graph, instDefine, stringProt);
105 auto *returnundefined = helpers::FindFirstInst(graph, ABCKIT_ISA_API_DYNAMIC_OPCODE_RETURNUNDEFINED);
106 auto *newobj = g_dynG->iCreateNewobjrange(graph, 1, instDefine);
107 g_implG->iInsertBefore(instDefine, returnundefined);
108 g_implG->iInsertBefore(ldobjbyname, returnundefined);
109 g_implG->iInsertBefore(newobj, returnundefined);
110 });
111
112 output = helpers::ExecuteDynamicAbc(ABCKIT_ABC_DIR
113 "ut/isa/isa_dynamic/define/defineclasswithbuffer_dynamic_modified.abc",
114 "defineclasswithbuffer_dynamic");
115 EXPECT_TRUE(helpers::Match(output, "constr\n"));
116 }
117
118 // Test: test-kind=api, api=IsaApiDynamicImpl::iCreateDefineclasswithbuffer, abc-kind=ArkTS1, category=positive,
119 // extension=c
TEST_F(LibAbcKitCreateDynDefineClass,IcreateDefineclasswithbuffer_3)120 TEST_F(LibAbcKitCreateDynDefineClass, IcreateDefineclasswithbuffer_3)
121 {
122 auto output = helpers::ExecuteDynamicAbc(
123 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/define/defineclasswithbuffer_dynamic.abc", "defineclasswithbuffer_dynamic");
124 EXPECT_TRUE(helpers::Match(output, ""));
125
126 helpers::TransformMethod(
127 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/define/defineclasswithbuffer_dynamic.abc",
128 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/define/defineclasswithbuffer_dynamic_modified.abc", "func_main_0",
129 [&](AbckitFile *file, AbckitCoreFunction * /*method*/, AbckitGraph *graph) {
130 auto *inst = helpers::FindFirstInst(graph, ABCKIT_ISA_API_DYNAMIC_OPCODE_DEFINECLASSWITHBUFFER);
131 auto *input = g_implG->iGetInput(inst, 0);
132
133 auto *classConstr = helpers::FindMethodByName(file, "newClassConstr");
134 ASSERT_NE(classConstr, nullptr);
135 auto arr = std::vector<AbckitLiteral *>();
136 arr.emplace_back(g_implM->createLiteralString(file, "newClassMethod", strlen("newClassMethod")));
137 arr.emplace_back(g_implM->createLiteralMethod(file, helpers::FindMethodByName(file, "newClassMethod")));
138 arr.emplace_back(g_implM->createLiteralMethodAffiliate(file, 0));
139 arr.emplace_back(g_implM->createLiteralU32(file, 1));
140 auto *litArr = g_implM->createLiteralArray(file, arr.data(), arr.size());
141
142 auto *instDefine = g_dynG->iCreateDefineclasswithbuffer(graph, classConstr, litArr, 0x0, input);
143 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
144 auto *stringProt = g_implM->createString(file, "prototype", strlen("prototype"));
145 auto *ldobjbyname = g_dynG->iCreateLdobjbyname(graph, instDefine, stringProt);
146 auto *returnundefined = helpers::FindFirstInst(graph, ABCKIT_ISA_API_DYNAMIC_OPCODE_RETURNUNDEFINED);
147 auto *newobj = g_dynG->iCreateNewobjrange(graph, 1, instDefine);
148 auto *stringMethod = g_implM->createString(file, "newClassMethod", strlen("newClassMethod"));
149 auto *ldobjbyname2 = g_dynG->iCreateLdobjbyname(graph, newobj, stringMethod);
150 auto *callthis = g_dynG->iCreateCallthis0(graph, ldobjbyname2, newobj);
151 g_implG->iInsertBefore(instDefine, returnundefined);
152 g_implG->iInsertBefore(ldobjbyname, returnundefined);
153 g_implG->iInsertBefore(newobj, returnundefined);
154 g_implG->iInsertBefore(ldobjbyname2, returnundefined);
155 g_implG->iInsertBefore(callthis, returnundefined);
156 });
157
158 output = helpers::ExecuteDynamicAbc(ABCKIT_ABC_DIR
159 "ut/isa/isa_dynamic/define/defineclasswithbuffer_dynamic_modified.abc",
160 "defineclasswithbuffer_dynamic");
161 EXPECT_TRUE(helpers::Match(output, "constr\nmethod\n"));
162 }
163
164 // Test: test-kind=api, api=IsaApiDynamicImpl::iCreateDefineclasswithbuffer, abc-kind=ArkTS1, category=positive,
165 // extension=c
TEST_F(LibAbcKitCreateDynDefineClass,IcreateDefineclasswithbuffer_4)166 TEST_F(LibAbcKitCreateDynDefineClass, IcreateDefineclasswithbuffer_4)
167 {
168 auto output = helpers::ExecuteDynamicAbc(
169 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/define/defineclasswithbuffer_dynamic.abc", "defineclasswithbuffer_dynamic");
170 EXPECT_TRUE(helpers::Match(output, ""));
171
172 helpers::TransformMethod(
173 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/define/defineclasswithbuffer_dynamic.abc",
174 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/define/defineclasswithbuffer_dynamic_modified.abc", "func_main_0",
175 [&](AbckitFile *file, AbckitCoreFunction * /*method*/, AbckitGraph *graph) {
176 auto *inst = helpers::FindFirstInst(graph, ABCKIT_ISA_API_DYNAMIC_OPCODE_DEFINECLASSWITHBUFFER);
177 auto *input = g_implG->iGetInput(inst, 0);
178
179 auto *classConstr = helpers::FindMethodByName(file, "newClassConstr");
180 ASSERT_NE(classConstr, nullptr);
181 auto arr = std::vector<AbckitLiteral *>();
182 arr.emplace_back(g_implM->createLiteralString(file, "newClassMethod", strlen("newClassMethod")));
183 arr.emplace_back(g_implM->createLiteralMethod(file, helpers::FindMethodByName(file, "newClassMethod")));
184 arr.emplace_back(g_implM->createLiteralMethodAffiliate(file, 0));
185 arr.emplace_back(g_implM->createLiteralString(file, "newClassMethod2", strlen("newClassMethod2")));
186 arr.emplace_back(g_implM->createLiteralMethod(file, helpers::FindMethodByName(file, "newClassMethod2")));
187 arr.emplace_back(g_implM->createLiteralMethodAffiliate(file, 1));
188 arr.emplace_back(g_implM->createLiteralU32(file, 2));
189 auto *litArr = g_implM->createLiteralArray(file, arr.data(), arr.size());
190
191 auto *instDefine = g_dynG->iCreateDefineclasswithbuffer(graph, classConstr, litArr, 0x0, input);
192 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
193 auto *stringProt = g_implM->createString(file, "prototype", strlen("prototype"));
194 auto *ldobjbyname = g_dynG->iCreateLdobjbyname(graph, instDefine, stringProt);
195 auto *returnundefined = helpers::FindFirstInst(graph, ABCKIT_ISA_API_DYNAMIC_OPCODE_RETURNUNDEFINED);
196 auto *newobj = g_dynG->iCreateNewobjrange(graph, 1, instDefine);
197 auto *stringMethod = g_implM->createString(file, "newClassMethod2", strlen("newClassMethod2"));
198 auto *ldobjbyname2 = g_dynG->iCreateLdobjbyname(graph, newobj, stringMethod);
199 auto *const1 = g_implG->gFindOrCreateConstantU64(graph, 5);
200 auto *callthis = g_dynG->iCreateCallthis1(graph, ldobjbyname2, newobj, const1);
201 g_implG->iInsertBefore(instDefine, returnundefined);
202 g_implG->iInsertBefore(ldobjbyname, returnundefined);
203 g_implG->iInsertBefore(newobj, returnundefined);
204 g_implG->iInsertBefore(ldobjbyname2, returnundefined);
205 g_implG->iInsertBefore(callthis, returnundefined);
206 });
207
208 output = helpers::ExecuteDynamicAbc(ABCKIT_ABC_DIR
209 "ut/isa/isa_dynamic/define/defineclasswithbuffer_dynamic_modified.abc",
210 "defineclasswithbuffer_dynamic");
211 EXPECT_TRUE(helpers::Match(output, "constr\nmethod 5\n"));
212 }
213
214 // Test: test-kind=api, api=IsaApiDynamicImpl::iCreateDefineclasswithbuffer, abc-kind=ArkTS1, category=positive,
215 // extension=c
TEST_F(LibAbcKitCreateDynDefineClass,IcreateDefineclasswithbuffer_5)216 TEST_F(LibAbcKitCreateDynDefineClass, IcreateDefineclasswithbuffer_5)
217 {
218 auto output = helpers::ExecuteDynamicAbc(
219 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/define/defineclasswithbuffer_dynamic.abc", "defineclasswithbuffer_dynamic");
220 EXPECT_TRUE(helpers::Match(output, ""));
221
222 helpers::TransformMethod(
223 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/define/defineclasswithbuffer_dynamic.abc",
224 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/define/defineclasswithbuffer_dynamic_modified.abc", "func_main_0",
225 [&](AbckitFile *file, AbckitCoreFunction * /*method*/, AbckitGraph *graph) {
226 auto *inst = helpers::FindFirstInst(graph, ABCKIT_ISA_API_DYNAMIC_OPCODE_DEFINECLASSWITHBUFFER);
227 auto *input = g_implG->iGetInput(inst, 0);
228
229 auto *classConstr = helpers::FindMethodByName(file, "newClassConstr2");
230 ASSERT_NE(classConstr, nullptr);
231 auto arr = std::vector<AbckitLiteral *>();
232 arr.emplace_back(g_implM->createLiteralString(file, "newClassMethod", strlen("newClassMethod")));
233 arr.emplace_back(g_implM->createLiteralMethod(file, helpers::FindMethodByName(file, "newClassMethod")));
234 arr.emplace_back(g_implM->createLiteralMethodAffiliate(file, 0));
235 arr.emplace_back(g_implM->createLiteralString(file, "newClassMethod2", strlen("newClassMethod2")));
236 arr.emplace_back(g_implM->createLiteralMethod(file, helpers::FindMethodByName(file, "newClassMethod2")));
237 arr.emplace_back(g_implM->createLiteralMethodAffiliate(file, 1));
238 arr.emplace_back(g_implM->createLiteralU32(file, 2));
239 auto *litArr = g_implM->createLiteralArray(file, arr.data(), arr.size());
240
241 auto *instDefine = g_dynG->iCreateDefineclasswithbuffer(graph, classConstr, litArr, 0x0, input);
242 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
243 auto *stringProt = g_implM->createString(file, "prototype", strlen("prototype"));
244 auto *ldobjbyname = g_dynG->iCreateLdobjbyname(graph, instDefine, stringProt);
245 auto *returnundefined = helpers::FindFirstInst(graph, ABCKIT_ISA_API_DYNAMIC_OPCODE_RETURNUNDEFINED);
246 auto *string = g_implM->createString(file, "initialize", strlen("initialize"));
247 auto *loadString = g_dynG->iCreateLoadString(graph, string);
248 auto *newobj = g_dynG->iCreateNewobjrange(graph, 2, instDefine, loadString);
249 g_implG->iInsertBefore(instDefine, returnundefined);
250 g_implG->iInsertBefore(ldobjbyname, returnundefined);
251 g_implG->iInsertBefore(loadString, returnundefined);
252 g_implG->iInsertBefore(newobj, returnundefined);
253 });
254
255 output = helpers::ExecuteDynamicAbc(ABCKIT_ABC_DIR
256 "ut/isa/isa_dynamic/define/defineclasswithbuffer_dynamic_modified.abc",
257 "defineclasswithbuffer_dynamic");
258 EXPECT_TRUE(helpers::Match(output, "constr initialize\n"));
259 }
260
261 // Test: test-kind=api, api=IsaApiDynamicImpl::iCreateDefineclasswithbuffer, abc-kind=ArkTS1, category=positive,
262 // extension=c
TEST_F(LibAbcKitCreateDynDefineClass,IcreateDefineclasswithbuffer_6)263 TEST_F(LibAbcKitCreateDynDefineClass, IcreateDefineclasswithbuffer_6)
264 {
265 auto output = helpers::ExecuteDynamicAbc(
266 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/define/defineclasswithbuffer_dynamic.abc", "defineclasswithbuffer_dynamic");
267 EXPECT_TRUE(helpers::Match(output, ""));
268
269 helpers::TransformMethod(
270 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/define/defineclasswithbuffer_dynamic.abc",
271 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/define/defineclasswithbuffer_dynamic_modified.abc", "func_main_0",
272 [&](AbckitFile *file, AbckitCoreFunction * /*method*/, AbckitGraph *graph) {
273 auto *inst = helpers::FindFirstInst(graph, ABCKIT_ISA_API_DYNAMIC_OPCODE_DEFINECLASSWITHBUFFER);
274 auto *input = g_implG->iGetInput(inst, 0);
275
276 auto *classConstr = helpers::FindMethodByName(file, "newClassConstr3");
277 ASSERT_NE(classConstr, nullptr);
278 auto arr = std::vector<AbckitLiteral *>();
279 arr.emplace_back(g_implM->createLiteralU32(file, 0));
280 auto *litArr = g_implM->createLiteralArray(file, arr.data(), arr.size());
281
282 auto *instDefine = g_dynG->iCreateDefineclasswithbuffer(graph, classConstr, litArr, 0x1, input);
283 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
284 auto *stringProt = g_implM->createString(file, "prototype", strlen("prototype"));
285 auto *ldobjbyname = g_dynG->iCreateLdobjbyname(graph, instDefine, stringProt);
286 auto *returnundefined = helpers::FindFirstInst(graph, ABCKIT_ISA_API_DYNAMIC_OPCODE_RETURNUNDEFINED);
287 g_implG->iInsertBefore(instDefine, returnundefined);
288 g_implG->iInsertBefore(ldobjbyname, returnundefined);
289
290 auto *classConstr2 = helpers::FindMethodByName(file, "newClassConstr");
291 ASSERT_NE(classConstr2, nullptr);
292
293 auto *instDefine2 = g_dynG->iCreateDefineclasswithbuffer(graph, classConstr2, litArr, 0x0, instDefine);
294 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
295 auto *ldobjbyname2 = g_dynG->iCreateLdobjbyname(graph, instDefine2, stringProt);
296 auto *newobj = g_dynG->iCreateNewobjrange(graph, 1, instDefine2);
297 g_implG->iInsertBefore(instDefine2, returnundefined);
298 g_implG->iInsertBefore(ldobjbyname2, returnundefined);
299 g_implG->iInsertBefore(newobj, returnundefined);
300 });
301
302 output = helpers::ExecuteDynamicAbc(ABCKIT_ABC_DIR
303 "ut/isa/isa_dynamic/define/defineclasswithbuffer_dynamic_modified.abc",
304 "defineclasswithbuffer_dynamic");
305 EXPECT_TRUE(helpers::Match(output, "constr\n"));
306 }
307
308 } // namespace libabckit::test
309 // NOLINTEND(readability-magic-numbers)
310