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 #include "libabckit/include/c/statuses.h"
24
25 #include <gtest/gtest.h>
26 #include <cstdint>
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 LibAbcKitCreateDynSuperCall : public ::testing::Test {};
38
TransformSuperCallThisRangeIr(AbckitGraph * graph,bool isWideMode)39 static void TransformSuperCallThisRangeIr(AbckitGraph *graph, bool isWideMode)
40 {
41 auto *par = g_implG->iGetPrev(helpers::FindLastInst(graph, ABCKIT_ISA_API_DYNAMIC_OPCODE_PARAMETER));
42 ASSERT_NE(par, nullptr);
43 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
44
45 auto *obj = g_implG->iGetNext(par);
46 ASSERT_NE(obj, nullptr);
47 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
48
49 AbckitInst *supercall = isWideMode ? g_dynG->iCreateWideSupercallthisrange(graph, 1, obj)
50 : g_dynG->iCreateSupercallthisrange(graph, 1, obj);
51 ASSERT_NE(supercall, nullptr);
52 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
53
54 auto *throwcall1 = helpers::FindFirstInst(graph, ABCKIT_ISA_API_DYNAMIC_OPCODE_THROW_IFSUPERNOTCORRECTCALL);
55 ASSERT_NE(throwcall1, nullptr);
56 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
57
58 auto *ret = helpers::FindFirstInst(graph, ABCKIT_ISA_API_DYNAMIC_OPCODE_RETURN);
59 ASSERT_NE(ret, nullptr);
60 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
61
62 g_implG->iSetInput(throwcall1, supercall, 0);
63 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
64
65 g_implG->iSetInput(ret, supercall, 0);
66 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
67
68 auto *throwcall2 = g_dynG->iCreateThrowIfsupernotcorrectcall(graph, par, 0x1);
69 ASSERT_NE(throwcall2, nullptr);
70 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
71
72 auto *mainBB = g_implG->gGetBasicBlock(graph, 0);
73 ASSERT_NE(mainBB, nullptr);
74 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
75
76 g_implG->bbAddInstFront(mainBB, throwcall2);
77 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
78 g_implG->bbAddInstFront(mainBB, supercall);
79 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
80 }
81
TransformSuperCallThisRangeIrLarge(AbckitGraph * graph,bool isWideMode)82 static void TransformSuperCallThisRangeIrLarge(AbckitGraph *graph, bool isWideMode)
83 {
84 auto *par1 = g_implG->iGetNext(helpers::FindFirstInst(graph, ABCKIT_ISA_API_DYNAMIC_OPCODE_PARAMETER));
85 par1 = g_implG->iGetNext(g_implG->iGetNext(par1));
86 ASSERT_NE(par1, nullptr);
87 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
88
89 auto *par2 = g_implG->iGetNext(par1);
90 ASSERT_NE(par2, nullptr);
91 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
92 auto *par3 = g_implG->iGetNext(par2);
93 auto *par4 = g_implG->iGetNext(par3);
94 auto *par5 = g_implG->iGetNext(par4);
95 auto *par6 = g_implG->iGetNext(par5);
96 auto *par7 = g_implG->iGetNext(par6);
97 auto *par8 = g_implG->iGetNext(par7);
98 auto *par9 = g_implG->iGetNext(par8);
99 auto *par10 = g_implG->iGetNext(par9);
100 auto *par11 = g_implG->iGetNext(par10);
101 auto *par12 = g_implG->iGetNext(par11);
102 auto *par13 = g_implG->iGetNext(par12);
103 auto *par14 = g_implG->iGetNext(par13);
104 auto *par15 = g_implG->iGetNext(par14);
105 auto *par16 = g_implG->iGetNext(par15);
106
107 AbckitInst *supercall =
108 isWideMode ? g_dynG->iCreateWideSupercallthisrange(graph, 0x10, par1, par2, par3, par4, par5, par6, par7, par8,
109 par9, par10, par11, par12, par13, par14, par15, par16)
110 : g_dynG->iCreateSupercallthisrange(graph, 0x10, par1, par2, par3, par4, par5, par6, par7, par8,
111 par9, par10, par11, par12, par13, par14, par15, par16);
112 ASSERT_NE(supercall, nullptr);
113 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
114
115 auto *throwcall1 = helpers::FindFirstInst(graph, ABCKIT_ISA_API_DYNAMIC_OPCODE_THROW_IFSUPERNOTCORRECTCALL);
116 ASSERT_NE(throwcall1, nullptr);
117 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
118
119 auto *ret = helpers::FindFirstInst(graph, ABCKIT_ISA_API_DYNAMIC_OPCODE_RETURN);
120 ASSERT_NE(ret, nullptr);
121 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
122
123 g_implG->iSetInput(throwcall1, supercall, 0);
124 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
125
126 g_implG->iSetInput(ret, supercall, 0);
127 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
128
129 auto *throwcall2 = g_dynG->iCreateThrowIfsupernotcorrectcall(graph, par1, 0x10);
130 ASSERT_NE(throwcall2, nullptr);
131 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
132
133 auto *mainBB = g_implG->gGetBasicBlock(graph, 0);
134 ASSERT_NE(mainBB, nullptr);
135 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
136
137 g_implG->bbAddInstFront(mainBB, throwcall2);
138 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
139 g_implG->bbAddInstFront(mainBB, supercall);
140 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
141 }
142
VerifySuperCallThisRangeIr(AbckitGraph * graph,bool isWideMode)143 static void VerifySuperCallThisRangeIr(AbckitGraph *graph, bool isWideMode)
144 {
145 AbckitIsaApiDynamicOpcode supercall = isWideMode ? ABCKIT_ISA_API_DYNAMIC_OPCODE_WIDE_SUPERCALLTHISRANGE
146 : ABCKIT_ISA_API_DYNAMIC_OPCODE_SUPERCALLTHISRANGE;
147 std::vector<helpers::BBSchema<AbckitIsaApiDynamicOpcode>> bbSchema = {
148 {{},
149 {1},
150 {
151 {0, ABCKIT_ISA_API_DYNAMIC_OPCODE_PARAMETER, {}},
152 {1, ABCKIT_ISA_API_DYNAMIC_OPCODE_PARAMETER, {}},
153 {2, ABCKIT_ISA_API_DYNAMIC_OPCODE_PARAMETER, {}},
154 {3, ABCKIT_ISA_API_DYNAMIC_OPCODE_PARAMETER, {}},
155 }},
156 {{0},
157 {2},
158 {
159 {4, supercall, {3}},
160 {5, ABCKIT_ISA_API_DYNAMIC_OPCODE_THROW_IFSUPERNOTCORRECTCALL, {2}},
161 {6, ABCKIT_ISA_API_DYNAMIC_OPCODE_TRYLDGLOBALBYNAME, {}},
162 {7, ABCKIT_ISA_API_DYNAMIC_OPCODE_CALLARG1, {6, 3}},
163 {8, ABCKIT_ISA_API_DYNAMIC_OPCODE_THROW_IFSUPERNOTCORRECTCALL, {4}},
164 {9, ABCKIT_ISA_API_DYNAMIC_OPCODE_RETURN, {4}},
165 }},
166 {{1}, {}, {}}};
167
168 helpers::VerifyGraph(graph, bbSchema);
169 }
170
TestSuperCallThisRangeImpl(bool isWideMode)171 static void TestSuperCallThisRangeImpl(bool isWideMode)
172 {
173 auto output = helpers::ExecuteDynamicAbc(ABCKIT_ABC_DIR "ut/isa/isa_dynamic/supercall/supercall_dynamic.abc",
174 "supercall_dynamic");
175 EXPECT_TRUE(helpers::Match(output, "1\n"));
176
177 helpers::TransformMethod(
178 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/supercall/supercall_dynamic.abc",
179 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/supercall/supercall_dynamic_modified.abc", "supercall_dynamic.B",
180 [&](AbckitFile * /*file*/, AbckitCoreFunction * /*method*/, AbckitGraph *graph) {
181 TransformSuperCallThisRangeIr(graph, isWideMode);
182 },
183 [&](AbckitGraph *graph) { VerifySuperCallThisRangeIr(graph, isWideMode); });
184
185 output = helpers::ExecuteDynamicAbc(ABCKIT_ABC_DIR "ut/isa/isa_dynamic/supercall/supercall_dynamic_modified.abc",
186 "supercall_dynamic");
187 EXPECT_TRUE(helpers::Match(output, "1\n1\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16\n"));
188 }
189
TestSuperCallThisRangeImplLarge(bool isWideMode)190 static void TestSuperCallThisRangeImplLarge(bool isWideMode)
191 {
192 auto output = helpers::ExecuteDynamicAbc(ABCKIT_ABC_DIR "ut/isa/isa_dynamic/supercall/supercall_dynamic.abc",
193 "supercall_dynamic");
194 EXPECT_TRUE(helpers::Match(output, "1\n"));
195
196 helpers::TransformMethod(
197 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/supercall/supercall_dynamic.abc",
198 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/supercall/supercall_dynamic_modified.abc", "supercall_dynamic.B",
199 [&](AbckitFile *, AbckitCoreFunction *, AbckitGraph *graph) {
200 TransformSuperCallThisRangeIr(graph, isWideMode);
201 },
202 [&](AbckitGraph *graph) { VerifySuperCallThisRangeIr(graph, isWideMode); });
203
204 helpers::TransformMethod(
205 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/supercall/supercall_dynamic_modified.abc",
206 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/supercall/supercall_dynamic_modified.abc", "supercall_dynamic.D",
207 [&](AbckitFile *, AbckitCoreFunction *, AbckitGraph *graph) {
208 TransformSuperCallThisRangeIrLarge(graph, isWideMode);
209 },
210 [&]([[maybe_unused]] AbckitGraph *graph) {});
211
212 output = helpers::ExecuteDynamicAbc(ABCKIT_ABC_DIR "ut/isa/isa_dynamic/supercall/supercall_dynamic_modified.abc",
213 "supercall_dynamic");
214 EXPECT_TRUE(helpers::Match(
215 output, "1\n1\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16\n"));
216 }
217
TransformSuperCallSpreadIr(AbckitGraph * graph)218 static void TransformSuperCallSpreadIr(AbckitGraph *graph)
219 {
220 auto *par0 = helpers::FindFirstInst(graph, ABCKIT_ISA_API_DYNAMIC_OPCODE_PARAMETER);
221 ASSERT_NE(par0, nullptr);
222 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
223
224 auto *par3 = helpers::FindLastInst(graph, ABCKIT_ISA_API_DYNAMIC_OPCODE_PARAMETER);
225 ASSERT_NE(par3, nullptr);
226 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
227
228 auto *constant = helpers::FindFirstInst(graph, ABCKIT_ISA_API_DYNAMIC_OPCODE_CONSTANT);
229 ASSERT_NE(constant, nullptr);
230 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
231
232 auto *supercallthis = helpers::FindFirstInst(graph, ABCKIT_ISA_API_DYNAMIC_OPCODE_SUPERCALLTHISRANGE);
233 ASSERT_NE(supercallthis, nullptr);
234 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
235
236 auto *createemptyarr = g_dynG->iCreateCreateemptyarray(graph);
237 ASSERT_NE(createemptyarr, nullptr);
238 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
239
240 auto *starrayspread = g_dynG->iCreateStarrayspread(graph, par3, createemptyarr, constant);
241 ASSERT_NE(starrayspread, nullptr);
242 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
243
244 auto *supercallspread = g_dynG->iCreateSupercallspread(graph, par0, createemptyarr);
245 ASSERT_NE(supercallspread, nullptr);
246 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
247
248 auto *mainBB = g_implG->gGetBasicBlock(graph, 0x0);
249 ASSERT_NE(mainBB, nullptr);
250 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
251
252 g_implG->bbAddInstFront(mainBB, starrayspread);
253 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
254 g_implG->bbAddInstFront(mainBB, createemptyarr);
255 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
256
257 helpers::ReplaceInst(supercallthis, supercallspread);
258 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
259 }
260
VerifySuperCallSpreadIr(AbckitGraph * graph)261 static void VerifySuperCallSpreadIr(AbckitGraph *graph)
262 {
263 std::vector<helpers::BBSchema<AbckitIsaApiDynamicOpcode>> bbSchema = {
264 {{},
265 {1},
266 {
267 {0, ABCKIT_ISA_API_DYNAMIC_OPCODE_PARAMETER, {}},
268 {1, ABCKIT_ISA_API_DYNAMIC_OPCODE_PARAMETER, {}},
269 {2, ABCKIT_ISA_API_DYNAMIC_OPCODE_PARAMETER, {}},
270 {3, ABCKIT_ISA_API_DYNAMIC_OPCODE_PARAMETER, {}},
271 {5, ABCKIT_ISA_API_DYNAMIC_OPCODE_CONSTANT, {}},
272 }},
273 {{0},
274 {2},
275 {
276 {4, ABCKIT_ISA_API_DYNAMIC_OPCODE_CREATEEMPTYARRAY, {}},
277 {6, ABCKIT_ISA_API_DYNAMIC_OPCODE_STARRAYSPREAD, {3, 4, 5}},
278 {7, ABCKIT_ISA_API_DYNAMIC_OPCODE_SUPERCALLSPREAD, {0, 4}},
279 {8, ABCKIT_ISA_API_DYNAMIC_OPCODE_THROW_IFSUPERNOTCORRECTCALL, {2}},
280 {9, ABCKIT_ISA_API_DYNAMIC_OPCODE_TRYLDGLOBALBYNAME, {}},
281 {10, ABCKIT_ISA_API_DYNAMIC_OPCODE_CALLARG1, {9, 3}},
282 {11, ABCKIT_ISA_API_DYNAMIC_OPCODE_THROW_IFSUPERNOTCORRECTCALL, {7}},
283 {12, ABCKIT_ISA_API_DYNAMIC_OPCODE_RETURN, {7}},
284 }},
285 {{1}, {}, {}}};
286
287 helpers::VerifyGraph(graph, bbSchema);
288 }
289
TestSuperCallSpreadImpl()290 static void TestSuperCallSpreadImpl()
291 {
292 auto output = helpers::ExecuteDynamicAbc(ABCKIT_ABC_DIR "ut/isa/isa_dynamic/supercall/supercallspread_dynamic.abc",
293 "supercallspread_dynamic");
294 EXPECT_TRUE(helpers::Match(output, "0\n1,2\n"));
295
296 helpers::TransformMethod(
297 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/supercall/supercallspread_dynamic.abc",
298 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/supercall/supercallspread_dynamic_modified.abc", "supercallspread_dynamic.B",
299 [&](AbckitFile * /*file*/, AbckitCoreFunction * /*method*/, AbckitGraph *graph) {
300 TransformSuperCallSpreadIr(graph);
301 },
302 [&](AbckitGraph *graph) { VerifySuperCallSpreadIr(graph); });
303
304 output = helpers::ExecuteDynamicAbc(
305 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/supercall/supercallspread_dynamic_modified.abc", "supercallspread_dynamic");
306 EXPECT_TRUE(helpers::Match(output, "3\n1,2\n"));
307 }
308
VerifySuperCallArrowRangeIr(AbckitGraph * graph,bool isWideMode)309 static void VerifySuperCallArrowRangeIr(AbckitGraph *graph, bool isWideMode)
310 {
311 AbckitIsaApiDynamicOpcode superCall = isWideMode ? ABCKIT_ISA_API_DYNAMIC_OPCODE_WIDE_SUPERCALLARROWRANGE
312 : ABCKIT_ISA_API_DYNAMIC_OPCODE_SUPERCALLARROWRANGE;
313 std::vector<helpers::BBSchema<AbckitIsaApiDynamicOpcode>> bbSchema = {
314 {{},
315 {1},
316 {
317 {0, ABCKIT_ISA_API_DYNAMIC_OPCODE_PARAMETER, {}},
318 {1, ABCKIT_ISA_API_DYNAMIC_OPCODE_PARAMETER, {}},
319 {2, ABCKIT_ISA_API_DYNAMIC_OPCODE_PARAMETER, {}},
320 }},
321 {{0},
322 {2},
323 {
324 {3, ABCKIT_ISA_API_DYNAMIC_OPCODE_LDUNDEFINED, {}},
325 {4, superCall, {0, 3}},
326 {5, ABCKIT_ISA_API_DYNAMIC_OPCODE_THROW_IFSUPERNOTCORRECTCALL, {2}},
327 {6, ABCKIT_ISA_API_DYNAMIC_OPCODE_THROW_IFSUPERNOTCORRECTCALL, {4}},
328 {7, ABCKIT_ISA_API_DYNAMIC_OPCODE_RETURN, {4}},
329 }},
330 {{1}, {}, {}}};
331
332 helpers::VerifyGraph(graph, bbSchema);
333 }
334
TransformSuperCallArrowRangeIr(AbckitGraph * graph,bool isWideMode)335 static void TransformSuperCallArrowRangeIr(AbckitGraph *graph, bool isWideMode)
336 {
337 auto *obj = helpers::FindFirstInst(graph, ABCKIT_ISA_API_DYNAMIC_OPCODE_PARAMETER);
338
339 auto *undef = helpers::FindFirstInst(graph, ABCKIT_ISA_API_DYNAMIC_OPCODE_LDUNDEFINED);
340
341 auto *newsupercall = isWideMode ? g_dynG->iCreateWideSupercallarrowrange(graph, obj, 0x1, undef)
342 : g_dynG->iCreateSupercallarrowrange(graph, obj, 0x1, undef);
343 ASSERT_NE(newsupercall, nullptr);
344 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
345
346 auto *supercall = helpers::FindFirstInst(graph, ABCKIT_ISA_API_DYNAMIC_OPCODE_SUPERCALLTHISRANGE);
347
348 helpers::ReplaceInst(supercall, newsupercall);
349 }
350
TransformSuperCallArrowRangeIrLarge(AbckitGraph * graph,bool isWideMode)351 static void TransformSuperCallArrowRangeIrLarge(AbckitGraph *graph, bool isWideMode)
352 {
353 auto *obj = helpers::FindFirstInst(graph, ABCKIT_ISA_API_DYNAMIC_OPCODE_PARAMETER);
354
355 auto *par1 = g_implG->iGetNext(obj);
356 par1 = g_implG->iGetNext(g_implG->iGetNext(par1));
357 ASSERT_NE(par1, nullptr);
358 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
359
360 auto *par2 = g_implG->iGetNext(par1);
361 ASSERT_NE(par2, nullptr);
362 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
363 auto *par3 = g_implG->iGetNext(par2);
364 auto *par4 = g_implG->iGetNext(par3);
365 auto *par5 = g_implG->iGetNext(par4);
366
367 auto *newsupercall = isWideMode
368 ? g_dynG->iCreateWideSupercallarrowrange(graph, obj, 0x5, par1, par2, par3, par4, par5)
369 : g_dynG->iCreateSupercallarrowrange(graph, obj, 0x5, par1, par2, par3, par4, par5);
370 ASSERT_NE(newsupercall, nullptr);
371 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
372
373 auto *supercall = helpers::FindFirstInst(graph, ABCKIT_ISA_API_DYNAMIC_OPCODE_SUPERCALLTHISRANGE);
374
375 helpers::ReplaceInst(supercall, newsupercall);
376 }
377
TestSuperCallArrowRangeImpl(bool isWideMode)378 static void TestSuperCallArrowRangeImpl(bool isWideMode)
379 {
380 auto output = helpers::ExecuteDynamicAbc(ABCKIT_ABC_DIR "ut/isa/isa_dynamic/supercall/supercallarrow_dynamic.abc",
381 "supercallarrow_dynamic");
382 EXPECT_TRUE(helpers::Match(output, "Hello\n"));
383
384 helpers::TransformMethod(
385 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/supercall/supercallarrow_dynamic.abc",
386 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/supercall/supercallarrow_dynamic_modified.abc", "supercallarrow_dynamic.B",
387 [&](AbckitFile * /*file*/, AbckitCoreFunction * /*method*/, AbckitGraph *graph) {
388 TransformSuperCallArrowRangeIr(graph, isWideMode);
389 },
390 [&](AbckitGraph *graph) { VerifySuperCallArrowRangeIr(graph, isWideMode); });
391
392 output = helpers::ExecuteDynamicAbc(
393 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/supercall/supercallarrow_dynamic_modified.abc", "supercallarrow_dynamic");
394 EXPECT_TRUE(helpers::Match(output, "Hello\n"));
395 }
396
TestSuperCallArrowRangeImplLarge(bool isWideMode)397 static void TestSuperCallArrowRangeImplLarge(bool isWideMode)
398 {
399 auto output = helpers::ExecuteDynamicAbc(ABCKIT_ABC_DIR "ut/isa/isa_dynamic/supercall/supercallarrow_dynamic.abc",
400 "supercallarrow_dynamic");
401 EXPECT_TRUE(helpers::Match(output, "Hello\n"));
402
403 helpers::TransformMethod(
404 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/supercall/supercallarrow_dynamic.abc",
405 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/supercall/supercallarrow_dynamic_modified.abc", "supercallarrow_dynamic.D",
406 [&](AbckitFile *, AbckitCoreFunction *, AbckitGraph *graph) {
407 TransformSuperCallArrowRangeIrLarge(graph, isWideMode);
408 },
409 [&]([[maybe_unused]] AbckitGraph *graph) {});
410
411 output = helpers::ExecuteDynamicAbc(
412 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/supercall/supercallarrow_dynamic_modified.abc", "supercallarrow_dynamic");
413 EXPECT_TRUE(helpers::Match(output, "Hello\n"));
414 }
415
416 // Test: test-kind=api, api=IsaApiDynamicImpl::iCreateSupercallthisrange, abc-kind=ArkTS1, category=positive,
417 // extension=c
TEST_F(LibAbcKitCreateDynSuperCall,CreateSuperCallThisRange)418 TEST_F(LibAbcKitCreateDynSuperCall, CreateSuperCallThisRange)
419 {
420 TestSuperCallThisRangeImpl(false);
421 }
422
423 // Test: test-kind=api, api=IsaApiDynamicImpl::iCreateSupercallthisrange, abc-kind=ArkTS1, category=positive,
424 // extension=c
TEST_F(LibAbcKitCreateDynSuperCall,CreateSuperCallThisRange_large)425 TEST_F(LibAbcKitCreateDynSuperCall, CreateSuperCallThisRange_large)
426 {
427 TestSuperCallThisRangeImplLarge(false);
428 }
429
430 // Test: test-kind=api, api=IsaApiDynamicImpl::iCreateWideSupercallthisrange, abc-kind=ArkTS1, category=positive,
431 // extension=c
TEST_F(LibAbcKitCreateDynSuperCall,CreateWideSuperCallThisRange)432 TEST_F(LibAbcKitCreateDynSuperCall, CreateWideSuperCallThisRange)
433 {
434 TestSuperCallThisRangeImpl(true);
435 }
436
437 // Test: test-kind=api, api=IsaApiDynamicImpl::iCreateWideSupercallthisrange, abc-kind=ArkTS1, category=positive,
438 // extension=c
TEST_F(LibAbcKitCreateDynSuperCall,CreateWideSuperCallThisRange_large)439 TEST_F(LibAbcKitCreateDynSuperCall, CreateWideSuperCallThisRange_large)
440 {
441 TestSuperCallThisRangeImplLarge(true);
442 }
443
444 // Test: test-kind=api, api=IsaApiDynamicImpl::iCreateSupercallspread, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(LibAbcKitCreateDynSuperCall,CreateSuperCallSpread)445 TEST_F(LibAbcKitCreateDynSuperCall, CreateSuperCallSpread)
446 {
447 TestSuperCallSpreadImpl();
448 }
449
450 // Test: test-kind=api, api=IsaApiDynamicImpl::iCreateSupercallarrowrange, abc-kind=ArkTS1, category=positive,
451 // extension=c
TEST_F(LibAbcKitCreateDynSuperCall,CreateSuperCallArrowRange)452 TEST_F(LibAbcKitCreateDynSuperCall, CreateSuperCallArrowRange)
453 {
454 TestSuperCallArrowRangeImpl(false);
455 }
456
457 // Test: test-kind=api, api=IsaApiDynamicImpl::iCreateSupercallarrowrange, abc-kind=ArkTS1, category=positive,
458 // extension=c
TEST_F(LibAbcKitCreateDynSuperCall,CreateSuperCallArrowRange_large)459 TEST_F(LibAbcKitCreateDynSuperCall, CreateSuperCallArrowRange_large)
460 {
461 TestSuperCallArrowRangeImplLarge(false);
462 }
463
464 // Test: test-kind=api, api=IsaApiDynamicImpl::iCreateWideSupercallarrowrange, abc-kind=ArkTS1, category=positive,
465 // extension=c
TEST_F(LibAbcKitCreateDynSuperCall,CreateWideSuperCallArrowRange)466 TEST_F(LibAbcKitCreateDynSuperCall, CreateWideSuperCallArrowRange)
467 {
468 TestSuperCallArrowRangeImpl(true);
469 }
470
471 // Test: test-kind=api, api=IsaApiDynamicImpl::iCreateWideSupercallarrowrange, abc-kind=ArkTS1, category=positive,
472 // extension=c
TEST_F(LibAbcKitCreateDynSuperCall,CreateWideSuperCallArrowRange_large)473 TEST_F(LibAbcKitCreateDynSuperCall, CreateWideSuperCallArrowRange_large)
474 {
475 TestSuperCallArrowRangeImplLarge(true);
476 }
477
478 } // namespace libabckit::test
479 // NOLINTEND(readability-magic-numbers)
480