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 <cstdlib>
17 #include <gtest/gtest.h>
18 #include <iostream>
19 #include <string>
20 #include <vector>
21 #include "abc2program_driver.h"
22 #include "abc2program_test_utils.h"
23 #include "common/abc_file_utils.h"
24 #include "modifiers.h"
25
26 using namespace testing::ext;
27
28 namespace panda::abc2program {
29
30 struct FuncName {
31 std::string hello_world = ".#~@0=#HelloWorld";
32 std::string foo = ".#*#foo";
33 std::string goo = ".#*#goo";
34 std::string hoo = ".#*#hoo";
35 std::string main = ".func_main_0";
36 std::string method = ".#*@3*#method";
37 std::string lit = ".#~@1>#lit";
38 std::string add = ".#*#add";
39 std::string generate = ".#*#generateFunc";
40 std::string async_generate = ".#*#asyncGenerateFunc";
41 std::string async_arrow = ".#*#asyncArrowFunc";
42 std::string nested_literal_array = ".#~@2>#NestedLiteralArray";
43 };
44
45 const FuncName FUNC_NAME;
46 const std::string HELLO_WORLD_ABC_TEST_FILE_NAME = GRAPH_TEST_ABC_DIR "HelloWorld.abc";
47 const std::string HELLO_WORLD_DEBUG_ABC_TEST_FILE_NAME = GRAPH_TEST_ABC_DIR "HelloWorldDebug.abc";
48 const bool REMOVE_DUMP_RESULT_FILES = true;
49 const std::string HELLO_WORLD_DUMP_RESULT_FILE_NAME = GRAPH_TEST_ABC_DUMP_DIR "HelloWorldDumpResult.txt";
50 const std::string HELLO_WORLD_DEBUG_DUMP_RESULT_FILE_NAME = GRAPH_TEST_ABC_DUMP_DIR "HelloWorldDebugDumpResult.txt";
51 const std::string HELLO_WORLD_DUMP_EXPECTED_FILE_NAME = GRAPH_TEST_ABC_DUMP_DIR "HelloWorldDumpExpected.txt";
52 const std::string HELLO_WORLD_DEBUG_DUMP_EXPECTED_FILE_NAME = GRAPH_TEST_ABC_DUMP_DIR "HelloWorldDebugDumpExpected.txt";
53 constexpr uint32_t NUM_OF_CODE_TEST_UT_FOO_METHOD_INS = 73;
54 constexpr uint8_t INS_SIZE_OF_FUNCTION_HOO = 5;
55 constexpr uint8_t IMMS_SIZE_OF_OPCODE_FLDAI = 1;
56 constexpr uint8_t SIZE_OF_LITERAL_ARRAY_TABLE = 7;
57 constexpr uint8_t TOTAL_NUM_OF_ASYNC_METHOD_LITERALS = 6;
58 constexpr uint8_t TOTAL_NUM_OF_MODULE_LITERALS = 21;
59 constexpr uint8_t TOTAL_NUM_OF_NESTED_LITERALS = 10;
60 constexpr uint8_t NUM_OF_MODULE_REQUESTS = 4;
61 constexpr uint8_t NUM_OF_REGULAR_IMPORTS = 1;
62 constexpr uint8_t NUM_OF_NAMESPACE_IMPORTS = 1;
63 constexpr uint8_t NUM_OF_LOCAL_EXPORTS = 1;
64 constexpr uint8_t NUM_OF_INDIRECT_EXPORTS = 1;
65 constexpr uint8_t NUM_OF_STAR_EXPORTS = 1;
66
GetFunction(const std::string & name,const pandasm::Program & program)67 static const pandasm::Function *GetFunction(const std::string &name,
68 const pandasm::Program &program)
69 {
70 ASSERT(program.function_table.find(name) != program.function_table.end());
71 return &(program.function_table.find(name)->second);
72 }
73
74 class Abc2ProgramHelloWorldTest : public testing::Test {
75 public:
SetUpTestCase(void)76 static void SetUpTestCase(void) {}
TearDownTestCase(void)77 static void TearDownTestCase(void) {}
SetUp()78 void SetUp()
79 {
80 (void)driver_.Compile(HELLO_WORLD_ABC_TEST_FILE_NAME);
81 prog_ = &(driver_.GetProgram());
82 hello_world_function_ = GetFunction(FUNC_NAME.hello_world, *prog_);
83 foo_function_ = GetFunction(FUNC_NAME.foo, *prog_);
84 goo_function_ = GetFunction(FUNC_NAME.goo, *prog_);
85 hoo_function_ = GetFunction(FUNC_NAME.hoo, *prog_);
86 main_function_ = GetFunction(FUNC_NAME.main, *prog_);
87 method_function_ = GetFunction(FUNC_NAME.method, *prog_);
88 lit_function_ = GetFunction(FUNC_NAME.lit, *prog_);
89 add_function_ = GetFunction(FUNC_NAME.add, *prog_);
90 generate_function_ = GetFunction(FUNC_NAME.generate, *prog_);
91 async_generate_function_ = GetFunction(FUNC_NAME.async_generate, *prog_);
92 async_arrow_function_ = GetFunction(FUNC_NAME.async_arrow, *prog_);
93 }
94
TearDown()95 void TearDown() {}
96
97 Abc2ProgramDriver driver_;
98 const pandasm::Program *prog_ = nullptr;
99 const pandasm::Function *hello_world_function_ = nullptr;
100 const pandasm::Function *foo_function_ = nullptr;
101 const pandasm::Function *goo_function_ = nullptr;
102 const pandasm::Function *hoo_function_ = nullptr;
103 const pandasm::Function *main_function_ = nullptr;
104 const pandasm::Function *method_function_ = nullptr;
105 const pandasm::Function *lit_function_ = nullptr;
106 const pandasm::Function *add_function_ = nullptr;
107 const pandasm::Function *generate_function_ = nullptr;
108 const pandasm::Function *async_generate_function_ = nullptr;
109 const pandasm::Function *async_arrow_function_ = nullptr;
110 };
111
112 class Abc2ProgramHelloWorldDebugTest : public testing::Test {
113 public:
SetUpTestCase(void)114 static void SetUpTestCase(void) {}
TearDownTestCase(void)115 static void TearDownTestCase(void) {}
SetUp()116 void SetUp()
117 {
118 (void)driver_.Compile(HELLO_WORLD_DEBUG_ABC_TEST_FILE_NAME);
119 prog_ = &(driver_.GetProgram());
120 foo_function_ = GetFunction(FUNC_NAME.foo, *prog_);
121 main_function_ = GetFunction(FUNC_NAME.main, *prog_);
122 }
123
TearDown()124 void TearDown() {}
125
126 Abc2ProgramDriver driver_;
127 const pandasm::Program *prog_ = nullptr;
128 const pandasm::Function *foo_function_ = nullptr;
129 const pandasm::Function *main_function_ = nullptr;
130 };
131
132 /*------------------------------------- Cases of release mode below -------------------------------------*/
133
134 /**
135 * @tc.name: abc2program_hello_world_test_dump
136 * @tc.desc: check dump result in release mode.
137 * @tc.type: FUNC
138 * @tc.require: IADG92
139 */
140 HWTEST_F(Abc2ProgramHelloWorldTest, abc2program_hello_world_test_dump, TestSize.Level1)
141 {
142 driver_.Dump(HELLO_WORLD_DUMP_RESULT_FILE_NAME);
143 EXPECT_TRUE(Abc2ProgramTestUtils::ValidateDumpResult(HELLO_WORLD_DUMP_RESULT_FILE_NAME,
144 HELLO_WORLD_DUMP_EXPECTED_FILE_NAME));
145 if (REMOVE_DUMP_RESULT_FILES) {
146 Abc2ProgramTestUtils::RemoveDumpResultFile(HELLO_WORLD_DUMP_RESULT_FILE_NAME);
147 }
148 }
149
150 /**
151 * @tc.name: abc2program_hello_world_test_func_annotation
152 * @tc.desc: get program function annotation.
153 * @tc.type: FUNC
154 * @tc.require: #I9AQ3K
155 */
156 HWTEST_F(Abc2ProgramHelloWorldTest, abc2program_hello_world_test_func_annotation, TestSize.Level1)
157 {
158 constexpr uint32_t NUM_OF_HELLO_WORLD_TEST_UT_HELLO_WORLD_SLOTS_NUM = 2;
159 constexpr uint32_t NUM_OF_HELLO_WORLD_TEST_UT_FOO_SLOTS_NUM = 24;
160 constexpr uint32_t NUM_OF_HELLO_WORLD_TEST_UT_GOO_SLOTS_NUM = 0;
161 EXPECT_TRUE(hello_world_function_->GetSlotsNum() == NUM_OF_HELLO_WORLD_TEST_UT_HELLO_WORLD_SLOTS_NUM);
162 EXPECT_TRUE(foo_function_->GetSlotsNum() == NUM_OF_HELLO_WORLD_TEST_UT_FOO_SLOTS_NUM);
163 EXPECT_TRUE(goo_function_->GetSlotsNum() == NUM_OF_HELLO_WORLD_TEST_UT_GOO_SLOTS_NUM);
164 EXPECT_TRUE(hello_world_function_->concurrent_module_requests.empty());
165 EXPECT_TRUE(foo_function_->concurrent_module_requests.empty());
166 EXPECT_TRUE(goo_function_->concurrent_module_requests.empty());
167 }
168
169 /**
170 * @tc.name: abc2program_hello_world_test_field_metadata
171 * @tc.desc: get program field metadata.
172 * @tc.type: FUNC
173 * @tc.require: issueI98NGN
174 */
175 HWTEST_F(Abc2ProgramHelloWorldTest, abc2program_hello_world_test_field_metadata, TestSize.Level1)
176 {
177 for (const auto &it : prog_->record_table) {
178 if (it.first == "_ESModuleRecord") {
179 const pandasm::Record &record = it.second;
180 const std::vector<pandasm::Field> &field_list = record.field_list;
181 const pandasm::Field &field = field_list[0];
182 EXPECT_TRUE(field.type.GetPandasmName() == "u32");
183 EXPECT_TRUE(field.name.find("HelloWorld.ts") != std::string::npos);
184 }
185 }
186 }
187
188 /**
189 * @tc.name: abc2program_hello_world_test_lang
190 * @tc.desc: get program language.
191 * @tc.type: FUNC
192 * @tc.require: issueI96G2J
193 */
194 HWTEST_F(Abc2ProgramHelloWorldTest, abc2program_hello_world_test_lang, TestSize.Level1)
195 {
196 panda_file::SourceLang expected_lang = panda_file::SourceLang::ECMASCRIPT;
197 bool lang_matched = (prog_->lang == expected_lang);
198 EXPECT_TRUE(lang_matched);
199 }
200
201 /**
202 * @tc.name: abc2program_hello_world_test_literalarray_table
203 * @tc.desc: get program literalarray_table.
204 * @tc.type: FUNC
205 * @tc.require: issueI9DK5D
206 */
207 HWTEST_F(Abc2ProgramHelloWorldTest, abc2program_hello_world_test_literalarray_table, TestSize.Level1)
208 {
209 std::set<size_t> literals_sizes;
210 std::vector<std::string> literal_array_keys;
211 for (const auto &it : prog_->literalarray_table) {
212 const pandasm::LiteralArray &literal_array = it.second;
213 size_t literals_size = literal_array.literals_.size();
214 literals_sizes.insert(literals_size);
215 literal_array_keys.emplace_back(it.first);
216 }
217 EXPECT_TRUE(Abc2ProgramTestUtils::ValidateLiteralsSizes(literals_sizes));
218 EXPECT_TRUE(Abc2ProgramTestUtils::ValidateLiteralArrayKeys(literal_array_keys));
219 }
220
221 /**
222 * @tc.name: abc2program_async_method_literals
223 * @tc.desc: get and check literals of async generator method.
224 * @tc.type: FUNC
225 * @tc.require: issueI9SLHH
226 */
227 HWTEST_F(Abc2ProgramHelloWorldTest, abc2program_async_method_literals, TestSize.Level1)
228 {
229 auto &literal_array_table = prog_->literalarray_table;
230 EXPECT_EQ(literal_array_table.size(), SIZE_OF_LITERAL_ARRAY_TABLE);
231 panda::pandasm::LiteralArray async_literals;
232 for (auto &item : literal_array_table) {
233 for (auto &literal : item.second.literals_) {
234 if (literal.tag_ == panda_file::LiteralTag::ASYNCGENERATORMETHOD) {
235 async_literals = item.second;
236 break;
237 }
238 }
239 if (async_literals.literals_.size() != 0) {
240 break;
241 }
242 }
243 EXPECT_EQ(async_literals.literals_.size(), TOTAL_NUM_OF_ASYNC_METHOD_LITERALS);
244 auto it = async_literals.literals_.begin();
245 EXPECT_EQ(it->tag_, panda_file::LiteralTag::TAGVALUE);
246 ++it;
247 EXPECT_EQ(it->tag_, panda_file::LiteralTag::STRING);
248 ++it;
249 EXPECT_EQ(it->tag_, panda_file::LiteralTag::TAGVALUE);
250 ++it;
251 EXPECT_EQ(it->tag_, panda_file::LiteralTag::ASYNCGENERATORMETHOD);
252 EXPECT_EQ(std::get<std::string>(it->value_), FUNC_NAME.method);
253 ++it;
254 EXPECT_EQ(it->tag_, panda_file::LiteralTag::TAGVALUE);
255 ++it;
256 EXPECT_EQ(it->tag_, panda_file::LiteralTag::METHODAFFILIATE);
257 }
258
259 /**
260 * @tc.name: abc2program_hello_world_test_record_table
261 * @tc.desc: get program record_table.
262 * @tc.type: FUNC
263 * @tc.require: issueI96G2J
264 */
265 HWTEST_F(Abc2ProgramHelloWorldTest, abc2program_hello_world_test_record_table, TestSize.Level1)
266 {
267 panda_file::SourceLang expected_lang = panda_file::SourceLang::ECMASCRIPT;
268 std::vector<std::string> record_names;
269 for (const auto &it : prog_->record_table) {
270 EXPECT_TRUE(it.second.language == expected_lang);
271 EXPECT_TRUE(it.second.source_file == "");
272 EXPECT_TRUE(it.first == it.second.name);
273 record_names.emplace_back(it.first);
274 }
275 EXPECT_TRUE(Abc2ProgramTestUtils::ValidateRecordNames(record_names));
276 }
277
278 /**
279 * @tc.name: abc2program_hello_world_test_fields
280 * @tc.desc: get program record_table.
281 * @tc.type: FUNC
282 * @tc.require: issueI98NGN
283 */
284 HWTEST_F(Abc2ProgramHelloWorldTest, abc2program_hello_world_test_fields, TestSize.Level1)
285 {
286 for (const auto &it : prog_->record_table) {
287 if (it.first == "_ESModuleRecord" || it.first == "_ESScopeNamesRecord") {
288 const pandasm::Record &record = it.second;
289 const std::vector<pandasm::Field> &field_list = record.field_list;
290 EXPECT_EQ(field_list.size(), 1);
291 const pandasm::Field &field = field_list[0];
292 EXPECT_EQ(field.type.GetPandasmName(), "u32");
293 EXPECT_NE(field.name.find("HelloWorld.ts"), std::string::npos);
294 } else {
295 EXPECT_EQ(it.second.field_list.size(), 0);
296 }
297 }
298 }
299
300 /**
301 * @tc.name: abc2program_hello_world_test_strings
302 * @tc.desc: get existed string.
303 * @tc.type: FUNC
304 * @tc.require: issueI96G2J
305 */
306 HWTEST_F(Abc2ProgramHelloWorldTest, abc2program_hello_world_test_strings, TestSize.Level1)
307 {
308 bool string_matched = Abc2ProgramTestUtils::ValidateProgramStrings(prog_->strings);
309 EXPECT_TRUE(string_matched);
310 }
311
312 /**
313 * @tc.name: abc2program_hello_world_test_function_kind_access_flags
314 * @tc.desc: get existed function_kind.
315 * @tc.type: FUNC
316 * @tc.require: issueI9BPIO
317 */
318 HWTEST_F(Abc2ProgramHelloWorldTest, abc2program_hello_world_test_function_kind_access_flags, TestSize.Level1)
319 {
320 const pandasm::Function &function = *foo_function_;
321 panda_file::FunctionKind function_kind = function.function_kind;
322 EXPECT_TRUE(function_kind == panda_file::FunctionKind::FUNCTION);
323 uint32_t access_flags = function.metadata->GetAccessFlags();
324 EXPECT_TRUE((access_flags & ACC_STATIC) != 0);
325 EXPECT_TRUE(lit_function_->GetFunctionKind() == panda::panda_file::FunctionKind::NONE);
326 EXPECT_TRUE(foo_function_->GetFunctionKind() == panda::panda_file::FunctionKind::FUNCTION);
327 EXPECT_TRUE(add_function_->GetFunctionKind() == panda::panda_file::FunctionKind::NC_FUNCTION);
328 EXPECT_TRUE(generate_function_->GetFunctionKind() == panda::panda_file::FunctionKind::GENERATOR_FUNCTION);
329 EXPECT_TRUE(method_function_->GetFunctionKind() == panda::panda_file::FunctionKind::ASYNC_FUNCTION);
330 EXPECT_TRUE(async_generate_function_->GetFunctionKind() ==
331 panda::panda_file::FunctionKind::ASYNC_GENERATOR_FUNCTION);
332 EXPECT_TRUE(async_arrow_function_->GetFunctionKind() == panda::panda_file::FunctionKind::ASYNC_NC_FUNCTION);
333 }
334
335 /**
336 * @tc.name: abc2program_code_test_function_foo_part1
337 * @tc.desc: get program fuction foo.
338 * @tc.type: FUNC
339 * @tc.require: issueI989S6
340 */
341 HWTEST_F(Abc2ProgramHelloWorldTest, abc2program_code_test_function_foo_part1, TestSize.Level1)
342 {
343 const pandasm::Function &function = *foo_function_;
344 size_t regs_num = function.regs_num;
345 constexpr size_t NUM_OF_ARGS_FOR_FOO_METHOD = 3;
346 EXPECT_TRUE(function.params.size() == NUM_OF_ARGS_FOR_FOO_METHOD);
347 for (size_t i = 0; i < function.params.size(); ++i) {
348 EXPECT_TRUE(function.params[i].type.GetPandasmName() == ANY_TYPE_NAME);
349 }
350 EXPECT_TRUE(function.name == FUNC_NAME.foo);
351 EXPECT_TRUE(function.ins.size() == NUM_OF_CODE_TEST_UT_FOO_METHOD_INS);
352 // check ins[0]
353 const pandasm::Ins &ins0 = function.ins[0];
354 std::string pa_ins_str0 = ins0.ToString("", true, regs_num);
355 EXPECT_TRUE(pa_ins_str0 == "nop");
356 EXPECT_TRUE(ins0.label == "");
357 EXPECT_FALSE(ins0.set_label);
358 // check ins[3]
359 const pandasm::Ins &ins3 = function.ins[3];
360 std::string pa_ins_str3 = ins3.ToString("", true, regs_num);
361 EXPECT_TRUE(pa_ins_str3 == "label@3: ldai 0xb");
362 EXPECT_TRUE(ins3.label == "label@3");
363 EXPECT_TRUE(ins3.set_label);
364 // check ins[9]
365 const pandasm::Ins &ins9 = function.ins[9];
366 std::string pa_ins_str9 = ins9.ToString("", true, regs_num);
367 EXPECT_TRUE(pa_ins_str9 == "label@9: ldai 0x1");
368 EXPECT_TRUE(ins9.label == "label@9");
369 EXPECT_TRUE(ins9.set_label);
370 // check ins[11]
371 const pandasm::Ins &ins11 = function.ins[11];
372 std::string pa_ins_str11 = ins11.ToString("", true, regs_num);
373 EXPECT_TRUE(pa_ins_str11 == "label@11: jmp label@20");
374 EXPECT_TRUE(ins11.label == "label@11");
375 EXPECT_TRUE(ins11.set_label);
376 }
377
378 /**
379 * @tc.name: abc2program_code_test_function_foo_part2
380 * @tc.desc: get program fuction foo.
381 * @tc.type: FUNC
382 * @tc.require: issueI989S6
383 */
384 HWTEST_F(Abc2ProgramHelloWorldTest, abc2program_code_test_function_foo_part2, TestSize.Level1)
385 {
386 const pandasm::Function &function = *foo_function_;
387 size_t regs_num = function.regs_num;
388
389 // check ins[12]
390 const pandasm::Ins &ins12 = function.ins[12];
391 std::string pa_ins_str12 = ins12.ToString("", true, regs_num);
392 EXPECT_TRUE(pa_ins_str12 == "label@12: lda.str inner catch");
393 EXPECT_TRUE(ins12.label == "label@12");
394 EXPECT_TRUE(ins12.set_label);
395 // check ins[22]
396 const pandasm::Ins &ins22 = function.ins[22];
397 std::string pa_ins_str22 = ins22.ToString("", true, regs_num);
398 EXPECT_TRUE(pa_ins_str22 == "tryldglobalbyname 0x8, varA");
399 EXPECT_TRUE(ins22.label == "");
400 EXPECT_FALSE(ins22.set_label);
401 // check ins[26]
402 const pandasm::Ins &ins26 = function.ins[26];
403 std::string pa_ins_str26 = ins26.ToString("", true, regs_num);
404 EXPECT_TRUE(pa_ins_str26 == "jeqz label@29");
405 EXPECT_TRUE(ins26.label == "");
406 EXPECT_FALSE(ins26.set_label);
407 // check ins[29]
408 const pandasm::Ins &ins29 = function.ins[29];
409 std::string pa_ins_str29 = ins29.ToString("", true, regs_num);
410 EXPECT_TRUE(pa_ins_str29 == "label@29: tryldglobalbyname 0xa, x");
411 EXPECT_TRUE(ins29.label == "label@29");
412 EXPECT_TRUE(ins29.set_label);
413 // check ins[33]
414 const pandasm::Ins &ins33 = function.ins[33];
415 std::string pa_ins_str33 = ins33.ToString("", true, regs_num);
416 EXPECT_TRUE(pa_ins_str33 == "jeqz label@36");
417 EXPECT_TRUE(ins33.label == "");
418 EXPECT_FALSE(ins33.set_label);
419 // check ins[36]
420 const pandasm::Ins &ins36 = function.ins[36];
421 std::string pa_ins_str36 = ins36.ToString("", true, regs_num);
422 EXPECT_TRUE(pa_ins_str36 == "label@36: lda.str min");
423 EXPECT_TRUE(ins36.label == "label@36");
424 EXPECT_TRUE(ins36.set_label);
425 }
426
427 /**
428 * @tc.name: abc2program_code_test_function_foo_part3
429 * @tc.desc: get program fuction foo.
430 * @tc.type: FUNC
431 * @tc.require: issueI989S6
432 */
433 HWTEST_F(Abc2ProgramHelloWorldTest, abc2program_code_test_function_foo_part3, TestSize.Level1)
434 {
435 const pandasm::Function &function = *foo_function_;
436 size_t regs_num = function.regs_num;
437 // check ins[38]
438 const pandasm::Ins &ins38 = function.ins[38];
439 std::string pa_ins_str38 = ins38.ToString("", true, regs_num);
440 EXPECT_TRUE(pa_ins_str38 == "label@38: mov v1, v3");
441 EXPECT_TRUE(ins38.label == "label@38");
442 EXPECT_TRUE(ins38.set_label);
443 // check ins[44]
444 const pandasm::Ins &ins44 = function.ins[44];
445 std::string pa_ins_str44 = ins44.ToString("", true, regs_num);
446 EXPECT_TRUE(pa_ins_str44 == "sta v4");
447 EXPECT_TRUE(ins44.label == "");
448 EXPECT_FALSE(ins44.set_label);
449 // check ins[47]
450 const pandasm::Ins &ins47 = function.ins[47];
451 std::string pa_ins_str47 = ins47.ToString("", true, regs_num);
452 EXPECT_TRUE(pa_ins_str47 == "label@47: ldhole");
453 EXPECT_TRUE(ins47.label == "label@47");
454 EXPECT_TRUE(ins47.set_label);
455 // check ins[51]
456 const pandasm::Ins &ins51 = function.ins[51];
457 std::string pa_ins_str51 = ins51.ToString("", true, regs_num);
458 EXPECT_TRUE(pa_ins_str51 == "jmp label@53");
459 EXPECT_TRUE(ins51.label == "");
460 EXPECT_FALSE(ins51.set_label);
461 // check ins[52]
462 const pandasm::Ins &ins52 = function.ins[52];
463 std::string pa_ins_str52 = ins52.ToString("", true, regs_num);
464 EXPECT_TRUE(pa_ins_str52 == "label@52: sta v2");
465 EXPECT_TRUE(ins52.label == "label@52");
466 EXPECT_TRUE(ins52.set_label);
467 // check ins[53]
468 const pandasm::Ins &ins53 = function.ins[53];
469 std::string pa_ins_str53 = ins53.ToString("", true, regs_num);
470 EXPECT_TRUE(pa_ins_str53 == "label@53: ldundefined");
471 EXPECT_TRUE(ins53.label == "label@53");
472 EXPECT_TRUE(ins53.set_label);
473 // check ins[55]
474 const pandasm::Ins &ins55 = function.ins[55];
475 std::string pa_ins_str55 = ins55.ToString("", true, regs_num);
476 EXPECT_TRUE(pa_ins_str55 == "jeqz label@64");
477 EXPECT_TRUE(ins55.label == "");
478 EXPECT_FALSE(ins55.set_label);
479 // check ins[64]
480 const pandasm::Ins &ins64 = function.ins[64];
481 std::string pa_ins_str64 = ins64.ToString("", true, regs_num);
482 EXPECT_TRUE(pa_ins_str64 == "label@64: ldhole");
483 EXPECT_TRUE(ins64.label == "label@64");
484 EXPECT_TRUE(ins64.set_label);
485 }
486
487 /**
488 * @tc.name: abc2program_code_test_function_foo_part4
489 * @tc.desc: get program fuction foo.
490 * @tc.type: FUNC
491 * @tc.require: issueI989S6
492 */
493 HWTEST_F(Abc2ProgramHelloWorldTest, abc2program_code_test_function_foo_part4, TestSize.Level1)
494 {
495 const pandasm::Function &function = *foo_function_;
496 size_t regs_num = function.regs_num;
497 // check ins[68]
498 const pandasm::Ins &ins68 = function.ins[68];
499 std::string pa_ins_str68 = ins68.ToString("", true, regs_num);
500 EXPECT_TRUE(pa_ins_str68 == "jeqz label@71");
501 EXPECT_TRUE(ins68.label == "");
502 EXPECT_FALSE(ins68.set_label);
503 // check ins[71]
504 const pandasm::Ins &ins71 = function.ins[71];
505 std::string pa_ins_str71 = ins71.ToString("", true, regs_num);
506 EXPECT_TRUE(pa_ins_str71 == "label@71: ldundefined");
507 EXPECT_TRUE(ins71.label == "label@71");
508 EXPECT_TRUE(ins71.set_label);
509 // check ins[72]
510 const pandasm::Ins &ins72 = function.ins[72];
511 std::string pa_ins_str72 = ins72.ToString("", true, regs_num);
512 EXPECT_TRUE(pa_ins_str72 == "returnundefined");
513 EXPECT_TRUE(ins72.label == "");
514 EXPECT_FALSE(ins72.set_label);
515 // check catch blocks
516 constexpr uint32_t NUM_OF_CODE_TEST_UT_FOO_METHOD_CATCH_BLOCKS = 3;
517 EXPECT_TRUE(function.catch_blocks.size() == NUM_OF_CODE_TEST_UT_FOO_METHOD_CATCH_BLOCKS);
518 // catch_blocks[0]
519 const pandasm::Function::CatchBlock &pa_catch_block0 = function.catch_blocks[0];
520 EXPECT_TRUE(pa_catch_block0.try_begin_label == "label@9");
521 EXPECT_TRUE(pa_catch_block0.try_end_label == "label@11");
522 EXPECT_TRUE(pa_catch_block0.catch_begin_label == "label@12");
523 EXPECT_TRUE(pa_catch_block0.catch_end_label == "label@12");
524 // catch_blocks[1]
525 const pandasm::Function::CatchBlock &pa_catch_block1 = function.catch_blocks[1];
526 EXPECT_TRUE(pa_catch_block1.try_begin_label == "label@3");
527 EXPECT_TRUE(pa_catch_block1.try_end_label == "label@38");
528 EXPECT_TRUE(pa_catch_block1.catch_begin_label == "label@38");
529 EXPECT_TRUE(pa_catch_block1.catch_end_label == "label@38");
530 // catch_blocks[2]
531 const pandasm::Function::CatchBlock &pa_catch_block2 = function.catch_blocks[2];
532 EXPECT_TRUE(pa_catch_block2.try_begin_label == "label@3");
533 EXPECT_TRUE(pa_catch_block2.try_end_label == "label@47");
534 EXPECT_TRUE(pa_catch_block2.catch_begin_label == "label@52");
535 EXPECT_TRUE(pa_catch_block2.catch_end_label == "label@52");
536 }
537
538 /**
539 * @tc.name: abc2program_code_test_function_goo
540 * @tc.desc: get program fuction goo.
541 * @tc.type: FUNC
542 * @tc.require: issueI989S6
543 */
544 HWTEST_F(Abc2ProgramHelloWorldTest, abc2program_code_test_function_goo, TestSize.Level1)
545 {
546 const pandasm::Function &function = *goo_function_;
547 size_t regs_num = function.regs_num;
548 constexpr uint32_t NUM_OF_CODE_TEST_UT_GOO_METHOD_INS = 2;
549 EXPECT_TRUE(function.name == FUNC_NAME.goo);
550 EXPECT_TRUE(function.ins.size() == NUM_OF_CODE_TEST_UT_GOO_METHOD_INS);
551 // check ins[0]
552 constexpr uint32_t INDEX_OF_FUNC_LDUNDEFINED = 0;
553 const pandasm::Ins &ins0 = function.ins[INDEX_OF_FUNC_LDUNDEFINED];
554 std::string pa_ins_str0 = ins0.ToString("", true, regs_num);
555 EXPECT_TRUE(pa_ins_str0 == "ldundefined");
556 EXPECT_TRUE(ins0.label == "");
557 EXPECT_FALSE(ins0.set_label);
558 // check ins[1]
559 constexpr uint32_t INDEX_OF_FUNC_RETURNUNDEFINED = 1;
560 const pandasm::Ins &ins1 = function.ins[INDEX_OF_FUNC_RETURNUNDEFINED];
561 std::string pa_ins_str1 = ins1.ToString("", true, regs_num);
562 EXPECT_TRUE(pa_ins_str1 == "returnundefined");
563 EXPECT_TRUE(ins1.label == "");
564 EXPECT_FALSE(ins1.set_label);
565 // check catch blocks
566 EXPECT_TRUE(function.catch_blocks.size() == 0);
567 }
568
569 /**
570 * @tc.name: abc2program_code_imm_of_FLDAI
571 * @tc.desc: get and check immediate number of opcode FLDAI.
572 * @tc.type: FUNC
573 * @tc.require: issueI9E5ZM
574 */
575 HWTEST_F(Abc2ProgramHelloWorldTest, abc2program_code_imm_of_FLDAI, TestSize.Level1)
576 {
577 const pandasm::Function &hoo = *hoo_function_;
578 EXPECT_EQ(hoo.ins.size(), INS_SIZE_OF_FUNCTION_HOO);
579 pandasm::Ins ins_fldai;
580 for (auto &ins : hoo.ins) {
581 if (ins.opcode == pandasm::Opcode::FLDAI) {
582 ins_fldai = ins;
583 break;
584 }
585 }
586 EXPECT_TRUE(ins_fldai.opcode == pandasm::Opcode::FLDAI);
587 // check imm of FLDAI
588 EXPECT_EQ(ins_fldai.imms.size(), IMMS_SIZE_OF_OPCODE_FLDAI);
589 auto p = std::get_if<double>(&ins_fldai.imms[0]);
590 EXPECT_NE(p, nullptr);
591 EXPECT_EQ(*p, 1.23);
592 }
593
594 /**
595 * @tc.name: abc2program_module_literal_entry_test
596 * @tc.desc: get and check number of modules.
597 * @tc.type: FUNC
598 * @tc.require: issueI9E5ZM
599 */
600 HWTEST_F(Abc2ProgramHelloWorldTest, abc2program_module_literal_entry_test, TestSize.Level1)
601 {
602 auto &mod_table = prog_->literalarray_table;
603 EXPECT_EQ(mod_table.size(), SIZE_OF_LITERAL_ARRAY_TABLE);
604 auto &module_literals = mod_table.begin()->second.literals_;
605 EXPECT_EQ(module_literals.size(), TOTAL_NUM_OF_MODULE_LITERALS);
__anon43551a2d0102(size_t idx, panda::panda_file::LiteralTag expect_tag, uint32_t expect_value) 606 auto check_entry = [&module_literals](size_t idx, panda::panda_file::LiteralTag expect_tag, uint32_t expect_value) {
607 auto *literal = &(module_literals[idx]);
608 EXPECT_EQ(literal->tag_, expect_tag);
609 auto p = std::get_if<uint32_t>(&literal->value_);
610 EXPECT_TRUE(p != nullptr && *p == expect_value);
611 };
612 size_t idx = 0;
613 // check ModuleRequests
614 check_entry(idx, panda::panda_file::LiteralTag::INTEGER, NUM_OF_MODULE_REQUESTS);
615 // Each constant value '1' below stands for each entry. Each entry is also in the literal vector and shall be
616 // considered while calculating the position (index) of next entry.
617 // check RegularImportEntry
618 idx += NUM_OF_MODULE_REQUESTS + 1;
619 check_entry(idx, panda::panda_file::LiteralTag::INTEGER, NUM_OF_REGULAR_IMPORTS);
620 // check NamespaceImportEntry
621 idx += NUM_OF_REGULAR_IMPORTS * LITERAL_NUM_OF_REGULAR_IMPORT + 1;
622 check_entry(idx, panda::panda_file::LiteralTag::INTEGER, NUM_OF_NAMESPACE_IMPORTS);
623 // check LocalExportEntry
624 idx += NUM_OF_NAMESPACE_IMPORTS * LITERAL_NUM_OF_NAMESPACE_IMPORT + 1;
625 check_entry(idx, panda::panda_file::LiteralTag::INTEGER, NUM_OF_LOCAL_EXPORTS);
626 // check IndirectExportEntry
627 idx += NUM_OF_LOCAL_EXPORTS * LITERAL_NUM_OF_LOCAL_EXPORT + 1;
628 check_entry(idx, panda::panda_file::LiteralTag::INTEGER, NUM_OF_INDIRECT_EXPORTS);
629 // check StarExportEntry
630 idx += NUM_OF_INDIRECT_EXPORTS * LITERAL_NUM_OF_INDIRECT_EXPORT + 1;
631 check_entry(idx, panda::panda_file::LiteralTag::INTEGER, NUM_OF_STAR_EXPORTS);
632 // check idx
633 idx += NUM_OF_STAR_EXPORTS * LITERAL_NUM_OF_STAR_EXPORT + 1;
634 EXPECT_EQ(idx, TOTAL_NUM_OF_MODULE_LITERALS);
635 }
636
637 /**
638 * @tc.name: abc2program_hello_world_test_nested_literal_array
639 * @tc.desc: check contents of nested literal array
640 * @tc.type: FUNC
641 * @tc.require: issueIA7D9J
642 */
643 HWTEST_F(Abc2ProgramHelloWorldTest, abc2program_hello_world_test_nested_literal_array, TestSize.Level1)
644 {
645 auto &literal_array_table = prog_->literalarray_table;
646 EXPECT_EQ(literal_array_table.size(), SIZE_OF_LITERAL_ARRAY_TABLE);
647 /** current literal array table should be similar to below, each line indicates a literal array, which is
648 * formated as 'id_name : { literals }':
649 * _1 : { ... } // some other literal arrays
650 * _2 : { ... }
651 * _3 : { ... } // literal array that be nested, which id name is, for example, '_3'.
652 * _4 : { ..., literal_array:_3} // target literal array we are checking.
653 */
654 panda::pandasm::LiteralArray nested_literal_array;
655 for (auto &item : literal_array_table) {
656 for (auto &literal : item.second.literals_) {
657 if (literal.tag_ == panda_file::LiteralTag::LITERALARRAY) {
658 nested_literal_array = item.second;
659 break;
660 }
661 }
662 if (nested_literal_array.literals_.size() != 0) {
663 break;
664 }
665 }
666 EXPECT_EQ(nested_literal_array.literals_.size(), TOTAL_NUM_OF_NESTED_LITERALS);
667 auto it = nested_literal_array.literals_.begin();
668 EXPECT_EQ(it->tag_, panda_file::LiteralTag::TAGVALUE);
669 ++it;
670 EXPECT_EQ(it->tag_, panda_file::LiteralTag::STRING);
671 ++it;
672 EXPECT_EQ(it->tag_, panda_file::LiteralTag::TAGVALUE);
673 ++it;
674 EXPECT_EQ(it->tag_, panda_file::LiteralTag::METHOD);
675 EXPECT_EQ(std::get<std::string>(it->value_), FUNC_NAME.nested_literal_array);
676 ++it;
677 EXPECT_EQ(it->tag_, panda_file::LiteralTag::TAGVALUE);
678 ++it;
679 EXPECT_EQ(it->tag_, panda_file::LiteralTag::METHODAFFILIATE);
680 ++it;
681 EXPECT_EQ(it->tag_, panda_file::LiteralTag::TAGVALUE);
682 ++it;
683 EXPECT_EQ(it->tag_, panda_file::LiteralTag::INTEGER);
684 ++it;
685 EXPECT_EQ(it->tag_, panda_file::LiteralTag::TAGVALUE);
686 ++it;
687 EXPECT_EQ(it->tag_, panda_file::LiteralTag::LITERALARRAY);
688 EXPECT_NE(literal_array_table.find(std::get<std::string>(it->value_)), literal_array_table.end());
689 }
690
691 /*------------------------------------- Cases of release mode above -------------------------------------*/
692 /*-------------------------------------- Cases of debug mode below --------------------------------------*/
693
694 /**
695 * @tc.name: abc2program_hello_world_debug_test_dump
696 * @tc.desc: check dump result in debug mode.
697 * @tc.type: FUNC
698 * @tc.require: IADG92
699 */
700 HWTEST_F(Abc2ProgramHelloWorldDebugTest, abc2program_hello_world_debug_test_dump, TestSize.Level1)
701 {
702 driver_.Dump(HELLO_WORLD_DEBUG_DUMP_RESULT_FILE_NAME);
703 EXPECT_TRUE(Abc2ProgramTestUtils::ValidateDumpResult(HELLO_WORLD_DEBUG_DUMP_RESULT_FILE_NAME,
704 HELLO_WORLD_DEBUG_DUMP_EXPECTED_FILE_NAME));
705 if (REMOVE_DUMP_RESULT_FILES) {
706 Abc2ProgramTestUtils::RemoveDumpResultFile(HELLO_WORLD_DEBUG_DUMP_RESULT_FILE_NAME);
707 }
708 }
709
710 /**
711 * @tc.name: abc2program_hello_world_test_source_file
712 * @tc.desc: Verify the source file.
713 * @tc.type: FUNC
714 * @tc.require: issueI9CL5Z
715 */
716 HWTEST_F(Abc2ProgramHelloWorldDebugTest, abc2program_hello_world_test_source_file, TestSize.Level1)
717 {
718 const pandasm::Function &function = *foo_function_;
719 std::string source_file = function.source_file;
720 EXPECT_TRUE(source_file.find("HelloWorld.ts") != std::string::npos);
721 }
722
723 /**
724 * @tc.name: abc2program_hello_world_test_source_code
725 * @tc.desc: Verify the source code
726 * @tc.type: FUNC
727 * @tc.require: issueI9DT0V
728 */
729 HWTEST_F(Abc2ProgramHelloWorldDebugTest, abc2program_hello_world_test_source_code, TestSize.Level1)
730 {
731 const pandasm::Function &function = *main_function_;
732 std::string source_code = function.source_code;
733 EXPECT_TRUE(source_code.find("not supported") != std::string::npos);
734 }
735
736 /**
737 * @tc.name: abc2program_hello_world_test_local_variable
738 * @tc.desc: get local variables
739 * @tc.type: FUNC
740 * @tc.require: issueI9DT0V
741 */
742 HWTEST_F(Abc2ProgramHelloWorldDebugTest, abc2program_hello_world_test_local_variable, TestSize.Level1)
743 {
744 const pandasm::Function &function = *foo_function_;
745 EXPECT_FALSE(function.local_variable_debug.empty());
746 EXPECT_TRUE(function.local_variable_debug[0].name.find("4funcObj") != std::string::npos);
747 EXPECT_TRUE(function.local_variable_debug[0].signature.find("any") != std::string::npos);
748 EXPECT_TRUE(function.local_variable_debug[0].signature_type.find("any") != std::string::npos);
749 EXPECT_TRUE(function.local_variable_debug[0].reg == 0);
750 EXPECT_TRUE(function.local_variable_debug[0].start == 3);
751 EXPECT_TRUE(function.local_variable_debug[0].length == 74);
752 }
753
754 /**
755 * @tc.name: abc2program_hello_world_test_ins_debug
756 * @tc.desc: get ins_debug line number and column number
757 * @tc.type: FUNC
758 * @tc.require: issueI9DT0V
759 */
760 HWTEST_F(Abc2ProgramHelloWorldDebugTest, abc2program_hello_world_test_ins_debug, TestSize.Level1)
761 {
762 const pandasm::Function &function = *foo_function_;
763 size_t regs_num = function.regs_num;
764 EXPECT_FALSE(function.local_variable_debug.empty());
765
766 const pandasm::Ins &ins0 = function.ins[0];
767 std::string pa_ins_str0 = ins0.ToString("", true, regs_num);
768 EXPECT_TRUE(pa_ins_str0 == "mov v0, a0");
769 EXPECT_TRUE(ins0.ins_debug.line_number == -1);
770 EXPECT_TRUE(ins0.ins_debug.column_number == -1);
771
772 const pandasm::Ins &ins3 = function.ins[3];
773 std::string pa_ins_str3 = ins3.ToString("", true, regs_num);
774 EXPECT_TRUE(pa_ins_str3 == "ldundefined");
775 EXPECT_TRUE(ins3.ins_debug.line_number == 40);
776 EXPECT_TRUE(ins3.ins_debug.column_number == 2);
777
778 const pandasm::Ins &ins5 = function.ins[5];
779 std::string pa_ins_str5 = ins5.ToString("", true, regs_num);
780 EXPECT_TRUE(pa_ins_str5 == "label@5: ldai 0xb");
781 EXPECT_TRUE(ins5.ins_debug.line_number == 41);
782 EXPECT_TRUE(ins5.ins_debug.column_number == 11);
783 }
784 }; // panda::abc2program