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 "ir_impl.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
25 #include <gtest/gtest.h>
26
27 // NOLINTBEGIN(readability-magic-numbers)
28 namespace libabckit::test {
29
30 static auto g_impl = AbckitGetApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
31 static auto g_implI = AbckitGetInspectApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
32 static auto g_implM = AbckitGetModifyApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
33 static auto g_implG = AbckitGetGraphApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
34 static auto g_dynG = AbckitGetIsaApiDynamicImpl(ABCKIT_VERSION_RELEASE_1_0_0);
35
36 class LibAbcKitCreateDynCreateobjectwithexcludedkeys : public ::testing::Test {};
37
FillMainBb1(AbckitFile * file,AbckitGraph * graph,AbckitBasicBlock * bbMain,bool isWide)38 static void FillMainBb1(AbckitFile *file, AbckitGraph *graph, AbckitBasicBlock *bbMain, bool isWide)
39 {
40 auto *createobjectwithbuffer = helpers::FindFirstInst(graph, ABCKIT_ISA_API_DYNAMIC_OPCODE_CREATEOBJECTWITHBUFFER);
41 auto *stringValue = g_implM->createString(file, "value", strlen("value"));
42 auto *stringAge = g_implM->createString(file, "age", strlen("age"));
43 auto *loadStringValue = g_dynG->iCreateLoadString(graph, stringValue);
44 auto *loadStringAge = g_dynG->iCreateLoadString(graph, stringAge);
45
46 auto *createobjectwithexcludedkeys =
47 isWide ? g_dynG->iCreateWideCreateobjectwithexcludedkeys(graph, createobjectwithbuffer, loadStringValue, 0x1,
48 loadStringAge)
49 : g_dynG->iCreateCreateobjectwithexcludedkeys(graph, createobjectwithbuffer, loadStringValue, 0x1,
50 loadStringAge);
51 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
52 auto *ldundef2 = g_dynG->iCreateLdundefined(graph);
53 auto *returnUndef = g_dynG->iCreateReturnundefined(graph);
54
55 g_implG->bbAddInstBack(bbMain, loadStringValue);
56 g_implG->bbAddInstBack(bbMain, loadStringAge);
57 g_implG->bbAddInstBack(bbMain, createobjectwithexcludedkeys);
58
59 auto *stringPrint = g_implM->createString(file, "print", strlen("print"));
60 auto *tryldglobalbyname = g_dynG->iCreateTryldglobalbyname(graph, stringPrint);
61 auto *callarg11 = g_dynG->iCreateCallarg1(graph, tryldglobalbyname, loadStringValue);
62 auto *callarg12 = g_dynG->iCreateCallarg1(graph, tryldglobalbyname, loadStringAge);
63 g_implG->bbAddInstBack(bbMain, tryldglobalbyname);
64 g_implG->bbAddInstBack(bbMain, callarg11);
65 g_implG->bbAddInstBack(bbMain, callarg12);
66 g_implG->bbAddInstBack(bbMain, ldundef2);
67 g_implG->bbAddInstBack(bbMain, returnUndef);
68 }
69
FillMainBb2(AbckitFile * file,AbckitGraph * graph,AbckitBasicBlock * bbMain,bool isWide)70 static void FillMainBb2(AbckitFile *file, AbckitGraph *graph, AbckitBasicBlock *bbMain, bool isWide)
71 {
72 auto *createobjectwithbuffer = helpers::FindFirstInst(graph, ABCKIT_ISA_API_DYNAMIC_OPCODE_CREATEOBJECTWITHBUFFER);
73 auto *stringValue = g_implM->createString(file, "value", strlen("value"));
74 auto *stringAge = g_implM->createString(file, "age", strlen("age"));
75 auto *stringName = g_implM->createString(file, "name", strlen("name"));
76 auto *loadStringValue = g_dynG->iCreateLoadString(graph, stringValue);
77 auto *loadStringAge = g_dynG->iCreateLoadString(graph, stringAge);
78 auto *createobjectwithexcludedkeys =
79 isWide ? g_dynG->iCreateWideCreateobjectwithexcludedkeys(graph, createobjectwithbuffer, loadStringValue, 0x1,
80 loadStringAge)
81 : g_dynG->iCreateCreateobjectwithexcludedkeys(graph, createobjectwithbuffer, loadStringValue, 0x1,
82 loadStringAge);
83 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
84
85 g_implG->bbAddInstBack(bbMain, loadStringValue);
86 g_implG->bbAddInstBack(bbMain, loadStringAge);
87 g_implG->bbAddInstBack(bbMain, createobjectwithexcludedkeys);
88
89 auto *ldundef2 = g_dynG->iCreateLdundefined(graph);
90 auto *returnUndef = g_dynG->iCreateReturnundefined(graph);
91 auto *stringPrint = g_implM->createString(file, "print", strlen("print"));
92 auto *tryldglobalbyname = g_dynG->iCreateTryldglobalbyname(graph, stringPrint);
93 auto *ldobjbynameValue = g_dynG->iCreateLdobjbyname(graph, createobjectwithexcludedkeys, stringValue);
94 auto *ldobjbynameAge = g_dynG->iCreateLdobjbyname(graph, createobjectwithexcludedkeys, stringAge);
95 auto *ldobjbynameName = g_dynG->iCreateLdobjbyname(graph, createobjectwithexcludedkeys, stringName);
96 auto *callarg11 = g_dynG->iCreateCallarg1(graph, tryldglobalbyname, ldobjbynameValue);
97 auto *callarg12 = g_dynG->iCreateCallarg1(graph, tryldglobalbyname, ldobjbynameAge);
98 auto *callarg13 = g_dynG->iCreateCallarg1(graph, tryldglobalbyname, ldobjbynameName);
99 g_implG->bbAddInstBack(bbMain, tryldglobalbyname);
100 g_implG->bbAddInstBack(bbMain, ldobjbynameValue);
101 g_implG->bbAddInstBack(bbMain, ldobjbynameAge);
102 g_implG->bbAddInstBack(bbMain, ldobjbynameName);
103 g_implG->bbAddInstBack(bbMain, callarg11);
104 g_implG->bbAddInstBack(bbMain, callarg12);
105 g_implG->bbAddInstBack(bbMain, callarg13);
106 g_implG->bbAddInstBack(bbMain, ldundef2);
107 g_implG->bbAddInstBack(bbMain, returnUndef);
108 }
109
FillUndefBB(AbckitGraph * graph,AbckitBasicBlock * bbUndef)110 static void FillUndefBB(AbckitGraph *graph, AbckitBasicBlock *bbUndef)
111 {
112 auto *createobjectwithbuffer = helpers::FindFirstInst(graph, ABCKIT_ISA_API_DYNAMIC_OPCODE_CREATEOBJECTWITHBUFFER);
113 auto *ldundef = g_dynG->iCreateLdundefined(graph);
114 auto *strictnoteq2 = g_dynG->iCreateStrictnoteq(graph, ldundef, createobjectwithbuffer);
115 auto *ifInst2 = g_dynG->iCreateIf(graph, strictnoteq2, ABCKIT_ISA_API_DYNAMIC_CONDITION_CODE_CC_NE);
116
117 g_implG->bbAddInstBack(bbUndef, ldundef);
118 g_implG->bbAddInstBack(bbUndef, strictnoteq2);
119 g_implG->bbAddInstBack(bbUndef, ifInst2);
120 }
121
122 // Test: test-kind=api, api=IsaApiDynamicImpl::iCreateCreateobjectwithexcludedkeys, abc-kind=ArkTS1, category=positive,
123 // extension=c
TEST_F(LibAbcKitCreateDynCreateobjectwithexcludedkeys,IcreateCreateobjectwithexcludedkeys_1)124 TEST_F(LibAbcKitCreateDynCreateobjectwithexcludedkeys, IcreateCreateobjectwithexcludedkeys_1)
125 {
126 auto output =
127 helpers::ExecuteDynamicAbc(ABCKIT_ABC_DIR "ut/isa/isa_dynamic/create/createobjectwithexcludedkeys_dynamic.abc",
128 "createobjectwithexcludedkeys_dynamic");
129 EXPECT_TRUE(helpers::Match(output, ""));
130
131 helpers::TransformMethod(
132 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/create/createobjectwithexcludedkeys_dynamic.abc",
133 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/create/createobjectwithexcludedkeys_dynamic_modified.abc", "func_main_0",
134 [&](AbckitFile *file, AbckitCoreFunction * /*method*/, AbckitGraph *graph) {
135 auto *bb = helpers::BBgetSuccBlocks(g_implG->gGetStartBasicBlock(graph))[0];
136 auto *bbUndef = g_implG->bbCreateEmpty(graph);
137 auto *bbThrow = g_implG->bbCreateEmpty(graph);
138 auto *bbMain = g_implG->bbCreateEmpty(graph);
139
140 g_implG->bbDisconnectSuccBlock(bb, 0);
141 g_implG->bbAppendSuccBlock(bb, bbThrow);
142 g_implG->bbAppendSuccBlock(bb, bbUndef);
143 g_implG->bbAppendSuccBlock(bbUndef, bbMain);
144 g_implG->bbAppendSuccBlock(bbUndef, bbThrow);
145 g_implG->bbAppendSuccBlock(bbThrow, bbMain);
146 g_implG->bbAppendSuccBlock(bbMain, g_implG->gGetEndBasicBlock(graph));
147
148 auto *createobjectwithbuffer =
149 helpers::FindFirstInst(graph, ABCKIT_ISA_API_DYNAMIC_OPCODE_CREATEOBJECTWITHBUFFER);
150 g_implG->iRemove(g_implG->iGetNext(createobjectwithbuffer));
151 g_implG->iRemove(g_implG->iGetNext(createobjectwithbuffer));
152
153 auto *ldnull = g_dynG->iCreateLdnull(graph);
154 auto *strictnoteq = g_dynG->iCreateStrictnoteq(graph, ldnull, createobjectwithbuffer);
155 auto *ifInst = g_dynG->iCreateIf(graph, strictnoteq, ABCKIT_ISA_API_DYNAMIC_CONDITION_CODE_CC_EQ);
156 g_implG->iInsertAfter(ldnull, createobjectwithbuffer);
157 g_implG->iInsertAfter(strictnoteq, ldnull);
158 g_implG->iInsertAfter(ifInst, strictnoteq);
159
160 FillUndefBB(graph, bbUndef);
161
162 auto *throwInst = g_dynG->iCreateThrowPatternnoncoercible(graph);
163 g_implG->bbAddInstBack(bbThrow, throwInst);
164
165 FillMainBb1(file, graph, bbMain, false);
166 },
167 [&]([[maybe_unused]] AbckitGraph *graph) {});
168
169 output = helpers::ExecuteDynamicAbc(ABCKIT_ABC_DIR
170 "ut/isa/isa_dynamic/create/createobjectwithexcludedkeys_dynamic_modified.abc",
171 "createobjectwithexcludedkeys_dynamic");
172 EXPECT_TRUE(helpers::Match(output, "value\nage\n"));
173 }
174
175 // Test: test-kind=api, api=IsaApiDynamicImpl::iCreateCreateobjectwithexcludedkeys, abc-kind=ArkTS1, category=positive,
176 // extension=c
TEST_F(LibAbcKitCreateDynCreateobjectwithexcludedkeys,IcreateCreateobjectwithexcludedkeys_2)177 TEST_F(LibAbcKitCreateDynCreateobjectwithexcludedkeys, IcreateCreateobjectwithexcludedkeys_2)
178 {
179 auto output =
180 helpers::ExecuteDynamicAbc(ABCKIT_ABC_DIR "ut/isa/isa_dynamic/create/createobjectwithexcludedkeys_dynamic.abc",
181 "createobjectwithexcludedkeys_dynamic");
182 EXPECT_TRUE(helpers::Match(output, ""));
183
184 helpers::TransformMethod(
185 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/create/createobjectwithexcludedkeys_dynamic.abc",
186 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/create/createobjectwithexcludedkeys_dynamic_modified.abc", "func_main_0",
187 [&](AbckitFile *file, AbckitCoreFunction * /*method*/, AbckitGraph *graph) {
188 auto *bb = helpers::BBgetSuccBlocks(g_implG->gGetStartBasicBlock(graph))[0];
189 auto *bbUndef = g_implG->bbCreateEmpty(graph);
190 auto *bbThrow = g_implG->bbCreateEmpty(graph);
191 auto *bbMain = g_implG->bbCreateEmpty(graph);
192
193 g_implG->bbDisconnectSuccBlock(bb, 0);
194 g_implG->bbAppendSuccBlock(bb, bbThrow);
195 g_implG->bbAppendSuccBlock(bb, bbUndef);
196 g_implG->bbAppendSuccBlock(bbUndef, bbMain);
197 g_implG->bbAppendSuccBlock(bbUndef, bbThrow);
198 g_implG->bbAppendSuccBlock(bbThrow, bbMain);
199 g_implG->bbAppendSuccBlock(bbMain, g_implG->gGetEndBasicBlock(graph));
200
201 auto *createobjectwithbuffer =
202 helpers::FindFirstInst(graph, ABCKIT_ISA_API_DYNAMIC_OPCODE_CREATEOBJECTWITHBUFFER);
203 g_implG->iRemove(g_implG->iGetNext(createobjectwithbuffer));
204 g_implG->iRemove(g_implG->iGetNext(createobjectwithbuffer));
205
206 auto *ldnull = g_dynG->iCreateLdnull(graph);
207 auto *strictnoteq = g_dynG->iCreateStrictnoteq(graph, ldnull, createobjectwithbuffer);
208 auto *ifInst = g_dynG->iCreateIf(graph, strictnoteq, ABCKIT_ISA_API_DYNAMIC_CONDITION_CODE_CC_EQ);
209 g_implG->iInsertAfter(ldnull, createobjectwithbuffer);
210 g_implG->iInsertAfter(strictnoteq, ldnull);
211 g_implG->iInsertAfter(ifInst, strictnoteq);
212
213 FillUndefBB(graph, bbUndef);
214
215 auto *throwInst = g_dynG->iCreateThrowPatternnoncoercible(graph);
216 g_implG->bbAddInstBack(bbThrow, throwInst);
217
218 FillMainBb2(file, graph, bbMain, false);
219 },
220 [&]([[maybe_unused]] AbckitGraph *graph) {});
221
222 output = helpers::ExecuteDynamicAbc(ABCKIT_ABC_DIR
223 "ut/isa/isa_dynamic/create/createobjectwithexcludedkeys_dynamic_modified.abc",
224 "createobjectwithexcludedkeys_dynamic");
225 EXPECT_TRUE(helpers::Match(output, "undefined\nundefined\nname\n"));
226 }
227
228 // Test: test-kind=api, api=IsaApiDynamicImpl::iCreateWideCreateobjectwithexcludedkeys, abc-kind=ArkTS1,
229 // category=positive
TEST_F(LibAbcKitCreateDynCreateobjectwithexcludedkeys,IcreateWideCreateobjectwithexcludedkeys_1)230 TEST_F(LibAbcKitCreateDynCreateobjectwithexcludedkeys, IcreateWideCreateobjectwithexcludedkeys_1)
231 {
232 auto output =
233 helpers::ExecuteDynamicAbc(ABCKIT_ABC_DIR "ut/isa/isa_dynamic/create/createobjectwithexcludedkeys_dynamic.abc",
234 "createobjectwithexcludedkeys_dynamic");
235 EXPECT_TRUE(helpers::Match(output, ""));
236
237 helpers::TransformMethod(
238 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/create/createobjectwithexcludedkeys_dynamic.abc",
239 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/create/createobjectwithexcludedkeys_dynamic_modified.abc", "func_main_0",
240 [&](AbckitFile *file, AbckitCoreFunction * /*method*/, AbckitGraph *graph) {
241 auto *bb = helpers::BBgetSuccBlocks(g_implG->gGetStartBasicBlock(graph))[0];
242 auto *bbUndef = g_implG->bbCreateEmpty(graph);
243 auto *bbThrow = g_implG->bbCreateEmpty(graph);
244 auto *bbMain = g_implG->bbCreateEmpty(graph);
245
246 g_implG->bbDisconnectSuccBlock(bb, 0);
247 g_implG->bbAppendSuccBlock(bb, bbThrow);
248 g_implG->bbAppendSuccBlock(bb, bbUndef);
249 g_implG->bbAppendSuccBlock(bbUndef, bbMain);
250 g_implG->bbAppendSuccBlock(bbUndef, bbThrow);
251 g_implG->bbAppendSuccBlock(bbThrow, bbMain);
252 g_implG->bbAppendSuccBlock(bbMain, g_implG->gGetEndBasicBlock(graph));
253
254 auto *createobjectwithbuffer =
255 helpers::FindFirstInst(graph, ABCKIT_ISA_API_DYNAMIC_OPCODE_CREATEOBJECTWITHBUFFER);
256 g_implG->iRemove(g_implG->iGetNext(createobjectwithbuffer));
257 g_implG->iRemove(g_implG->iGetNext(createobjectwithbuffer));
258
259 auto *ldnull = g_dynG->iCreateLdnull(graph);
260 auto *strictnoteq = g_dynG->iCreateStrictnoteq(graph, ldnull, createobjectwithbuffer);
261 auto *ifInst = g_dynG->iCreateIf(graph, strictnoteq, ABCKIT_ISA_API_DYNAMIC_CONDITION_CODE_CC_EQ);
262 g_implG->iInsertAfter(ldnull, createobjectwithbuffer);
263 g_implG->iInsertAfter(strictnoteq, ldnull);
264 g_implG->iInsertAfter(ifInst, strictnoteq);
265
266 FillUndefBB(graph, bbUndef);
267
268 auto *throwInst = g_dynG->iCreateThrowPatternnoncoercible(graph);
269 g_implG->bbAddInstBack(bbThrow, throwInst);
270
271 FillMainBb1(file, graph, bbMain, true);
272 },
273 [&]([[maybe_unused]] AbckitGraph *graph) {});
274
275 output = helpers::ExecuteDynamicAbc(ABCKIT_ABC_DIR
276 "ut/isa/isa_dynamic/create/createobjectwithexcludedkeys_dynamic_modified.abc",
277 "createobjectwithexcludedkeys_dynamic");
278 EXPECT_TRUE(helpers::Match(output, "value\nage\n"));
279 }
280
281 // Test: test-kind=api, api=IsaApiDynamicImpl::iCreateWideCreateobjectwithexcludedkeys, abc-kind=ArkTS1,
282 // category=positive
TEST_F(LibAbcKitCreateDynCreateobjectwithexcludedkeys,IcreateWideCreateobjectwithexcludedkeys_2)283 TEST_F(LibAbcKitCreateDynCreateobjectwithexcludedkeys, IcreateWideCreateobjectwithexcludedkeys_2)
284 {
285 auto output =
286 helpers::ExecuteDynamicAbc(ABCKIT_ABC_DIR "ut/isa/isa_dynamic/create/createobjectwithexcludedkeys_dynamic.abc",
287 "createobjectwithexcludedkeys_dynamic");
288 EXPECT_TRUE(helpers::Match(output, ""));
289
290 helpers::TransformMethod(
291 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/create/createobjectwithexcludedkeys_dynamic.abc",
292 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/create/createobjectwithexcludedkeys_dynamic_modified.abc", "func_main_0",
293 [&](AbckitFile *file, AbckitCoreFunction * /*method*/, AbckitGraph *graph) {
294 auto *bb = helpers::BBgetSuccBlocks(g_implG->gGetStartBasicBlock(graph))[0];
295 auto *bbUndef = g_implG->bbCreateEmpty(graph);
296 auto *bbThrow = g_implG->bbCreateEmpty(graph);
297 auto *bbMain = g_implG->bbCreateEmpty(graph);
298
299 g_implG->bbDisconnectSuccBlock(bb, 0);
300 g_implG->bbAppendSuccBlock(bb, bbThrow);
301 g_implG->bbAppendSuccBlock(bb, bbUndef);
302 g_implG->bbAppendSuccBlock(bbUndef, bbMain);
303 g_implG->bbAppendSuccBlock(bbUndef, bbThrow);
304 g_implG->bbAppendSuccBlock(bbThrow, bbMain);
305 g_implG->bbAppendSuccBlock(bbMain, g_implG->gGetEndBasicBlock(graph));
306
307 auto *createobjectwithbuffer =
308 helpers::FindFirstInst(graph, ABCKIT_ISA_API_DYNAMIC_OPCODE_CREATEOBJECTWITHBUFFER);
309 g_implG->iRemove(g_implG->iGetNext(createobjectwithbuffer));
310 g_implG->iRemove(g_implG->iGetNext(createobjectwithbuffer));
311
312 auto *ldnull = g_dynG->iCreateLdnull(graph);
313 auto *strictnoteq = g_dynG->iCreateStrictnoteq(graph, ldnull, createobjectwithbuffer);
314 auto *ifInst = g_dynG->iCreateIf(graph, strictnoteq, ABCKIT_ISA_API_DYNAMIC_CONDITION_CODE_CC_EQ);
315 g_implG->iInsertAfter(ldnull, createobjectwithbuffer);
316 g_implG->iInsertAfter(strictnoteq, ldnull);
317 g_implG->iInsertAfter(ifInst, strictnoteq);
318
319 FillUndefBB(graph, bbUndef);
320
321 auto *throwInst = g_dynG->iCreateThrowPatternnoncoercible(graph);
322 g_implG->bbAddInstBack(bbThrow, throwInst);
323
324 FillMainBb2(file, graph, bbMain, true);
325 },
326 [&]([[maybe_unused]] AbckitGraph *graph) {});
327
328 output = helpers::ExecuteDynamicAbc(ABCKIT_ABC_DIR
329 "ut/isa/isa_dynamic/create/createobjectwithexcludedkeys_dynamic_modified.abc",
330 "createobjectwithexcludedkeys_dynamic");
331 EXPECT_TRUE(helpers::Match(output, "undefined\nundefined\nname\n"));
332 }
333
334 } // namespace libabckit::test
335 // NOLINTEND(readability-magic-numbers)
336