• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file EXPECT 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 <gtest/gtest.h>
17 #include <iostream>
18 
19 #include "assembly-emitter.h"
20 #include "assembly-parser.h"
21 #include "class_data_accessor-inl.h"
22 #include "code_data_accessor-inl.h"
23 #include "debug_data_accessor-inl.h"
24 #include "field_data_accessor-inl.h"
25 #include "file_items.h"
26 #include "lexer.h"
27 #include "method_data_accessor-inl.h"
28 #include "param_annotations_data_accessor.h"
29 #include "proto_data_accessor-inl.h"
30 #include "utils/span.h"
31 #include "utils/leb128.h"
32 #include "utils/utf.h"
33 #include "bytecode_instruction-inl.h"
34 
35 using namespace testing::ext;
36 
37 namespace panda::pandasm {
38 class AssemblyEmitterTest : public testing::Test {
39 };
40 
GetTypeDescriptor(const std::string & name,std::string * storage)41 static const uint8_t *GetTypeDescriptor(const std::string &name, std::string *storage)
42 {
43     *storage = "L" + name + ";";
44     std::replace(storage->begin(), storage->end(), '.', '/');
45     return utf::CStringAsMutf8(storage->c_str());
46 }
47 
GetSpecialOpcode(uint32_t pc_inc,int32_t line_inc)48 uint8_t GetSpecialOpcode(uint32_t pc_inc, int32_t line_inc)
49 {
50     return static_cast<uint8_t>(line_inc - panda_file::LineNumberProgramItem::LINE_BASE) +
51            static_cast<uint8_t>(pc_inc * panda_file::LineNumberProgramItem::LINE_RANGE) +
52            panda_file::LineNumberProgramItem::OPCODE_BASE;
53 }
54 
55 /**
56  * @tc.name: assembly_emitter_test_001
57  * @tc.desc: Verify the EnumerateMethods function.
58  * @tc.type: FUNC
59  * @tc.require: issueNumber
60  */
61 HWTEST_F(AssemblyEmitterTest, assembly_emitter_test_001, TestSize.Level1)
62 {
63     Parser p;
64     auto source = R"(
65         .record R {}
66         .function void R.foo(R a0) <ctor> {}
67     )";
68 
69     auto res = p.Parse(source);
70     EXPECT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
71 
72     auto pf = AsmEmitter::Emit(res.Value());
73     EXPECT_NE(pf, nullptr);
74 
75     std::string descriptor;
76 
77     auto class_id = pf->GetClassId(GetTypeDescriptor("R", &descriptor));
78     EXPECT_TRUE(class_id.IsValid());
79 
80     panda_file::ClassDataAccessor cda(*pf, class_id);
81 
__anon9d5bb8020102(panda_file::MethodDataAccessor &mda) 82     cda.EnumerateMethods([&](panda_file::MethodDataAccessor &mda) {
83         auto *name = utf::Mutf8AsCString(pf->GetStringData(mda.GetNameId()).data);
84         EXPECT_STREQ(name, ".ctor");
85     });
86 }
87 
88 /**
89  * @tc.name: assembly_emitter_test_002
90  * @tc.desc: Verify the EnumerateMethods function.
91  * @tc.type: FUNC
92  * @tc.require: issueNumber
93  */
94 HWTEST_F(AssemblyEmitterTest, assembly_emitter_test_002, TestSize.Level1)
95 {
96     Parser p;
97 
98     auto source = R"(            # 1
99         .record R {              # 2
100             i32 sf <static>      # 3
101             i8  if               # 4
102         }                        # 5
103                                  # 6
104         .function void main() {  # 7
105             return               # 8
106         }                        # 9
107     )";
108 
109     std::string source_filename = "source.pa";
110     auto res = p.Parse(source, source_filename);
111     EXPECT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
112 
113     auto pf = AsmEmitter::Emit(res.Value());
114     EXPECT_NE(pf, nullptr);
115 
116     {
117         std::string descriptor;
118         auto class_id = pf->GetClassId(GetTypeDescriptor("_GLOBAL", &descriptor));
119         EXPECT_TRUE(class_id.IsValid());
120         EXPECT_FALSE(pf->IsExternal(class_id));
121 
122         panda_file::ClassDataAccessor cda(*pf, class_id);
123         EXPECT_EQ(cda.GetSuperClassId().GetOffset(), 0U);
124         EXPECT_EQ(cda.GetAccessFlags(), ACC_PUBLIC);
125         EXPECT_EQ(cda.GetFieldsNumber(), 0U);
126         EXPECT_EQ(cda.GetMethodsNumber(), 1U);
127         EXPECT_EQ(cda.GetIfacesNumber(), 0U);
128 
129         EXPECT_FALSE(cda.GetSourceFileId().has_value());
130 
__anon9d5bb8020202(panda_file::File::EntityId) 131         cda.EnumerateAnnotations([](panda_file::File::EntityId) { EXPECT_TRUE(false); });
132 
__anon9d5bb8020302(panda_file::FieldDataAccessor &) 133         cda.EnumerateFields([](panda_file::FieldDataAccessor &) { EXPECT_TRUE(false); });
134 
__anon9d5bb8020402(panda_file::MethodDataAccessor &mda) 135         cda.EnumerateMethods([&](panda_file::MethodDataAccessor &mda) {
136             EXPECT_FALSE(mda.IsExternal());
137             EXPECT_EQ(mda.GetClassId(), class_id);
138             EXPECT_EQ(utf::CompareMUtf8ToMUtf8(pf->GetStringData(mda.GetNameId()).data, utf::CStringAsMutf8("main")),
139                       0);
140 
141             panda_file::ProtoDataAccessor pda(*pf, mda.GetProtoId());
142             EXPECT_EQ(pda.GetNumArgs(), 0U);
143             EXPECT_EQ(pda.GetReturnType().GetId(), panda_file::Type::TypeId::VOID);
144 
145             EXPECT_EQ(mda.GetAccessFlags(), ACC_STATIC);
146             EXPECT_TRUE(mda.GetCodeId().has_value());
147 
148             panda_file::CodeDataAccessor cdacc(*pf, mda.GetCodeId().value());
149             EXPECT_EQ(cdacc.GetNumVregs(), 0U);
150             EXPECT_EQ(cdacc.GetNumArgs(), 0U);
151             EXPECT_EQ(cdacc.GetCodeSize(), 1U);
152             EXPECT_EQ(cdacc.GetTriesSize(), 0U);
153 
154             EXPECT_FALSE(mda.GetRuntimeParamAnnotationId().has_value());
155             EXPECT_FALSE(mda.GetParamAnnotationId().has_value());
156             EXPECT_TRUE(mda.GetDebugInfoId().has_value());
157 
158             panda_file::DebugInfoDataAccessor dda(*pf, mda.GetDebugInfoId().value());
159             EXPECT_EQ(dda.GetLineStart(), 8U);
160             EXPECT_EQ(dda.GetNumParams(), 0U);
161 
162             mda.EnumerateAnnotations([](panda_file::File::EntityId) {});
163         });
164     }
165     {
166         std::string descriptor;
167         auto class_id = pf->GetClassId(GetTypeDescriptor("R", &descriptor));
168         EXPECT_TRUE(class_id.IsValid());
169         EXPECT_FALSE(pf->IsExternal(class_id));
170 
171         panda_file::ClassDataAccessor cda(*pf, class_id);
172         EXPECT_EQ(cda.GetSuperClassId().GetOffset(), 0U);
173         EXPECT_EQ(cda.GetAccessFlags(), 0U);
174         EXPECT_EQ(cda.GetFieldsNumber(), 2U);
175         EXPECT_EQ(cda.GetMethodsNumber(), 0U);
176         EXPECT_EQ(cda.GetIfacesNumber(), 0U);
177 
178         // We emit SET_FILE in debuginfo
179         EXPECT_TRUE(cda.GetSourceFileId().has_value());
180 
181         EXPECT_EQ(std::string(reinterpret_cast<const char *>(pf->GetStringData(cda.GetSourceFileId().value()).data)),
182                   source_filename);
183 
184         struct FieldData {
185             std::string name;
186             panda_file::Type::TypeId type_id;
187             uint32_t access_flags;
188         };
189 
190         std::vector<FieldData> fields {{"sf", panda_file::Type::TypeId::I32, ACC_STATIC},
191                                        {"if", panda_file::Type::TypeId::I8, 0}};
192 
193         size_t i = 0;
__anon9d5bb8020602(panda_file::FieldDataAccessor &fda) 194         cda.EnumerateFields([&](panda_file::FieldDataAccessor &fda) {
195             EXPECT_FALSE(fda.IsExternal());
196             EXPECT_EQ(fda.GetClassId(), class_id);
197             EXPECT_EQ(utf::CompareMUtf8ToMUtf8(pf->GetStringData(fda.GetNameId()).data,
198                                                utf::CStringAsMutf8(fields[i].name.c_str())),
199                       0);
200 
201             EXPECT_EQ(fda.GetType(), panda_file::Type(fields[i].type_id).GetFieldEncoding());
202             EXPECT_EQ(fda.GetAccessFlags(), fields[i].access_flags);
203 
204             fda.EnumerateAnnotations([](panda_file::File::EntityId) { EXPECT_TRUE(false); });
205 
206             ++i;
207         });
208 
__anon9d5bb8020802(panda_file::MethodDataAccessor &) 209         cda.EnumerateMethods([&](panda_file::MethodDataAccessor &) { EXPECT_TRUE(false); });
210     }
211 }
212 
213 /**
214  * @tc.name: assembly_emitter_test_003
215  * @tc.desc: Verify the EnumerateMethods function.
216  * @tc.type: FUNC
217  * @tc.require: issueNumber
218  */
219 HWTEST_F(AssemblyEmitterTest, assembly_emitter_test_003, TestSize.Level1)
220 {
221     Parser p;
222 
223     auto source = R"(
224         .function void main() {
225             ldai 0      # line 3, pc 0
226                         # line 4
227                         # line 5
228                         # line 6
229                         # line 7
230                         # line 8
231                         # line 9
232                         # line 10
233                         # line 11
234                         # line 12
235                         # line 13
236                         # line 14
237             ldai 1      # line 15, pc 9
238             return # line 16, pc 18
239         }
240     )";
241 
242     std::string source_filename = "source.pa";
243     auto res = p.Parse(source, source_filename);
244     EXPECT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
245 
246     auto pf = AsmEmitter::Emit(res.Value());
247     EXPECT_NE(pf, nullptr);
248 
249     std::string descriptor;
250     auto class_id = pf->GetClassId(GetTypeDescriptor("_GLOBAL", &descriptor));
251     EXPECT_TRUE(class_id.IsValid());
252 
253     panda_file::ClassDataAccessor cda(*pf, class_id);
254 
__anon9d5bb8020902(panda_file::MethodDataAccessor &mda) 255     cda.EnumerateMethods([&](panda_file::MethodDataAccessor &mda) {
256         panda_file::CodeDataAccessor cdacc(*pf, mda.GetCodeId().value());
257         EXPECT_TRUE(mda.GetDebugInfoId().has_value());
258 
259         panda_file::DebugInfoDataAccessor dda(*pf, mda.GetDebugInfoId().value());
260         EXPECT_EQ(dda.GetLineStart(), 3U);
261         EXPECT_EQ(dda.GetNumParams(), 0U);
262 
263         dda.GetLineNumberProgram();
264         Span<const uint8_t> constant_pool = dda.GetConstantPool();
265 
266         std::vector<uint8_t> opcodes {static_cast<uint8_t>(panda_file::LineNumberProgramItem::Opcode::SET_FILE),
267                                       static_cast<uint8_t>(panda_file::LineNumberProgramItem::Opcode::ADVANCE_PC),
268                                       static_cast<uint8_t>(panda_file::LineNumberProgramItem::Opcode::ADVANCE_LINE),
269                                       GetSpecialOpcode(0, 0),
270                                       GetSpecialOpcode(9, 1),
271                                       static_cast<uint8_t>(panda_file::LineNumberProgramItem::Opcode::END_SEQUENCE)};
272 
273         size_t size {};
274         bool is_full {};
275         size_t constant_pool_offset = 0;
276 
277         uint32_t offset {};
278 
279         std::tie(offset, size, is_full) = leb128::DecodeUnsigned<uint32_t>(&constant_pool[constant_pool_offset]);
280         constant_pool_offset += size;
281         EXPECT_TRUE(is_full);
282         EXPECT_EQ(
283             std::string(reinterpret_cast<const char *>(pf->GetStringData(panda_file::File::EntityId(offset)).data)),
284             source_filename);
285 
286         uint32_t pc_inc;
287         std::tie(pc_inc, size, is_full) = leb128::DecodeUnsigned<uint32_t>(&constant_pool[constant_pool_offset]);
288         constant_pool_offset += size;
289         EXPECT_TRUE(is_full);
290         EXPECT_EQ(pc_inc, 0U);
291 
292         int32_t line_inc;
293         std::tie(line_inc, size, is_full) = leb128::DecodeSigned<int32_t>(&constant_pool[constant_pool_offset]);
294         constant_pool_offset += size;
295         EXPECT_TRUE(is_full);
296         EXPECT_EQ(line_inc, 5);
297 
298         EXPECT_EQ(constant_pool_offset + 1, constant_pool.size());
299     });
300 }
301 
302 /**
303  * @tc.name: assembly_emitter_test_004
304  * @tc.desc: Verify the EnumerateMethods function.
305  * @tc.type: FUNC
306  * @tc.require: issueNumber
307  */
308 HWTEST_F(AssemblyEmitterTest, assembly_emitter_test_004, TestSize.Level1)
309 {
310     Parser p;
311 
312     auto source = R"(
313         .record Exception1 {}
314         .record Exception2 {}
315 
316         .function any myFunction(any a0, any a1, any a2) <static> {
317             mov v0, a0
318             mov v1, a1
319             mov v2, a2
320             ldundefined
321             sta v4
322         try_begin:
323             jmp handler_begin1
324         handler_begin1:
325             ldhole
326             sta v5
327             jmp handler_end2
328         handler_begin2:
329             sta v5
330         handler_end2:
331             lda v4
332             sta v6
333             ldundefined
334             eq 0x0, v6
335             jeqz jump_label_4
336             sta v4
337         jump_label_4:
338             lda v5
339             sta v6
340             ldhole
341             sta v7
342             lda v6
343             noteq 0x1, v7
344             jeqz jump_label_5
345             lda v6
346             throw
347         jump_label_5:
348             ldundefined
349             returnundefined
350 
351         .catchall try_begin, try_begin, handler_begin1
352         .catchall try_begin, handler_begin1, handler_begin2, handler_end2
353         }
354     )";
355 
356     auto res = p.Parse(source);
357     EXPECT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
358     auto pf = AsmEmitter::Emit(res.Value());
359     EXPECT_NE(pf, nullptr);
360 
361     std::string descriptor;
362 
363     auto class_id = pf->GetClassId(GetTypeDescriptor("_GLOBAL", &descriptor));
364     EXPECT_TRUE(class_id.IsValid());
365 
366     panda_file::ClassDataAccessor cda(*pf, class_id);
367 
368     size_t i = 0;
__anon9d5bb8020a02(panda_file::MethodDataAccessor &mda) 369     cda.EnumerateMethods([&](panda_file::MethodDataAccessor &mda) {
370         panda_file::CodeDataAccessor cdacc(*pf, mda.GetCodeId().value());
371         // The NumVregs of arguments is 8U
372         // The NumArgs of arguments is 3U
373         // The tries size is 2U
374         EXPECT_EQ(cdacc.GetNumVregs(), 8U);
375         EXPECT_EQ(cdacc.GetNumArgs(), 3U);
376         EXPECT_EQ(cdacc.GetTriesSize(), 2U);
377 
378         cdacc.EnumerateTryBlocks([&](panda_file::CodeDataAccessor::TryBlock &try_block) {
379             // Try start Pc is 9U
380             // Catches number is 1U
381             EXPECT_EQ(try_block.GetStartPc(), 9U);
382             EXPECT_EQ(try_block.GetNumCatches(), 1U);
383 
384             struct CatchInfo {
385                 panda_file::File::EntityId type_id;
386                 uint32_t handler_pc;
387             };
388             // Exception1 class ID is 11.
389             // Exception2 class ID is 16.
390             // The file entity ID is 6 * 9.
391             std::vector<CatchInfo> catch_infos {{pf->GetClassId(GetTypeDescriptor("Exception1", &descriptor)), 11},
392                                                 {pf->GetClassId(GetTypeDescriptor("Exception2", &descriptor)), 16},
393                                                 {panda_file::File::EntityId(), 6 * 9}};
394 
395             try_block.EnumerateCatchBlocks([&](panda_file::CodeDataAccessor::CatchBlock &catch_block) {
396                 EXPECT_EQ(catch_block.GetHandlerPc(), catch_infos[i].handler_pc);
397                 ++i;
398 
399                 return true;
400             });
401 
402             return true;
403         });
404     });
405 }
406 
407 /**
408  * @tc.name: assembly_emitter_test_005
409  * @tc.desc: Verify the AsmEmitter::GetLastError() function.
410  * @tc.type: FUNC
411  * @tc.require: issueNumber
412  */
413 HWTEST_F(AssemblyEmitterTest, assembly_emitter_test_005, TestSize.Level1)
414 {
415     {
416         Parser p;
417         auto source = R"(
418             .record A {
419                 B b
420             }
421         )";
422 
423         auto res = p.Parse(source);
424         EXPECT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
425 
426         auto pf = AsmEmitter::Emit(res.Value());
427         EXPECT_EQ(pf, nullptr);
428         EXPECT_EQ(AsmEmitter::GetLastError(), "Field A.b has undefined type");
429     }
430 
431     {
432         Parser p;
433         auto source = R"(
434             .function void A.b() {}
435         )";
436 
437         auto res = p.Parse(source);
438         EXPECT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
439 
440         auto pf = AsmEmitter::Emit(res.Value());
441         EXPECT_EQ(pf, nullptr);
442         EXPECT_EQ(AsmEmitter::GetLastError(), "Function A.b is bound to undefined record A");
443     }
444 
445     {
446         Parser p;
447         auto source = R"(
448             .function A b() {}
449         )";
450 
451         auto res = p.Parse(source);
452         EXPECT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
453 
454         auto pf = AsmEmitter::Emit(res.Value());
455         EXPECT_EQ(pf, nullptr);
456         EXPECT_EQ(AsmEmitter::GetLastError(), "Function b has undefined return type");
457     }
458 
459     {
460         Parser p;
461         auto source = R"(
462             .function void a(b a0) {}
463         )";
464 
465         auto res = p.Parse(source);
466         EXPECT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
467 
468         auto pf = AsmEmitter::Emit(res.Value());
469         EXPECT_EQ(pf, nullptr);
470         EXPECT_EQ(AsmEmitter::GetLastError(), "Argument 0 of function a has undefined type");
471     }
472 
473     {
474         Parser p;
475         auto source = R"(
476             .record A <external>
477             .function void A.x() {}
478         )";
479 
480         auto res = p.Parse(source);
481         EXPECT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
482 
483         auto pf = AsmEmitter::Emit(res.Value());
484         EXPECT_EQ(pf, nullptr);
485         EXPECT_EQ(AsmEmitter::GetLastError(), "Non-external function A.x is bound to external record");
486     }
487 }
488 
489 /**
490  * @tc.name: assembly_emitter_test_006
491  * @tc.desc: Verify the EnumerateMethods function.
492  * @tc.type: FUNC
493  * @tc.require: issueNumber
494  */
495 HWTEST_F(AssemblyEmitterTest, assembly_emitter_test_006, TestSize.Level1)
496 {
497     Parser p;
498     auto source = R"(
499         .function void foo() {}
500     )";
501 
502     auto res = p.Parse(source);
503     EXPECT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
504 
505     auto pf = AsmEmitter::Emit(res.Value());
506     EXPECT_NE(pf, nullptr);
507 
508     std::string descriptor;
509 
510     auto class_id = pf->GetClassId(GetTypeDescriptor("_GLOBAL", &descriptor));
511     EXPECT_TRUE(class_id.IsValid());
512 
513     panda_file::ClassDataAccessor cda(*pf, class_id);
514 
515     EXPECT_FALSE(cda.GetSourceLang());
516 
__anon9d5bb8020d02(panda_file::MethodDataAccessor &mda) 517     cda.EnumerateMethods([&](panda_file::MethodDataAccessor &mda) { EXPECT_FALSE(mda.GetSourceLang()); });
518 }
519 
520 /**
521  * @tc.name: assembly_emitter_test_007
522  * @tc.desc: Verify the EnumerateMethods function.
523  * @tc.type: FUNC
524  * @tc.require: issueNumber
525  */
526 HWTEST_F(AssemblyEmitterTest, assembly_emitter_test_007, TestSize.Level1)
527 {
528     {
529         Parser p;
530         auto source = R"(
531             .record R {}
532             .function void R.foo(R a0) <ctor> {}
533         )";
534 
535         auto res = p.Parse(source);
536         EXPECT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
537 
538         auto pf = AsmEmitter::Emit(res.Value());
539         EXPECT_NE(pf, nullptr);
540 
541         std::string descriptor;
542 
543         auto class_id = pf->GetClassId(GetTypeDescriptor("R", &descriptor));
544         EXPECT_TRUE(class_id.IsValid());
545 
546         panda_file::ClassDataAccessor cda(*pf, class_id);
547 
__anon9d5bb8020e02(panda_file::MethodDataAccessor &mda) 548         cda.EnumerateMethods([&](panda_file::MethodDataAccessor &mda) {
549             auto *name = utf::Mutf8AsCString(pf->GetStringData(mda.GetNameId()).data);
550             EXPECT_STREQ(name, ".ctor");
551         });
552     }
553 
554     {
555         Parser p;
556         auto source = R"(
557             .record R {}
558             .function void R.foo(R a0) <cctor> {}
559         )";
560 
561         auto res = p.Parse(source);
562         EXPECT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
563 
564         auto pf = AsmEmitter::Emit(res.Value());
565         EXPECT_NE(pf, nullptr);
566 
567         std::string descriptor;
568 
569         auto class_id = pf->GetClassId(GetTypeDescriptor("R", &descriptor));
570         EXPECT_TRUE(class_id.IsValid());
571 
572         panda_file::ClassDataAccessor cda(*pf, class_id);
573 
__anon9d5bb8020f02(panda_file::MethodDataAccessor &mda) 574         cda.EnumerateMethods([&](panda_file::MethodDataAccessor &mda) {
575             auto *name = utf::Mutf8AsCString(pf->GetStringData(mda.GetNameId()).data);
576             EXPECT_STREQ(name, ".cctor");
577         });
578     }
579 }
580 
581 /**
582  * @tc.name: assembly_emitter_test_008
583  * @tc.desc: Verify the EnumerateFields function.
584  * @tc.type: FUNC
585  * @tc.require: issueNumber
586  */
587 HWTEST_F(AssemblyEmitterTest, assembly_emitter_test_008, TestSize.Level1)
588 {
589     Parser p;
590 
591     auto source = R"(
592         .record panda.String <external>
593 
594         .record R {
595             u1 f_u1 <value=1>
596             i8 f_i8 <value=2>
597             u8 f_u8 <value=128>
598             i16 f_i16 <value=256>
599             u16 f_u16 <value=32768>
600             i32 f_i32 <value=65536>
601             u32 f_u32 <value=2147483648>
602             i64 f_i64 <value=4294967296>
603             u64 f_u64 <value=9223372036854775808>
604             f32 f_f32 <value=1.0>
605             f64 f_f64 <value=2.0>
606             panda.String f_str <value="str">
607         }
608     )";
609 
610     struct FieldData {
611         std::string name;
612         panda_file::Type::TypeId type_id;
613         std::variant<int32_t, uint32_t, int64_t, uint64_t, float, double, std::string> value;
614     };
615 
616     uint32_t f_u1 = 1;
617     int32_t f_i8 = 2;
618     uint32_t f_u8 = 128;
619     int32_t f_i16 = 256;
620     uint32_t f_u16 = 32768;
621     int32_t f_i32 = 65536;
622     uint32_t f_u32 = 2147483648;
623     int64_t f_i64 = 4294967296;
624     uint64_t f_u64 = 9223372036854775808ULL;
625     float f_f32 = 1.0;
626     double f_f64 = 2.0;
627 
628     std::vector<FieldData> data {
629         {"f_u1", panda_file::Type::TypeId::U1, f_u1}, {"f_i8", panda_file::Type::TypeId::I8, f_i8},
630         {"f_u8", panda_file::Type::TypeId::U8, f_u8}, {"f_i16", panda_file::Type::TypeId::I16, f_i16},
631         {"f_u16", panda_file::Type::TypeId::U16, f_u16}, {"f_i32", panda_file::Type::TypeId::I32, f_i32},
632         {"f_u32", panda_file::Type::TypeId::U32, f_u32}, {"f_i64", panda_file::Type::TypeId::I64, f_i64},
633         {"f_u64", panda_file::Type::TypeId::U64, f_u64}, {"f_f32", panda_file::Type::TypeId::F32, f_f32},
634         {"f_f64", panda_file::Type::TypeId::F64, f_f64}, {"f_str", panda_file::Type::TypeId::REFERENCE, "str"}};
635 
636     auto res = p.Parse(source);
637     EXPECT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
638 
639     auto pf = AsmEmitter::Emit(res.Value());
640     EXPECT_NE(pf, nullptr);
641 
642     std::string descriptor;
643     auto class_id = pf->GetClassId(GetTypeDescriptor("R", &descriptor));
644     EXPECT_TRUE(class_id.IsValid());
645     EXPECT_FALSE(pf->IsExternal(class_id));
646 
647     panda_file::ClassDataAccessor cda(*pf, class_id);
648     EXPECT_EQ(cda.GetFieldsNumber(), data.size());
649 
650     auto panda_string_id = pf->GetClassId(GetTypeDescriptor("panda.String", &descriptor));
651 
652     size_t idx = 0;
__anon9d5bb8021002(panda_file::FieldDataAccessor &fda) 653     cda.EnumerateFields([&](panda_file::FieldDataAccessor &fda) {
654         const FieldData &field_data = data[idx];
655 
656         EXPECT_EQ(utf::CompareMUtf8ToMUtf8(pf->GetStringData(fda.GetNameId()).data,
657                                            utf::CStringAsMutf8(field_data.name.c_str())),
658                   0);
659 
660         panda_file::Type type(field_data.type_id);
661         uint32_t type_value;
662         if (type.IsReference()) {
663             type_value = panda_string_id.GetOffset();
664         } else {
665             type_value = type.GetFieldEncoding();
666         }
667 
668         switch (field_data.type_id) {
669             case panda_file::Type::TypeId::U1: {
670                 auto result = fda.GetValue<uint8_t>();
671                 EXPECT_TRUE(result);
672                 EXPECT_EQ(result.value(), std::get<uint32_t>(field_data.value));
673                 break;
674             }
675             case panda_file::Type::TypeId::I8: {
676                 auto result = fda.GetValue<int8_t>();
677                 EXPECT_TRUE(result);
678                 EXPECT_EQ(result.value(), std::get<int32_t>(field_data.value));
679                 break;
680             }
681             case panda_file::Type::TypeId::U8: {
682                 auto result = fda.GetValue<uint8_t>();
683                 EXPECT_TRUE(result);
684                 EXPECT_EQ(result.value(), std::get<uint32_t>(field_data.value));
685                 break;
686             }
687             case panda_file::Type::TypeId::I16: {
688                 auto result = fda.GetValue<int16_t>();
689                 EXPECT_TRUE(result);
690                 EXPECT_EQ(result.value(), std::get<int32_t>(field_data.value));
691                 break;
692             }
693             case panda_file::Type::TypeId::U16: {
694                 auto result = fda.GetValue<uint16_t>();
695                 EXPECT_TRUE(result);
696                 EXPECT_EQ(result.value(), std::get<uint32_t>(field_data.value));
697                 break;
698             }
699             case panda_file::Type::TypeId::I32: {
700                 auto result = fda.GetValue<int32_t>();
701                 EXPECT_TRUE(result);
702                 EXPECT_EQ(result.value(), std::get<int32_t>(field_data.value));
703                 break;
704             }
705             case panda_file::Type::TypeId::U32: {
706                 auto result = fda.GetValue<uint32_t>();
707                 EXPECT_TRUE(result);
708                 EXPECT_EQ(result.value(), std::get<uint32_t>(field_data.value));
709                 break;
710             }
711             case panda_file::Type::TypeId::I64: {
712                 auto result = fda.GetValue<int64_t>();
713                 EXPECT_TRUE(result);
714                 EXPECT_EQ(result.value(), std::get<int64_t>(field_data.value));
715                 break;
716             }
717             case panda_file::Type::TypeId::U64: {
718                 auto result = fda.GetValue<uint64_t>();
719                 EXPECT_TRUE(result);
720                 EXPECT_EQ(result.value(), std::get<uint64_t>(field_data.value));
721                 break;
722             }
723             case panda_file::Type::TypeId::F32: {
724                 auto result = fda.GetValue<float>();
725                 EXPECT_TRUE(result);
726                 EXPECT_EQ(result.value(), std::get<float>(field_data.value));
727                 break;
728             }
729             case panda_file::Type::TypeId::F64: {
730                 auto result = fda.GetValue<double>();
731                 EXPECT_TRUE(result);
732                 EXPECT_EQ(result.value(), std::get<double>(field_data.value));
733                 break;
734             }
735             case panda_file::Type::TypeId::REFERENCE: {
736                 auto result = fda.GetValue<uint32_t>();
737                 EXPECT_TRUE(result);
738 
739                 panda_file::File::EntityId string_id(result.value());
740                 auto val = std::get<std::string>(field_data.value);
741 
742                 EXPECT_EQ(utf::CompareMUtf8ToMUtf8(pf->GetStringData(string_id).data, utf::CStringAsMutf8(val.c_str())),
743                           0);
744                 break;
745             }
746             default: {
747                 UNREACHABLE();
748                 break;
749             }
750         }
751 
752         ++idx;
753     });
754 }
755 
756 /**
757  * @tc.name: assembly_emitter_test_009
758  * @tc.desc: Verify the EnumerateMethods function.
759  * @tc.type: FUNC
760  * @tc.require: issueNumber
761  */
762 HWTEST_F(AssemblyEmitterTest, assembly_emitter_test_009, TestSize.Level1)
763 {
764     Parser p;
765     auto source = R"(
766         .function any foo(any a0) <noimpl>
767     )";
768 
769     auto res = p.Parse(source);
770     EXPECT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
771 
772     auto pf = AsmEmitter::Emit(res.Value());
773     EXPECT_NE(pf, nullptr);
774 
775     std::string descriptor;
776 
777     auto class_id = pf->GetClassId(GetTypeDescriptor("_GLOBAL", &descriptor));
778     EXPECT_TRUE(class_id.IsValid());
779 
780     panda_file::ClassDataAccessor cda(*pf, class_id);
781 
782     int32_t num_methods = 0;
783     const auto tagged = panda_file::Type(panda_file::Type::TypeId::TAGGED);
__anon9d5bb8021102(panda_file::MethodDataAccessor &mda) 784     cda.EnumerateMethods([&](panda_file::MethodDataAccessor &mda) {
785         panda_file::ProtoDataAccessor pda(*pf, mda.GetProtoId());
786         EXPECT_EQ(tagged, pda.GetReturnType());
787         EXPECT_EQ(1u, pda.GetNumArgs());
788         EXPECT_EQ(tagged, pda.GetArgType(0));
789 
790         ++num_methods;
791     });
792     EXPECT_EQ(1, num_methods);
793 }
794 
795 /**
796  * @tc.name: assembly_emitter_test_010
797  * @tc.desc: Verify the AsmEmitter::Emit function.
798  * @tc.type: FUNC
799  * @tc.require: issueNumber
800  */
801 HWTEST_F(AssemblyEmitterTest, assembly_emitter_test_010, TestSize.Level1)
802 {
803     Parser p;
804     auto source = R"(
805         .record Test {
806             any foo
807         }
808     )";
809 
810     auto res = p.Parse(source);
811     EXPECT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
812 
813     auto pf = AsmEmitter::Emit(res.Value());
814     EXPECT_NE(pf, nullptr);
815 
816     std::string descriptor;
817 
818     auto class_id = pf->GetClassId(GetTypeDescriptor("Test", &descriptor));
819     EXPECT_TRUE(class_id.IsValid());
820 
821     panda_file::ClassDataAccessor cda(*pf, class_id);
822 
823     size_t num_fields = 0;
824     const auto tagged = panda_file::Type(panda_file::Type::TypeId::TAGGED);
__anon9d5bb8021202(panda_file::FieldDataAccessor &fda) 825     cda.EnumerateFields([&](panda_file::FieldDataAccessor &fda) {
826         uint32_t type = fda.GetType();
827         EXPECT_EQ(tagged.GetFieldEncoding(), type);
828 
829         ++num_fields;
830     });
831     EXPECT_EQ(1, num_fields);
832 }
833 
834 /**
835  * @tc.name: assembly_emitter_test_011
836  * @tc.desc: Verify the AsmEmitter::Emit function.
837  * @tc.type: FUNC
838  * @tc.require: issueNumber
839  */
840 HWTEST_F(AssemblyEmitterTest, assembly_emitter_test_011, TestSize.Level1)
841 {
842     Parser p1;
843     auto source1 = R"(
844         .record Test {
845             any foo
846         }
847     )";
848     Parser p2;
849     auto source2 = R"(
850         .function void main() {
851             ldai 0
852             ldai 1
853             return
854         }
855     )";
856     auto res1 = p1.Parse(source1);
857     EXPECT_EQ(p1.ShowError().err, Error::ErrorType::ERR_NONE);
858 
859     auto res2 = p2.Parse(source2);
860     EXPECT_EQ(p2.ShowError().err, Error::ErrorType::ERR_NONE);
861 
862     std::vector<Program *> progs;
863     progs.push_back(&res1.Value());
864     progs.push_back(&res2.Value());
865     const std::string filename = "source.pa";;
866     auto pf = AsmEmitter::EmitPrograms(filename, progs, false);
867     EXPECT_TRUE(pf);
868 }
869 
870 /**
871  * @tc.name: assembly_emitter_test_012
872  * @tc.desc: Verify the AsmEmitter::Emit function.
873  * @tc.type: FUNC
874  * @tc.require: issueNumber
875  */
876 HWTEST_F(AssemblyEmitterTest, assembly_emitter_test_012, TestSize.Level1)
877 {
878     Parser par;
879     auto source = R"(
880         .record Math <external>
881         .function i64 Math.minI64(i64 a0) <external>
882         .function i64 main(i64 a0, i64 a1) {
883             ldglobalvar 0x9, "Math.minI64"
884             callarg1 0x4, a0
885             return
886         }
887     )";
888     auto ret = par.Parse(source);
889     EXPECT_EQ(par.ShowError().err, Error::ErrorType::ERR_NONE);
890     auto pf = AsmEmitter::Emit(ret.Value());
891     EXPECT_NE(pf, nullptr);
892 
893     std::string descriptors;
894 
895     auto class_id = pf->GetClassId(GetTypeDescriptor("Math", &descriptors));
896     EXPECT_TRUE(class_id.IsValid());
897 }
898 
899 /**
900  * @tc.name: assembly_emitter_test_013
901  * @tc.desc: Verify the AsmEmitter::Emit function.
902  * @tc.type: FUNC
903  * @tc.require: issueNumber
904  */
905 HWTEST_F(AssemblyEmitterTest, assembly_emitter_test_013, TestSize.Level1)
906 {
907     Parser par;
908     auto source = R"(
909         .array array {
910             u1 1
911             u8 2
912             i8 -30
913             u16 400
914             i16 -5000
915             u32 60000
916             i32 -700000
917             u64 8000000
918             i64 -90000000
919             f32 12
920             f64 12
921         }
922     )";
923     std::string source_filename = "source.pa";
924     auto program = par.Parse(source, source_filename);
925     EXPECT_EQ(par.ShowError().err, Error::ErrorType::ERR_NONE);
926     auto pf = AsmEmitter::Emit(program.Value());
927     EXPECT_NE(pf, nullptr);
928 }
929 
930 /**
931  * @tc.name: assembly_emitter_test_014
932  * @tc.desc: Verify the AsmEmitter::Emit function.
933  * @tc.type: FUNC
934  * @tc.require: issueNumber
935  */
936 HWTEST_F(AssemblyEmitterTest, assembly_emitter_test_014, TestSize.Level1)
937 {
938     std::vector<std::vector<panda::pandasm::Token>> v;
939     Lexer l;
940     Parser par;
941     v.push_back(l.TokenizeString(".array array {").first);
942     v.push_back(l.TokenizeString("panda.String \"a\"").first);
943     v.push_back(l.TokenizeString("panda.String \"ab\"").first);
944     v.push_back(l.TokenizeString("panda.String \"abc\"").first);
945     v.push_back(l.TokenizeString("}").first);
946     v.push_back(l.TokenizeString(".array array_static panda.String 3 { \"a\" \"ab\" \"abc\" }").first);
947     auto program = par.Parse(v);
948     EXPECT_EQ(par.ShowError().err, Error::ErrorType::ERR_NONE);
949     auto pf = AsmEmitter::Emit(program.Value());
950     EXPECT_NE(pf, nullptr);
951 }
952 
953 /**
954  * @tc.name: assembly_emitter_test_015
955  * @tc.desc: Verify the AsmEmitter::Emit function.
956  * @tc.type: FUNC
957  * @tc.require: issueNumber
958  */
959 HWTEST_F(AssemblyEmitterTest, assembly_emitter_test_015, TestSize.Level1)
960 {
961     Parser par;
962     auto source = R"(
963         .record R {
964             R[][] f
965         }
966         .function any f(i8 a0) {
967             sta a0
968         }
969         .array array {
970             u1 1
971         }
972     )";
973     std::string source_filename = "source.pa";
974     auto program = par.Parse(source, source_filename);
975     EXPECT_EQ(par.ShowError().err, Error::ErrorType::ERR_NONE);
976 
977     panda::pandasm::Type type;
978     ScalarValue insn_order(ScalarValue::Create<panda::pandasm::Value::Type::RECORD>(type));
979     program.Value().record_table.at("R").field_list[0].metadata->SetValue(insn_order);
980 
981     auto pf = AsmEmitter::Emit(program.Value());
982     EXPECT_NE(pf, nullptr);
983 
984     program.Value().literalarray_table.at("array").literals_[0].tag_ = panda_file::LiteralTag::LITERALARRAY;
985     program.Value().literalarray_table.at("array").literals_[0].value_.emplace<std::string>("array");
986     ScalarValue insn_order_lite(ScalarValue::Create<panda::pandasm::Value::Type::LITERALARRAY>("array"));
987     program.Value().record_table.at("R").field_list[0].metadata->SetValue(insn_order_lite);
988     auto pf1 = AsmEmitter::Emit(program.Value());
989     EXPECT_NE(pf1, nullptr);
990 
991     ScalarValue insn_order_enum(ScalarValue::Create<panda::pandasm::Value::Type::ENUM>("R.f"));
992     program.Value().record_table.at("R").field_list[0].metadata->SetValue(insn_order_enum);
993     program.Value().record_table.at("R").field_list[0].metadata->SetAttributeValue("external", "enum");
994     auto pf2 = AsmEmitter::Emit(program.Value());
995     EXPECT_NE(pf2, nullptr);
996 
997     ScalarValue insn_order_method(ScalarValue::Create<panda::pandasm::Value::Type::METHOD>("f:(i8)"));
998     program.Value().record_table.at("R").field_list[0].metadata->SetValue(insn_order_method);
999     auto pf3 = AsmEmitter::Emit(program.Value());
1000     EXPECT_NE(pf3, nullptr);
1001 
1002     ScalarValue insn_orders(ScalarValue::Create<panda::pandasm::Value::Type::I32>(1));
1003     std::vector<panda::pandasm::ScalarValue> elements;
1004     elements.emplace_back(std::move(insn_orders));
1005 
1006     ArrayValue array_value(panda::pandasm::Value::Type::I32, elements);
1007     AnnotationElement anno_element("_TypeOfInstruction", std::make_unique<ArrayValue>(array_value));
1008     AnnotationData annotation("_ESSlotNumberAnnotation");
1009     annotation.AddElement(std::move(anno_element));
1010 
1011 
1012     ScalarValue insn_order_anno(ScalarValue::Create<panda::pandasm::Value::Type::ANNOTATION>(annotation));
1013 
1014     program.Value().record_table.at("R").field_list[0].metadata->SetValue(insn_order_anno);
1015     auto pf4 = AsmEmitter::Emit(program.Value());
1016     EXPECT_NE(pf4, nullptr);
1017 
1018 }
1019 
1020 /**
1021  * @tc.name: assembly_emitter_test_016
1022  * @tc.desc: Verify the AsmEmitter::Emit function.
1023  * @tc.type: FUNC
1024  * @tc.require: issueNumber
1025  */
1026 HWTEST_F(AssemblyEmitterTest, assembly_emitter_test_016, TestSize.Level1)
1027 {
1028     Parser par;
1029     std::vector<std::vector<panda::pandasm::Token>> v;
1030     Lexer l;
1031     v.push_back(l.TokenizeString(".array array {").first);
1032     v.push_back(l.TokenizeString("u1 1").first);
1033     v.push_back(l.TokenizeString("u8 2").first);
1034     v.push_back(l.TokenizeString("i8 -30").first);
1035     v.push_back(l.TokenizeString("u16 400").first);
1036     v.push_back(l.TokenizeString("i16 -5000").first);
1037     v.push_back(l.TokenizeString("u32 60000").first);
1038     v.push_back(l.TokenizeString("i32 -700000").first);
1039     v.push_back(l.TokenizeString("u64 8000000").first);
1040     v.push_back(l.TokenizeString("i64 -90000000").first);
1041     v.push_back(l.TokenizeString("}").first);
1042     v.push_back(l.TokenizeString(".function any f(i8 a0) { sta a0 }").first);
1043     std::string source_filename = "source.pa";
1044     auto item = par.Parse(v, source_filename);
1045     EXPECT_EQ(par.ShowError().err, Error::ErrorType::ERR_NONE);
1046 
1047     item.Value().literalarray_table.at("array").literals_[0].tag_ = panda_file::LiteralTag::BOOL;
1048     item.Value().literalarray_table.at("array").literals_[0].value_.emplace<0>(true);
1049 
1050     item.Value().literalarray_table.at("array").literals_[1].tag_ = panda_file::LiteralTag::METHODAFFILIATE;
1051     item.Value().literalarray_table.at("array").literals_[1].value_.emplace<uint16_t>(1);
1052 
1053     item.Value().literalarray_table.at("array").literals_[2].tag_ = panda_file::LiteralTag::FLOAT;
1054     item.Value().literalarray_table.at("array").literals_[2].value_.emplace<float>(1.0);
1055 
1056     item.Value().literalarray_table.at("array").literals_[3].tag_ = panda_file::LiteralTag::DOUBLE;
1057     item.Value().literalarray_table.at("array").literals_[3].value_.emplace<double>(1.0);
1058 
1059     item.Value().literalarray_table.at("array").literals_[4].tag_ = panda_file::LiteralTag::STRING;
1060     item.Value().literalarray_table.at("array").literals_[4].value_.emplace<std::string>("1.0");
1061 
1062     item.Value().literalarray_table.at("array").literals_[5].tag_ = panda_file::LiteralTag::ASYNCGENERATORMETHOD;
1063     item.Value().literalarray_table.at("array").literals_[5].value_.emplace<std::string>("f:(i8)");
1064 
1065     item.Value().literalarray_table.at("array").literals_[6].tag_ = panda_file::LiteralTag::LITERALARRAY;
1066     item.Value().literalarray_table.at("array").literals_[6].value_.emplace<std::string>("array");
1067 
1068     auto pf = AsmEmitter::Emit(item.Value());
1069     EXPECT_NE(pf, nullptr);
1070 }
1071 
1072 /**
1073  * @tc.name: assembly_emitter_test_017
1074  * @tc.desc: Verify the AsmEmitter::Emit function.
1075  * @tc.type: FUNC
1076  * @tc.require: issueNumber
1077  */
1078 HWTEST_F(AssemblyEmitterTest, assembly_emitter_test_017, TestSize.Level1)
1079 {
1080     Parser par;
1081     auto source = R"(
1082         .record Asm1 {
1083             i64 asm1
1084             void asm2
1085             i32 asm3
1086         }
1087     )";
1088     std::string source_filename = "source.pa";
1089     auto item = par.Parse(source, source_filename);
1090     EXPECT_EQ(par.ShowError().err, Error::ErrorType::ERR_NONE);
1091 
1092     EXPECT_EQ(item.Value().record_table.at("Asm1").name, "Asm1");
1093     EXPECT_EQ(item.Value().record_table.at("Asm1").field_list[0].name, "asm1");
1094     EXPECT_EQ(item.Value().record_table.at("Asm1").field_list[0].type.GetId(), panda::panda_file::Type::TypeId::I64);
1095     EXPECT_EQ(item.Value().record_table.at("Asm1").field_list[1].name, "asm2");
1096     EXPECT_EQ(item.Value().record_table.at("Asm1").field_list[1].type.GetId(), panda::panda_file::Type::TypeId::VOID);
1097     EXPECT_EQ(item.Value().record_table.at("Asm1").field_list[2].name, "asm3");
1098     EXPECT_EQ(item.Value().record_table.at("Asm1").field_list[2].type.GetId(), panda::panda_file::Type::TypeId::I32);
1099 
1100     auto pf = AsmEmitter::Emit(item.Value());
1101     EXPECT_NE(pf, nullptr);
1102 }
1103 
1104 /**
1105  * @tc.name: assembly_emitter_test_018
1106  * @tc.desc: Verify the AsmEmitter::Emit function.
1107  * @tc.type: FUNC
1108  * @tc.require: issueNumber
1109  */
1110 HWTEST_F(AssemblyEmitterTest, assembly_emitter_test_018, TestSize.Level1)
1111 {
1112     Parser par;
1113     auto source = R"(
1114         .function any f(i8 a0) {
1115             sta a0
1116         }
1117     )";
1118     std::string source_filename = "source.pa";
1119     AsmEmitter::PandaFileToPandaAsmMaps *maps = nullptr;
1120     auto items = panda::panda_file::ItemContainer {};
1121     auto program = par.Parse(source, source_filename);
1122     program.Value().function_table.at("f:(i8)").metadata->SetAttribute("external");
1123     EXPECT_EQ(par.ShowError().err, Error::ErrorType::ERR_NONE);
1124     auto pf = AsmEmitter::Emit(&items, program.Value(), maps, false);
1125     EXPECT_EQ(pf, true);
1126 }
1127 
1128 /**
1129  * @tc.name: assembly_emitter_test_019
1130  * @tc.desc: Verify the AsmEmitter::Emit function.
1131  * @tc.type: FUNC
1132  * @tc.require: issueNumber
1133  */
1134 HWTEST_F(AssemblyEmitterTest, assembly_emitter_test_019, TestSize.Level1)
1135 {
1136     Parser par;
1137     auto source = R"(
1138         .function any f(i8 a0) {
1139             sta a0
1140         }
1141     )";
1142     std::string source_filename = "source.pa";
1143 
1144     auto program = par.Parse(source, source_filename);
1145     program.Value().function_table.at("f:(i8)").metadata->SetAttribute("external");
1146     panda::pandasm::debuginfo::LocalVariable local;
1147     local.name = "test";
1148     local.signature = "test";
1149     local.signature_type = "test";
1150     program.Value().function_table.at("f:(i8)").local_variable_debug.push_back(local);
1151     EXPECT_EQ(par.ShowError().err, Error::ErrorType::ERR_NONE);
1152     auto success = AsmEmitter::Emit(program.Value());
1153     EXPECT_NE(success, nullptr);
1154 }
1155 
1156 /**
1157  * @tc.name: assembly_emitter_test_020
1158  * @tc.desc: Verify the EmitPrograms function.
1159  * @tc.type: FUNC
1160  * @tc.require: issueNumber
1161  */
1162 HWTEST_F(AssemblyEmitterTest, assembly_emitter_test_020, TestSize.Level1)
1163 {
1164     Parser p1;
1165     auto source1 = R"(
1166         .record Test {
1167             any foo
1168         }
1169     )";
1170     Parser p2;
1171     auto source2 = R"(
1172         .function void main() {
1173             ldai 0
1174             ldai 1
1175             return
1176         }
1177     )";
1178     auto res1 = p1.Parse(source1);
1179     EXPECT_EQ(p1.ShowError().err, Error::ErrorType::ERR_NONE);
1180 
1181     auto res2 = p2.Parse(source2);
1182     EXPECT_EQ(p2.ShowError().err, Error::ErrorType::ERR_NONE);
1183 
1184     std::vector<Program *> progs;
1185     progs.push_back(&res1.Value());
1186     progs.push_back(&res2.Value());
1187     const std::string filename = "source.pa";;
1188     auto success = AsmEmitter::EmitPrograms(filename, progs, true);
1189     EXPECT_TRUE(success);
1190 }
1191 }