• 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 
__anon4b9ec5e20102(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 
__anon4b9ec5e20202(panda_file::File::EntityId) 131         cda.EnumerateAnnotations([](panda_file::File::EntityId) { EXPECT_TRUE(false); });
132 
__anon4b9ec5e20302(panda_file::FieldDataAccessor &) 133         cda.EnumerateFields([](panda_file::FieldDataAccessor &) { EXPECT_TRUE(false); });
134 
__anon4b9ec5e20402(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             EXPECT_EQ(mda.GetProtoIdx(), panda_file::INVALID_INDEX_16);
142 
143             EXPECT_EQ(mda.GetAccessFlags(), ACC_STATIC);
144             EXPECT_TRUE(mda.GetCodeId().has_value());
145 
146             panda_file::CodeDataAccessor cdacc(*pf, mda.GetCodeId().value());
147             EXPECT_EQ(cdacc.GetNumVregs(), 0U);
148             EXPECT_EQ(cdacc.GetNumArgs(), 0U);
149             EXPECT_EQ(cdacc.GetCodeSize(), 1U);
150             EXPECT_EQ(cdacc.GetTriesSize(), 0U);
151 
152             EXPECT_FALSE(mda.GetRuntimeParamAnnotationId().has_value());
153             EXPECT_FALSE(mda.GetParamAnnotationId().has_value());
154             EXPECT_TRUE(mda.GetDebugInfoId().has_value());
155 
156             panda_file::DebugInfoDataAccessor dda(*pf, mda.GetDebugInfoId().value());
157             EXPECT_EQ(dda.GetLineStart(), 8U);
158             EXPECT_EQ(dda.GetNumParams(), 0U);
159 
160             mda.EnumerateAnnotations([](panda_file::File::EntityId) {});
161         });
162     }
163     {
164         std::string descriptor;
165         auto class_id = pf->GetClassId(GetTypeDescriptor("R", &descriptor));
166         EXPECT_TRUE(class_id.IsValid());
167         EXPECT_FALSE(pf->IsExternal(class_id));
168 
169         panda_file::ClassDataAccessor cda(*pf, class_id);
170         EXPECT_EQ(cda.GetSuperClassId().GetOffset(), 0U);
171         EXPECT_EQ(cda.GetAccessFlags(), ACC_PUBLIC);
172         EXPECT_EQ(cda.GetFieldsNumber(), 2U);
173         EXPECT_EQ(cda.GetMethodsNumber(), 0U);
174         EXPECT_EQ(cda.GetIfacesNumber(), 0U);
175 
176         // We emit SET_FILE in debuginfo
177         EXPECT_TRUE(cda.GetSourceFileId().has_value());
178 
179         EXPECT_EQ(std::string(reinterpret_cast<const char *>(pf->GetStringData(cda.GetSourceFileId().value()).data)),
180                   source_filename);
181 
182         struct FieldData {
183             std::string name;
184             panda_file::Type::TypeId type_id;
185             uint32_t access_flags;
186         };
187 
188         std::vector<FieldData> fields {{"sf", panda_file::Type::TypeId::I32, ACC_STATIC},
189                                        {"if", panda_file::Type::TypeId::I8, 0}};
190 
191         size_t i = 0;
__anon4b9ec5e20602(panda_file::FieldDataAccessor &fda) 192         cda.EnumerateFields([&](panda_file::FieldDataAccessor &fda) {
193             EXPECT_FALSE(fda.IsExternal());
194             EXPECT_EQ(fda.GetClassId(), class_id);
195             EXPECT_EQ(utf::CompareMUtf8ToMUtf8(pf->GetStringData(fda.GetNameId()).data,
196                                                utf::CStringAsMutf8(fields[i].name.c_str())),
197                       0);
198 
199             EXPECT_EQ(fda.GetType(), panda_file::Type(fields[i].type_id).GetFieldEncoding());
200             EXPECT_EQ(fda.GetAccessFlags(), fields[i].access_flags);
201 
202             fda.EnumerateAnnotations([](panda_file::File::EntityId) { EXPECT_TRUE(false); });
203 
204             ++i;
205         });
206 
__anon4b9ec5e20802(panda_file::MethodDataAccessor &) 207         cda.EnumerateMethods([&](panda_file::MethodDataAccessor &) { EXPECT_TRUE(false); });
208     }
209 }
210 
211 /**
212  * @tc.name: assembly_emitter_test_003
213  * @tc.desc: Verify the EnumerateMethods function.
214  * @tc.type: FUNC
215  * @tc.require: issueNumber
216  */
217 HWTEST_F(AssemblyEmitterTest, assembly_emitter_test_003, TestSize.Level1)
218 {
219     Parser p;
220 
221     auto source = R"(
222         .function void main() {
223             ldai 0      # line 3, pc 0
224                         # line 4
225                         # line 5
226                         # line 6
227                         # line 7
228                         # line 8
229                         # line 9
230                         # line 10
231                         # line 11
232                         # line 12
233                         # line 13
234                         # line 14
235             ldai 1      # line 15, pc 9
236             return # line 16, pc 18
237         }
238     )";
239 
240     std::string source_filename = "source.pa";
241     auto res = p.Parse(source, source_filename);
242     EXPECT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
243 
244     auto pf = AsmEmitter::Emit(res.Value());
245     EXPECT_NE(pf, nullptr);
246 
247     std::string descriptor;
248     auto class_id = pf->GetClassId(GetTypeDescriptor("_GLOBAL", &descriptor));
249     EXPECT_TRUE(class_id.IsValid());
250 
251     panda_file::ClassDataAccessor cda(*pf, class_id);
252 
__anon4b9ec5e20902(panda_file::MethodDataAccessor &mda) 253     cda.EnumerateMethods([&](panda_file::MethodDataAccessor &mda) {
254         panda_file::CodeDataAccessor cdacc(*pf, mda.GetCodeId().value());
255         EXPECT_TRUE(mda.GetDebugInfoId().has_value());
256 
257         panda_file::DebugInfoDataAccessor dda(*pf, mda.GetDebugInfoId().value());
258         EXPECT_EQ(dda.GetLineStart(), 3U);
259         EXPECT_EQ(dda.GetNumParams(), 0U);
260 
261         dda.GetLineNumberProgram();
262         Span<const uint8_t> constant_pool = dda.GetConstantPool();
263 
264         std::vector<uint8_t> opcodes {static_cast<uint8_t>(panda_file::LineNumberProgramItem::Opcode::SET_FILE),
265                                       static_cast<uint8_t>(panda_file::LineNumberProgramItem::Opcode::ADVANCE_PC),
266                                       static_cast<uint8_t>(panda_file::LineNumberProgramItem::Opcode::ADVANCE_LINE),
267                                       GetSpecialOpcode(0, 0),
268                                       GetSpecialOpcode(9, 1),
269                                       static_cast<uint8_t>(panda_file::LineNumberProgramItem::Opcode::END_SEQUENCE)};
270 
271         size_t size {};
272         bool is_full {};
273         size_t constant_pool_offset = 0;
274 
275         uint32_t offset {};
276 
277         std::tie(offset, size, is_full) = leb128::DecodeUnsigned<uint32_t>(&constant_pool[constant_pool_offset]);
278         constant_pool_offset += size;
279         EXPECT_TRUE(is_full);
280         EXPECT_EQ(
281             std::string(reinterpret_cast<const char *>(pf->GetStringData(panda_file::File::EntityId(offset)).data)),
282             source_filename);
283 
284         uint32_t pc_inc;
285         std::tie(pc_inc, size, is_full) = leb128::DecodeUnsigned<uint32_t>(&constant_pool[constant_pool_offset]);
286         constant_pool_offset += size;
287         EXPECT_TRUE(is_full);
288         EXPECT_EQ(pc_inc, 0U);
289 
290         int32_t line_inc;
291         std::tie(line_inc, size, is_full) = leb128::DecodeSigned<int32_t>(&constant_pool[constant_pool_offset]);
292         constant_pool_offset += size;
293         EXPECT_TRUE(is_full);
294         EXPECT_EQ(line_inc, 5);
295 
296         EXPECT_EQ(constant_pool_offset + 1, constant_pool.size());
297     });
298 }
299 
300 /**
301  * @tc.name: assembly_emitter_test_004
302  * @tc.desc: Verify the EnumerateMethods function.
303  * @tc.type: FUNC
304  * @tc.require: issueNumber
305  */
306 HWTEST_F(AssemblyEmitterTest, assembly_emitter_test_004, TestSize.Level1)
307 {
308     Parser p;
309 
310     auto source = R"(
311         .record Exception1 {}
312         .record Exception2 {}
313 
314         .function any myFunction(any a0, any a1, any a2) <static> {
315             mov v0, a0
316             mov v1, a1
317             mov v2, a2
318             ldundefined
319             sta v4
320         try_begin:
321             jmp handler_begin1
322         handler_begin1:
323             ldhole
324             sta v5
325             jmp handler_end2
326         handler_begin2:
327             sta v5
328         handler_end2:
329             lda v4
330             sta v6
331             ldundefined
332             eq 0x0, v6
333             jeqz jump_label_4
334             sta v4
335         jump_label_4:
336             lda v5
337             sta v6
338             ldhole
339             sta v7
340             lda v6
341             noteq 0x1, v7
342             jeqz jump_label_5
343             lda v6
344             throw
345         jump_label_5:
346             ldundefined
347             returnundefined
348 
349         .catchall try_begin, try_begin, handler_begin1
350         .catchall try_begin, handler_begin1, handler_begin2, handler_end2
351         }
352     )";
353 
354     auto res = p.Parse(source);
355     EXPECT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
356     auto pf = AsmEmitter::Emit(res.Value());
357     EXPECT_NE(pf, nullptr);
358 
359     std::string descriptor;
360 
361     auto class_id = pf->GetClassId(GetTypeDescriptor("_GLOBAL", &descriptor));
362     EXPECT_TRUE(class_id.IsValid());
363 
364     panda_file::ClassDataAccessor cda(*pf, class_id);
365 
366     size_t i = 0;
__anon4b9ec5e20a02(panda_file::MethodDataAccessor &mda) 367     cda.EnumerateMethods([&](panda_file::MethodDataAccessor &mda) {
368         panda_file::CodeDataAccessor cdacc(*pf, mda.GetCodeId().value());
369         // The NumVregs of arguments is 8U
370         // The NumArgs of arguments is 3U
371         // The tries size is 2U
372         EXPECT_EQ(cdacc.GetNumVregs(), 8U);
373         EXPECT_EQ(cdacc.GetNumArgs(), 3U);
374         EXPECT_EQ(cdacc.GetTriesSize(), 2U);
375 
376         cdacc.EnumerateTryBlocks([&](panda_file::CodeDataAccessor::TryBlock &try_block) {
377             // Try start Pc is 9U
378             // Catches number is 1U
379             EXPECT_EQ(try_block.GetStartPc(), 9U);
380             EXPECT_EQ(try_block.GetNumCatches(), 1U);
381 
382             struct CatchInfo {
383                 panda_file::File::EntityId type_id;
384                 uint32_t handler_pc;
385             };
386             // Exception1 class ID is 11.
387             // Exception2 class ID is 16.
388             // The file entity ID is 6 * 9.
389             std::vector<CatchInfo> catch_infos {{pf->GetClassId(GetTypeDescriptor("Exception1", &descriptor)), 11},
390                                                 {pf->GetClassId(GetTypeDescriptor("Exception2", &descriptor)), 16},
391                                                 {panda_file::File::EntityId(), 6 * 9}};
392 
393             try_block.EnumerateCatchBlocks([&](panda_file::CodeDataAccessor::CatchBlock &catch_block) {
394                 EXPECT_EQ(catch_block.GetHandlerPc(), catch_infos[i].handler_pc);
395                 ++i;
396 
397                 return true;
398             });
399 
400             return true;
401         });
402     });
403 }
404 
405 /**
406  * @tc.name: assembly_emitter_test_005
407  * @tc.desc: Verify the AsmEmitter::GetLastError() function.
408  * @tc.type: FUNC
409  * @tc.require: issueNumber
410  */
411 HWTEST_F(AssemblyEmitterTest, assembly_emitter_test_005, TestSize.Level1)
412 {
413     {
414         Parser p;
415         auto source = R"(
416             .record A {
417                 B b
418             }
419         )";
420 
421         auto res = p.Parse(source);
422         EXPECT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
423 
424         auto pf = AsmEmitter::Emit(res.Value());
425         EXPECT_EQ(pf, nullptr);
426         EXPECT_EQ(AsmEmitter::GetLastError(), "Field A.b has undefined type");
427     }
428 
429     {
430         Parser p;
431         auto source = R"(
432             .function void A.b() {}
433         )";
434 
435         auto res = p.Parse(source);
436         EXPECT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
437 
438         auto pf = AsmEmitter::Emit(res.Value());
439         EXPECT_EQ(pf, nullptr);
440         EXPECT_EQ(AsmEmitter::GetLastError(), "Function A.b is bound to undefined record A");
441     }
442 
443     {
444         Parser p;
445         auto source = R"(
446             .function A b() {}
447         )";
448 
449         auto res = p.Parse(source);
450         EXPECT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
451 
452         auto pf = AsmEmitter::Emit(res.Value());
453         EXPECT_EQ(pf, nullptr);
454         EXPECT_EQ(AsmEmitter::GetLastError(), "Function b has undefined return type");
455     }
456 
457     {
458         Parser p;
459         auto source = R"(
460             .function void a(b a0) {}
461         )";
462 
463         auto res = p.Parse(source);
464         EXPECT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
465 
466         auto pf = AsmEmitter::Emit(res.Value());
467         EXPECT_EQ(pf, nullptr);
468         EXPECT_EQ(AsmEmitter::GetLastError(), "Argument 0 of function a has undefined type");
469     }
470 
471     {
472         Parser p;
473         auto source = R"(
474             .record A <external>
475             .function void A.x() {}
476         )";
477 
478         auto res = p.Parse(source);
479         EXPECT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
480 
481         auto pf = AsmEmitter::Emit(res.Value());
482         EXPECT_EQ(pf, nullptr);
483         EXPECT_EQ(AsmEmitter::GetLastError(), "Non-external function A.x is bound to external record");
484     }
485 }
486 
487 /**
488  * @tc.name: assembly_emitter_test_006
489  * @tc.desc: Verify the EnumerateMethods function.
490  * @tc.type: FUNC
491  * @tc.require: issueNumber
492  */
493 HWTEST_F(AssemblyEmitterTest, assembly_emitter_test_006, TestSize.Level1)
494 {
495     Parser p;
496     auto source = R"(
497         .function void foo() {}
498     )";
499 
500     auto res = p.Parse(source);
501     EXPECT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
502 
503     auto pf = AsmEmitter::Emit(res.Value());
504     EXPECT_NE(pf, nullptr);
505 
506     std::string descriptor;
507 
508     auto class_id = pf->GetClassId(GetTypeDescriptor("_GLOBAL", &descriptor));
509     EXPECT_TRUE(class_id.IsValid());
510 
511     panda_file::ClassDataAccessor cda(*pf, class_id);
512 
513     EXPECT_FALSE(cda.GetSourceLang());
514 
__anon4b9ec5e20d02(panda_file::MethodDataAccessor &mda) 515     cda.EnumerateMethods([&](panda_file::MethodDataAccessor &mda) { EXPECT_FALSE(mda.GetSourceLang()); });
516 }
517 
518 /**
519  * @tc.name: assembly_emitter_test_007
520  * @tc.desc: Verify the EnumerateMethods function.
521  * @tc.type: FUNC
522  * @tc.require: issueNumber
523  */
524 HWTEST_F(AssemblyEmitterTest, assembly_emitter_test_007, TestSize.Level1)
525 {
526     {
527         Parser p;
528         auto source = R"(
529             .record R {}
530             .function void R.foo(R a0) <ctor> {}
531         )";
532 
533         auto res = p.Parse(source);
534         EXPECT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
535 
536         auto pf = AsmEmitter::Emit(res.Value());
537         EXPECT_NE(pf, nullptr);
538 
539         std::string descriptor;
540 
541         auto class_id = pf->GetClassId(GetTypeDescriptor("R", &descriptor));
542         EXPECT_TRUE(class_id.IsValid());
543 
544         panda_file::ClassDataAccessor cda(*pf, class_id);
545 
__anon4b9ec5e20e02(panda_file::MethodDataAccessor &mda) 546         cda.EnumerateMethods([&](panda_file::MethodDataAccessor &mda) {
547             auto *name = utf::Mutf8AsCString(pf->GetStringData(mda.GetNameId()).data);
548             EXPECT_STREQ(name, ".ctor");
549         });
550     }
551 
552     {
553         Parser p;
554         auto source = R"(
555             .record R {}
556             .function void R.foo(R a0) <cctor> {}
557         )";
558 
559         auto res = p.Parse(source);
560         EXPECT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
561 
562         auto pf = AsmEmitter::Emit(res.Value());
563         EXPECT_NE(pf, nullptr);
564 
565         std::string descriptor;
566 
567         auto class_id = pf->GetClassId(GetTypeDescriptor("R", &descriptor));
568         EXPECT_TRUE(class_id.IsValid());
569 
570         panda_file::ClassDataAccessor cda(*pf, class_id);
571 
__anon4b9ec5e20f02(panda_file::MethodDataAccessor &mda) 572         cda.EnumerateMethods([&](panda_file::MethodDataAccessor &mda) {
573             auto *name = utf::Mutf8AsCString(pf->GetStringData(mda.GetNameId()).data);
574             EXPECT_STREQ(name, ".cctor");
575         });
576     }
577 }
578 
579 /**
580  * @tc.name: assembly_emitter_test_008
581  * @tc.desc: Verify the EnumerateFields function.
582  * @tc.type: FUNC
583  * @tc.require: issueNumber
584  */
585 HWTEST_F(AssemblyEmitterTest, assembly_emitter_test_008, TestSize.Level1)
586 {
587     Parser p;
588 
589     auto source = R"(
590         .record panda.String <external>
591 
592         .record R {
593             u1 f_u1 <value=1>
594             i8 f_i8 <value=2>
595             u8 f_u8 <value=128>
596             i16 f_i16 <value=256>
597             u16 f_u16 <value=32768>
598             i32 f_i32 <value=65536>
599             u32 f_u32 <value=2147483648>
600             i64 f_i64 <value=4294967296>
601             u64 f_u64 <value=9223372036854775808>
602             f32 f_f32 <value=1.0>
603             f64 f_f64 <value=2.0>
604             panda.String f_str <value="str">
605         }
606     )";
607 
608     struct FieldData {
609         std::string name;
610         panda_file::Type::TypeId type_id;
611         std::variant<int32_t, uint32_t, int64_t, uint64_t, float, double, std::string> value;
612     };
613 
614     uint32_t f_u1 = 1;
615     int32_t f_i8 = 2;
616     uint32_t f_u8 = 128;
617     int32_t f_i16 = 256;
618     uint32_t f_u16 = 32768;
619     int32_t f_i32 = 65536;
620     uint32_t f_u32 = 2147483648;
621     int64_t f_i64 = 4294967296;
622     uint64_t f_u64 = 9223372036854775808ULL;
623     float f_f32 = 1.0;
624     double f_f64 = 2.0;
625 
626     std::vector<FieldData> data {
627         {"f_u1", panda_file::Type::TypeId::U1, f_u1}, {"f_i8", panda_file::Type::TypeId::I8, f_i8},
628         {"f_u8", panda_file::Type::TypeId::U8, f_u8}, {"f_i16", panda_file::Type::TypeId::I16, f_i16},
629         {"f_u16", panda_file::Type::TypeId::U16, f_u16}, {"f_i32", panda_file::Type::TypeId::I32, f_i32},
630         {"f_u32", panda_file::Type::TypeId::U32, f_u32}, {"f_i64", panda_file::Type::TypeId::I64, f_i64},
631         {"f_u64", panda_file::Type::TypeId::U64, f_u64}, {"f_f32", panda_file::Type::TypeId::F32, f_f32},
632         {"f_f64", panda_file::Type::TypeId::F64, f_f64}, {"f_str", panda_file::Type::TypeId::REFERENCE, "str"}};
633 
634     auto res = p.Parse(source);
635     EXPECT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
636 
637     auto pf = AsmEmitter::Emit(res.Value());
638     EXPECT_NE(pf, nullptr);
639 
640     std::string descriptor;
641     auto class_id = pf->GetClassId(GetTypeDescriptor("R", &descriptor));
642     EXPECT_TRUE(class_id.IsValid());
643     EXPECT_FALSE(pf->IsExternal(class_id));
644 
645     panda_file::ClassDataAccessor cda(*pf, class_id);
646     EXPECT_EQ(cda.GetFieldsNumber(), data.size());
647 
648     auto panda_string_id = pf->GetClassId(GetTypeDescriptor("panda.String", &descriptor));
649 
650     size_t idx = 0;
__anon4b9ec5e21002(panda_file::FieldDataAccessor &fda) 651     cda.EnumerateFields([&](panda_file::FieldDataAccessor &fda) {
652         const FieldData &field_data = data[idx];
653 
654         EXPECT_EQ(utf::CompareMUtf8ToMUtf8(pf->GetStringData(fda.GetNameId()).data,
655                                            utf::CStringAsMutf8(field_data.name.c_str())),
656                   0);
657 
658         panda_file::Type type(field_data.type_id);
659         uint32_t type_value;
660         if (type.IsReference()) {
661             type_value = panda_string_id.GetOffset();
662         } else {
663             type_value = type.GetFieldEncoding();
664         }
665 
666         switch (field_data.type_id) {
667             case panda_file::Type::TypeId::U1: {
668                 auto result = fda.GetValue<uint8_t>();
669                 EXPECT_TRUE(result);
670                 EXPECT_EQ(result.value(), std::get<uint32_t>(field_data.value));
671                 break;
672             }
673             case panda_file::Type::TypeId::I8: {
674                 auto result = fda.GetValue<int8_t>();
675                 EXPECT_TRUE(result);
676                 EXPECT_EQ(result.value(), std::get<int32_t>(field_data.value));
677                 break;
678             }
679             case panda_file::Type::TypeId::U8: {
680                 auto result = fda.GetValue<uint8_t>();
681                 EXPECT_TRUE(result);
682                 EXPECT_EQ(result.value(), std::get<uint32_t>(field_data.value));
683                 break;
684             }
685             case panda_file::Type::TypeId::I16: {
686                 auto result = fda.GetValue<int16_t>();
687                 EXPECT_TRUE(result);
688                 EXPECT_EQ(result.value(), std::get<int32_t>(field_data.value));
689                 break;
690             }
691             case panda_file::Type::TypeId::U16: {
692                 auto result = fda.GetValue<uint16_t>();
693                 EXPECT_TRUE(result);
694                 EXPECT_EQ(result.value(), std::get<uint32_t>(field_data.value));
695                 break;
696             }
697             case panda_file::Type::TypeId::I32: {
698                 auto result = fda.GetValue<int32_t>();
699                 EXPECT_TRUE(result);
700                 EXPECT_EQ(result.value(), std::get<int32_t>(field_data.value));
701                 break;
702             }
703             case panda_file::Type::TypeId::U32: {
704                 auto result = fda.GetValue<uint32_t>();
705                 EXPECT_TRUE(result);
706                 EXPECT_EQ(result.value(), std::get<uint32_t>(field_data.value));
707                 break;
708             }
709             case panda_file::Type::TypeId::I64: {
710                 auto result = fda.GetValue<int64_t>();
711                 EXPECT_TRUE(result);
712                 EXPECT_EQ(result.value(), std::get<int64_t>(field_data.value));
713                 break;
714             }
715             case panda_file::Type::TypeId::U64: {
716                 auto result = fda.GetValue<uint64_t>();
717                 EXPECT_TRUE(result);
718                 EXPECT_EQ(result.value(), std::get<uint64_t>(field_data.value));
719                 break;
720             }
721             case panda_file::Type::TypeId::F32: {
722                 auto result = fda.GetValue<float>();
723                 EXPECT_TRUE(result);
724                 EXPECT_EQ(result.value(), std::get<float>(field_data.value));
725                 break;
726             }
727             case panda_file::Type::TypeId::F64: {
728                 auto result = fda.GetValue<double>();
729                 EXPECT_TRUE(result);
730                 EXPECT_EQ(result.value(), std::get<double>(field_data.value));
731                 break;
732             }
733             case panda_file::Type::TypeId::REFERENCE: {
734                 auto result = fda.GetValue<uint32_t>();
735                 EXPECT_TRUE(result);
736 
737                 panda_file::File::EntityId string_id(result.value());
738                 auto val = std::get<std::string>(field_data.value);
739 
740                 EXPECT_EQ(utf::CompareMUtf8ToMUtf8(pf->GetStringData(string_id).data, utf::CStringAsMutf8(val.c_str())),
741                           0);
742                 break;
743             }
744             default: {
745                 UNREACHABLE();
746                 break;
747             }
748         }
749 
750         ++idx;
751     });
752 }
753 
754 /**
755  * @tc.name: assembly_emitter_test_009
756  * @tc.desc: Verify the EnumerateMethods function.
757  * @tc.type: FUNC
758  * @tc.require: issueNumber
759  */
760 HWTEST_F(AssemblyEmitterTest, assembly_emitter_test_009, TestSize.Level1)
761 {
762     Parser p;
763     auto source = R"(
764         .function any foo(any a0) <noimpl>
765     )";
766 
767     auto res = p.Parse(source);
768     EXPECT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
769 
770     auto pf = AsmEmitter::Emit(res.Value());
771     EXPECT_NE(pf, nullptr);
772 
773     std::string descriptor;
774 
775     auto class_id = pf->GetClassId(GetTypeDescriptor("_GLOBAL", &descriptor));
776     EXPECT_TRUE(class_id.IsValid());
777 
778     panda_file::ClassDataAccessor cda(*pf, class_id);
779 
780     int32_t num_methods = 0;
__anon4b9ec5e21102(panda_file::MethodDataAccessor &mda) 781     cda.EnumerateMethods([&](panda_file::MethodDataAccessor &mda) {
782         EXPECT_FALSE(mda.IsExternal());
783         EXPECT_EQ(mda.GetProtoIdx(), panda_file::INVALID_INDEX_16);
784         EXPECT_TRUE(mda.GetCodeId().has_value());
785         panda_file::CodeDataAccessor cdacc(*pf, mda.GetCodeId().value());
786         EXPECT_EQ(1u, cdacc.GetNumArgs());
787 
788         ++num_methods;
789     });
790     EXPECT_EQ(1, num_methods);
791 }
792 
793 /**
794  * @tc.name: assembly_emitter_test_010
795  * @tc.desc: Verify the AsmEmitter::Emit function.
796  * @tc.type: FUNC
797  * @tc.require: issueNumber
798  */
799 HWTEST_F(AssemblyEmitterTest, assembly_emitter_test_010, TestSize.Level1)
800 {
801     Parser p;
802     auto source = R"(
803         .record Test {
804             any foo
805         }
806     )";
807 
808     auto res = p.Parse(source);
809     EXPECT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
810 
811     auto pf = AsmEmitter::Emit(res.Value());
812     EXPECT_NE(pf, nullptr);
813 
814     std::string descriptor;
815 
816     auto class_id = pf->GetClassId(GetTypeDescriptor("Test", &descriptor));
817     EXPECT_TRUE(class_id.IsValid());
818 
819     panda_file::ClassDataAccessor cda(*pf, class_id);
820 
821     size_t num_fields = 0;
822     const auto tagged = panda_file::Type(panda_file::Type::TypeId::TAGGED);
__anon4b9ec5e21202(panda_file::FieldDataAccessor &fda) 823     cda.EnumerateFields([&](panda_file::FieldDataAccessor &fda) {
824         uint32_t type = fda.GetType();
825         EXPECT_EQ(tagged.GetFieldEncoding(), type);
826 
827         ++num_fields;
828     });
829     EXPECT_EQ(1, num_fields);
830 }
831 
832 /**
833  * @tc.name: assembly_emitter_test_011
834  * @tc.desc: Verify the AsmEmitter::Emit function.
835  * @tc.type: FUNC
836  * @tc.require: issueNumber
837  */
838 HWTEST_F(AssemblyEmitterTest, assembly_emitter_test_011, TestSize.Level1)
839 {
840     Parser p1;
841     auto source1 = R"(
842         .record Test {
843             any foo
844         }
845     )";
846     Parser p2;
847     auto source2 = R"(
848         .function void main() {
849             ldai 0
850             ldai 1
851             return
852         }
853     )";
854     auto res1 = p1.Parse(source1);
855     EXPECT_EQ(p1.ShowError().err, Error::ErrorType::ERR_NONE);
856 
857     auto res2 = p2.Parse(source2);
858     EXPECT_EQ(p2.ShowError().err, Error::ErrorType::ERR_NONE);
859 
860     std::vector<Program *> progs;
861     progs.push_back(&res1.Value());
862     progs.push_back(&res2.Value());
863     const std::string filename = "source.pa";;
864     auto pf = AsmEmitter::EmitPrograms(filename, progs, false);
865     EXPECT_TRUE(pf);
866 }
867 
868 /**
869  * @tc.name: assembly_emitter_test_012
870  * @tc.desc: Verify the AsmEmitter::Emit function.
871  * @tc.type: FUNC
872  * @tc.require: issueNumber
873  */
874 HWTEST_F(AssemblyEmitterTest, assembly_emitter_test_012, TestSize.Level1)
875 {
876     Parser par;
877     auto source = R"(
878         .record Math <external>
879         .function i64 Math.minI64(i64 a0) <external>
880         .function i64 main(i64 a0, i64 a1) {
881             ldglobalvar 0x9, "Math.minI64"
882             callarg1 0x4, a0
883             return
884         }
885     )";
886     auto ret = par.Parse(source);
887     EXPECT_EQ(par.ShowError().err, Error::ErrorType::ERR_NONE);
888     auto pf = AsmEmitter::Emit(ret.Value());
889     EXPECT_NE(pf, nullptr);
890 
891     std::string descriptors;
892 
893     auto class_id = pf->GetClassId(GetTypeDescriptor("Math", &descriptors));
894     EXPECT_TRUE(class_id.IsValid());
895 }
896 
897 /**
898  * @tc.name: assembly_emitter_test_013
899  * @tc.desc: Verify the AsmEmitter::Emit function.
900  * @tc.type: FUNC
901  * @tc.require: issueNumber
902  */
903 HWTEST_F(AssemblyEmitterTest, assembly_emitter_test_013, TestSize.Level1)
904 {
905     Parser par;
906     auto source = R"(
907         .array array {
908             u1 1
909             u8 2
910             i8 -30
911             u16 400
912             i16 -5000
913             u32 60000
914             i32 -700000
915             u64 8000000
916             i64 -90000000
917             f32 12
918             f64 12
919         }
920     )";
921     std::string source_filename = "source.pa";
922     auto program = par.Parse(source, source_filename);
923     EXPECT_EQ(par.ShowError().err, Error::ErrorType::ERR_NONE);
924     auto pf = AsmEmitter::Emit(program.Value());
925     EXPECT_NE(pf, nullptr);
926 }
927 
928 /**
929  * @tc.name: assembly_emitter_test_014
930  * @tc.desc: Verify the AsmEmitter::Emit function.
931  * @tc.type: FUNC
932  * @tc.require: issueNumber
933  */
934 HWTEST_F(AssemblyEmitterTest, assembly_emitter_test_014, TestSize.Level1)
935 {
936     std::vector<std::vector<panda::pandasm::Token>> v;
937     Lexer l;
938     Parser par;
939     v.push_back(l.TokenizeString(".array array {").first);
940     v.push_back(l.TokenizeString("panda.String \"a\"").first);
941     v.push_back(l.TokenizeString("panda.String \"ab\"").first);
942     v.push_back(l.TokenizeString("panda.String \"abc\"").first);
943     v.push_back(l.TokenizeString("}").first);
944     v.push_back(l.TokenizeString(".array array_static panda.String 3 { \"a\" \"ab\" \"abc\" }").first);
945     auto program = par.Parse(v);
946     EXPECT_EQ(par.ShowError().err, Error::ErrorType::ERR_NONE);
947     auto pf = AsmEmitter::Emit(program.Value());
948     EXPECT_NE(pf, nullptr);
949 }
950 
951 /**
952  * @tc.name: assembly_emitter_test_015
953  * @tc.desc: Verify the AsmEmitter::Emit function.
954  * @tc.type: FUNC
955  * @tc.require: issueNumber
956  */
957 HWTEST_F(AssemblyEmitterTest, assembly_emitter_test_015, TestSize.Level1)
958 {
959     Parser par;
960     auto source = R"(
961         .record R {
962             R[][] f
963         }
964         .function any f(i8 a0) {
965             sta a0
966         }
967         .array array {
968             u1 1
969         }
970     )";
971     std::string source_filename = "source.pa";
972     auto program = par.Parse(source, source_filename);
973     EXPECT_EQ(par.ShowError().err, Error::ErrorType::ERR_NONE);
974 
975     panda::pandasm::Type type;
976     ScalarValue insn_order(ScalarValue::Create<panda::pandasm::Value::Type::RECORD>(type));
977     program.Value().record_table.at("R").field_list[0].metadata->SetValue(insn_order);
978 
979     auto pf = AsmEmitter::Emit(program.Value());
980     EXPECT_NE(pf, nullptr);
981 
982     program.Value().literalarray_table.at("array").literals_[0].tag_ = panda_file::LiteralTag::LITERALARRAY;
983     program.Value().literalarray_table.at("array").literals_[0].value_.emplace<std::string>("array");
984     ScalarValue insn_order_lite(ScalarValue::Create<panda::pandasm::Value::Type::LITERALARRAY>("array"));
985     program.Value().record_table.at("R").field_list[0].metadata->SetValue(insn_order_lite);
986     auto pf1 = AsmEmitter::Emit(program.Value());
987     EXPECT_NE(pf1, nullptr);
988 
989     ScalarValue insn_order_enum(ScalarValue::Create<panda::pandasm::Value::Type::ENUM>("R.f"));
990     program.Value().record_table.at("R").field_list[0].metadata->SetValue(insn_order_enum);
991     program.Value().record_table.at("R").field_list[0].metadata->SetAttributeValue("external", "enum");
992     auto pf2 = AsmEmitter::Emit(program.Value());
993     EXPECT_NE(pf2, nullptr);
994 
995     ScalarValue insn_order_method(ScalarValue::Create<panda::pandasm::Value::Type::METHOD>("f:(i8)"));
996     program.Value().record_table.at("R").field_list[0].metadata->SetValue(insn_order_method);
997     auto pf3 = AsmEmitter::Emit(program.Value());
998     EXPECT_NE(pf3, nullptr);
999 
1000     ScalarValue insn_orders(ScalarValue::Create<panda::pandasm::Value::Type::I32>(1));
1001     std::vector<panda::pandasm::ScalarValue> elements;
1002     elements.emplace_back(std::move(insn_orders));
1003 
1004     ArrayValue array_value(panda::pandasm::Value::Type::I32, elements);
1005     AnnotationElement anno_element("_TypeOfInstruction", std::make_unique<ArrayValue>(array_value));
1006     AnnotationData annotation("_ESSlotNumberAnnotation");
1007     annotation.AddElement(std::move(anno_element));
1008 
1009 
1010     ScalarValue insn_order_anno(ScalarValue::Create<panda::pandasm::Value::Type::ANNOTATION>(annotation));
1011 
1012     static const std::string SLOT_NUMBER = "_ESSlotNumberAnnotation";
1013     pandasm::Record record(SLOT_NUMBER, pandasm::extensions::Language::ECMASCRIPT);
1014     record.metadata->AddAccessFlags(panda::ACC_ANNOTATION);
1015     program.Value().record_table.emplace(SLOT_NUMBER, std::move(record));
1016     program.Value().record_table.at("R").field_list[0].metadata->SetValue(insn_order_anno);
1017     auto pf4 = AsmEmitter::Emit(program.Value());
1018     EXPECT_NE(pf4, nullptr);
1019 }
1020 
1021 /**
1022  * @tc.name: assembly_emitter_test_016
1023  * @tc.desc: Verify the AsmEmitter::Emit function.
1024  * @tc.type: FUNC
1025  * @tc.require: issueNumber
1026  */
1027 HWTEST_F(AssemblyEmitterTest, assembly_emitter_test_016, TestSize.Level1)
1028 {
1029     Parser par;
1030     std::vector<std::vector<panda::pandasm::Token>> v;
1031     Lexer l;
1032     v.push_back(l.TokenizeString(".array array {").first);
1033     v.push_back(l.TokenizeString("u1 1").first);
1034     v.push_back(l.TokenizeString("u8 2").first);
1035     v.push_back(l.TokenizeString("i8 -30").first);
1036     v.push_back(l.TokenizeString("u16 400").first);
1037     v.push_back(l.TokenizeString("i16 -5000").first);
1038     v.push_back(l.TokenizeString("u32 60000").first);
1039     v.push_back(l.TokenizeString("i32 -700000").first);
1040     v.push_back(l.TokenizeString("u64 8000000").first);
1041     v.push_back(l.TokenizeString("i64 -90000000").first);
1042     v.push_back(l.TokenizeString("}").first);
1043     v.push_back(l.TokenizeString(".function any f(i8 a0) { sta a0 }").first);
1044     std::string source_filename = "source.pa";
1045     auto item = par.Parse(v, source_filename);
1046     EXPECT_EQ(par.ShowError().err, Error::ErrorType::ERR_NONE);
1047 
1048     item.Value().literalarray_table.at("array").literals_[0].tag_ = panda_file::LiteralTag::BOOL;
1049     item.Value().literalarray_table.at("array").literals_[0].value_.emplace<0>(true);
1050 
1051     item.Value().literalarray_table.at("array").literals_[1].tag_ = panda_file::LiteralTag::METHODAFFILIATE;
1052     item.Value().literalarray_table.at("array").literals_[1].value_.emplace<uint16_t>(1);
1053 
1054     item.Value().literalarray_table.at("array").literals_[2].tag_ = panda_file::LiteralTag::FLOAT;
1055     item.Value().literalarray_table.at("array").literals_[2].value_.emplace<float>(1.0);
1056 
1057     item.Value().literalarray_table.at("array").literals_[3].tag_ = panda_file::LiteralTag::DOUBLE;
1058     item.Value().literalarray_table.at("array").literals_[3].value_.emplace<double>(1.0);
1059 
1060     item.Value().literalarray_table.at("array").literals_[4].tag_ = panda_file::LiteralTag::STRING;
1061     item.Value().literalarray_table.at("array").literals_[4].value_.emplace<std::string>("1.0");
1062 
1063     item.Value().literalarray_table.at("array").literals_[5].tag_ = panda_file::LiteralTag::ASYNCGENERATORMETHOD;
1064     item.Value().literalarray_table.at("array").literals_[5].value_.emplace<std::string>("f:(i8)");
1065 
1066     item.Value().literalarray_table.at("array").literals_[6].tag_ = panda_file::LiteralTag::LITERALARRAY;
1067     item.Value().literalarray_table.at("array").literals_[6].value_.emplace<std::string>("array");
1068 
1069     auto pf = AsmEmitter::Emit(item.Value());
1070     EXPECT_NE(pf, nullptr);
1071 }
1072 
1073 /**
1074  * @tc.name: assembly_emitter_test_017
1075  * @tc.desc: Verify the AsmEmitter::Emit function.
1076  * @tc.type: FUNC
1077  * @tc.require: issueNumber
1078  */
1079 HWTEST_F(AssemblyEmitterTest, assembly_emitter_test_017, TestSize.Level1)
1080 {
1081     Parser par;
1082     auto source = R"(
1083         .record Asm1 {
1084             i64 asm1
1085             void asm2
1086             i32 asm3
1087         }
1088     )";
1089     std::string source_filename = "source.pa";
1090     auto item = par.Parse(source, source_filename);
1091     EXPECT_EQ(par.ShowError().err, Error::ErrorType::ERR_NONE);
1092 
1093     EXPECT_EQ(item.Value().record_table.at("Asm1").name, "Asm1");
1094     EXPECT_EQ(item.Value().record_table.at("Asm1").field_list[0].name, "asm1");
1095     EXPECT_EQ(item.Value().record_table.at("Asm1").field_list[0].type.GetId(), panda::panda_file::Type::TypeId::I64);
1096     EXPECT_EQ(item.Value().record_table.at("Asm1").field_list[1].name, "asm2");
1097     EXPECT_EQ(item.Value().record_table.at("Asm1").field_list[1].type.GetId(), panda::panda_file::Type::TypeId::VOID);
1098     EXPECT_EQ(item.Value().record_table.at("Asm1").field_list[2].name, "asm3");
1099     EXPECT_EQ(item.Value().record_table.at("Asm1").field_list[2].type.GetId(), panda::panda_file::Type::TypeId::I32);
1100 
1101     auto pf = AsmEmitter::Emit(item.Value());
1102     EXPECT_NE(pf, nullptr);
1103 }
1104 
1105 /**
1106  * @tc.name: assembly_emitter_test_018
1107  * @tc.desc: Verify the AsmEmitter::Emit function.
1108  * @tc.type: FUNC
1109  * @tc.require: issueNumber
1110  */
1111 HWTEST_F(AssemblyEmitterTest, assembly_emitter_test_018, TestSize.Level1)
1112 {
1113     Parser par;
1114     auto source = R"(
1115         .function any f(i8 a0) {
1116             sta a0
1117         }
1118     )";
1119     std::string source_filename = "source.pa";
1120     AsmEmitter::PandaFileToPandaAsmMaps *maps = nullptr;
1121     auto items = panda::panda_file::ItemContainer {};
1122     auto program = par.Parse(source, source_filename);
1123     program.Value().function_table.at("f:(i8)").metadata->SetAttribute("external");
1124     EXPECT_EQ(par.ShowError().err, Error::ErrorType::ERR_NONE);
1125     auto pf = AsmEmitter::Emit(&items, program.Value(), maps, false);
1126     EXPECT_EQ(pf, true);
1127 }
1128 
1129 /**
1130  * @tc.name: assembly_emitter_test_019
1131  * @tc.desc: Verify the AsmEmitter::Emit function.
1132  * @tc.type: FUNC
1133  * @tc.require: issueNumber
1134  */
1135 HWTEST_F(AssemblyEmitterTest, assembly_emitter_test_019, TestSize.Level1)
1136 {
1137     Parser par;
1138     auto source = R"(
1139         .function any f(i8 a0) {
1140             sta a0
1141         }
1142     )";
1143     std::string source_filename = "source.pa";
1144 
1145     auto program = par.Parse(source, source_filename);
1146     program.Value().function_table.at("f:(i8)").metadata->SetAttribute("external");
1147     panda::pandasm::debuginfo::LocalVariable local;
1148     local.name = "test";
1149     local.signature = "test";
1150     local.signature_type = "test";
1151     program.Value().function_table.at("f:(i8)").local_variable_debug.push_back(local);
1152     EXPECT_EQ(par.ShowError().err, Error::ErrorType::ERR_NONE);
1153     auto success = AsmEmitter::Emit(program.Value());
1154     EXPECT_NE(success, nullptr);
1155 }
1156 
1157 /**
1158  * @tc.name: assembly_emitter_test_020
1159  * @tc.desc: Verify the EmitPrograms function.
1160  * @tc.type: FUNC
1161  * @tc.require: issueNumber
1162  */
1163 HWTEST_F(AssemblyEmitterTest, assembly_emitter_test_020, TestSize.Level1)
1164 {
1165     Parser p1;
1166     auto source1 = R"(
1167         .record Test {
1168             any foo
1169         }
1170     )";
1171     Parser p2;
1172     auto source2 = R"(
1173         .function void main() {
1174             ldai 0
1175             ldai 1
1176             return
1177         }
1178     )";
1179     auto res1 = p1.Parse(source1);
1180     EXPECT_EQ(p1.ShowError().err, Error::ErrorType::ERR_NONE);
1181 
1182     auto res2 = p2.Parse(source2);
1183     EXPECT_EQ(p2.ShowError().err, Error::ErrorType::ERR_NONE);
1184 
1185     std::vector<Program *> progs;
1186     progs.push_back(&res1.Value());
1187     progs.push_back(&res2.Value());
1188     const std::string filename = "source.pa";;
1189     auto success = AsmEmitter::EmitPrograms(filename, progs, true);
1190     EXPECT_TRUE(success);
1191 }
1192 
1193 /**
1194  * @tc.name: assembly_emitter_test_021
1195  * @tc.desc: Verify the AsmEmitter::EmitPrograms function with different API version.
1196  * @tc.type: FUNC
1197  * @tc.require: issueNumber
1198  */
1199 HWTEST_F(AssemblyEmitterTest, assembly_emitter_test_021, TestSize.Level1)
1200 {
1201     Parser p;
1202     auto source = R"(
1203         .function any foo(any a0) <noimpl>
1204     )";
1205 
1206     // api 11
1207     {
1208         auto res = p.Parse(source);
1209         EXPECT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
1210 
1211         std::vector<Program *> progs;
1212         progs.push_back(&res.Value());
1213 
1214         std::string descriptor;
1215         const std::string filename_api11 = "source_021_api11.abc";
1216         auto is_emitted = AsmEmitter::EmitPrograms(filename_api11, progs, false, 11);
1217         EXPECT_TRUE(is_emitted);
1218         auto pf = panda_file::OpenPandaFile(filename_api11);
1219         EXPECT_NE(pf, nullptr);
1220 
1221         auto class_id = pf->GetClassId(GetTypeDescriptor("_GLOBAL", &descriptor));
1222         EXPECT_TRUE(class_id.IsValid());
1223 
1224         panda_file::ClassDataAccessor cda(*pf, class_id);
1225 
1226         EXPECT_FALSE(cda.GetSourceLang());
1227 
1228         const auto tagged = panda_file::Type(panda_file::Type::TypeId::TAGGED);
__anon4b9ec5e21302(panda_file::MethodDataAccessor &mda) 1229         cda.EnumerateMethods([&](panda_file::MethodDataAccessor &mda) {
1230             EXPECT_NE(mda.GetProtoIdx(), panda_file::INVALID_INDEX_16);
1231             panda_file::ProtoDataAccessor pda(*pf, mda.GetProtoId());
1232             EXPECT_EQ(tagged, pda.GetReturnType());
1233             EXPECT_EQ(1u, pda.GetNumArgs());
1234             EXPECT_EQ(tagged, pda.GetArgType(0));
1235         });
1236     }
1237 
1238     // api 12
1239     {
1240         auto res = p.Parse(source);
1241         EXPECT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
1242 
1243         std::vector<Program *> progs;
1244         progs.push_back(&res.Value());
1245 
1246         std::string descriptor;
1247         const std::string filename_api12 = "source_021_api12.abc";
1248         auto is_emitted = AsmEmitter::EmitPrograms(filename_api12, progs, false, 12);
1249         EXPECT_TRUE(is_emitted);
1250         auto pf = panda_file::OpenPandaFile(filename_api12);
1251         EXPECT_NE(pf, nullptr);
1252 
1253         auto class_id = pf->GetClassId(GetTypeDescriptor("_GLOBAL", &descriptor));
1254         EXPECT_TRUE(class_id.IsValid());
1255 
1256         panda_file::ClassDataAccessor cda(*pf, class_id);
1257 
1258         EXPECT_FALSE(cda.GetSourceLang());
1259 
__anon4b9ec5e21402(panda_file::MethodDataAccessor &mda) 1260         cda.EnumerateMethods([&](panda_file::MethodDataAccessor &mda) {
1261             EXPECT_EQ(mda.GetProtoIdx(), panda_file::INVALID_INDEX_16);
1262         });
1263     }
1264 }
1265 
1266 /**
1267  * @tc.name: assembly_emitter_test_022
1268  * @tc.desc: Verify the AsmEmitter::Emit function with different API version.
1269  * @tc.type: FUNC
1270  * @tc.require: issueNumber
1271  */
1272 HWTEST_F(AssemblyEmitterTest, assembly_emitter_test_022, TestSize.Level1)
1273 {
1274     Parser p;
1275     auto source = R"(
1276         .function any foo(any a0) <noimpl>
1277     )";
1278     auto res = p.Parse(source);
1279     EXPECT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
1280 
1281     // api 11
1282     {
1283         std::string descriptor;
1284         const std::string filename_api11 = "source_022_api11.abc";
1285         auto writer = panda_file::FileWriter(filename_api11);
1286         auto is_emitted = AsmEmitter::Emit(&writer, res.Value(), nullptr, nullptr, false, nullptr, 11);
1287         EXPECT_TRUE(is_emitted);
1288         auto pf = panda_file::OpenPandaFile(filename_api11);
1289         EXPECT_NE(pf, nullptr);
1290 
1291         auto class_id = pf->GetClassId(GetTypeDescriptor("_GLOBAL", &descriptor));
1292         EXPECT_TRUE(class_id.IsValid());
1293 
1294         panda_file::ClassDataAccessor cda(*pf, class_id);
1295 
1296         EXPECT_FALSE(cda.GetSourceLang());
1297 
1298         const auto tagged = panda_file::Type(panda_file::Type::TypeId::TAGGED);
__anon4b9ec5e21502(panda_file::MethodDataAccessor &mda) 1299         cda.EnumerateMethods([&](panda_file::MethodDataAccessor &mda) {
1300             EXPECT_NE(mda.GetProtoIdx(), panda_file::INVALID_INDEX_16);
1301             panda_file::ProtoDataAccessor pda(*pf, mda.GetProtoId());
1302             EXPECT_EQ(tagged, pda.GetReturnType());
1303             EXPECT_EQ(1u, pda.GetNumArgs());
1304             EXPECT_EQ(tagged, pda.GetArgType(0));
1305         });
1306     }
1307 
1308     // api 12
1309     {
1310         std::string descriptor;
1311         const std::string filename_api12 = "source_022_api12.abc";
1312         auto writer = panda_file::FileWriter(filename_api12);
1313         auto is_emitted = AsmEmitter::Emit(&writer, res.Value(), nullptr, nullptr, false, nullptr, 12);
1314         EXPECT_TRUE(is_emitted);
1315         auto pf = panda_file::OpenPandaFile(filename_api12);
1316         EXPECT_NE(pf, nullptr);
1317 
1318         auto class_id = pf->GetClassId(GetTypeDescriptor("_GLOBAL", &descriptor));
1319         EXPECT_TRUE(class_id.IsValid());
1320 
1321         panda_file::ClassDataAccessor cda(*pf, class_id);
1322 
1323         EXPECT_FALSE(cda.GetSourceLang());
1324 
__anon4b9ec5e21602(panda_file::MethodDataAccessor &mda) 1325         cda.EnumerateMethods([&](panda_file::MethodDataAccessor &mda) {
1326             EXPECT_EQ(mda.GetProtoIdx(), panda_file::INVALID_INDEX_16);
1327         });
1328     }
1329 }
1330 
1331 /**
1332  * @tc.name: assembly_emitter_test_023
1333  * @tc.desc: Verify the AsmEmitter::Emit function with different API version.
1334  * @tc.type: FUNC
1335  * @tc.require: issueNumber
1336  */
1337 HWTEST_F(AssemblyEmitterTest, assembly_emitter_test_023, TestSize.Level1)
1338 {
1339     Parser p;
1340     auto source = R"(
1341         .function any foo(any a0) <noimpl>
1342     )";
1343 
1344     auto res = p.Parse(source);
1345     EXPECT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
1346 
1347     // api 11
1348     {
1349         std::string descriptor;
1350         auto pf = AsmEmitter::Emit(res.Value(), nullptr, 11);
1351         EXPECT_NE(pf, nullptr);
1352 
1353         auto class_id = pf->GetClassId(GetTypeDescriptor("_GLOBAL", &descriptor));
1354         EXPECT_TRUE(class_id.IsValid());
1355 
1356         panda_file::ClassDataAccessor cda(*pf, class_id);
1357 
1358         EXPECT_FALSE(cda.GetSourceLang());
1359 
1360         const auto tagged = panda_file::Type(panda_file::Type::TypeId::TAGGED);
__anon4b9ec5e21702(panda_file::MethodDataAccessor &mda) 1361         cda.EnumerateMethods([&](panda_file::MethodDataAccessor &mda) {
1362             EXPECT_NE(mda.GetProtoIdx(), panda_file::INVALID_INDEX_16);
1363             panda_file::ProtoDataAccessor pda(*pf, mda.GetProtoId());
1364             EXPECT_EQ(tagged, pda.GetReturnType());
1365             EXPECT_EQ(1u, pda.GetNumArgs());
1366             EXPECT_EQ(tagged, pda.GetArgType(0));
1367         });
1368     }
1369 
1370     // api 12
1371     {
1372         std::string descriptor;
1373         auto pf = AsmEmitter::Emit(res.Value(), nullptr, 12);
1374         EXPECT_NE(pf, nullptr);
1375 
1376         auto class_id = pf->GetClassId(GetTypeDescriptor("_GLOBAL", &descriptor));
1377         EXPECT_TRUE(class_id.IsValid());
1378 
1379         panda_file::ClassDataAccessor cda(*pf, class_id);
1380 
1381         EXPECT_FALSE(cda.GetSourceLang());
1382 
__anon4b9ec5e21802(panda_file::MethodDataAccessor &mda) 1383         cda.EnumerateMethods([&](panda_file::MethodDataAccessor &mda) {
1384             EXPECT_EQ(mda.GetProtoIdx(), panda_file::INVALID_INDEX_16);
1385         });
1386     }
1387 }
1388 
1389 /**
1390  * @tc.name: assembly_emitter_test_024
1391  * @tc.desc: Verify the AsmEmitter::Emit Handle Same Record.
1392  * @tc.type: FUNC
1393  * @tc.require: I9OWSZ
1394  */
1395 HWTEST_F(AssemblyEmitterTest, assembly_emitter_test_024, TestSize.Level1)
1396 {
1397     Parser p1;
1398     auto source1 = R"(
1399         .record Rec {
1400             u8 rec <value=0>
1401         }
1402     )";
1403     Parser p2;
1404     auto source2 = R"(
1405         .record Rec {
1406             u8 rec <value=0>
1407         }
1408     )";
1409     auto res1 = p1.Parse(source1);
1410     EXPECT_EQ(p1.ShowError().err, Error::ErrorType::ERR_NONE);
1411 
1412     auto res2 = p2.Parse(source2);
1413     EXPECT_EQ(p2.ShowError().err, Error::ErrorType::ERR_NONE);
1414 
1415     std::vector<Program *> progs;
1416     progs.push_back(&res1.Value());
1417     progs.push_back(&res2.Value());
1418     const std::string filename = "source.pa";;
1419     auto pf = AsmEmitter::EmitPrograms(filename, progs, false);
1420     EXPECT_TRUE(pf);
1421 }
1422 
1423 /**
1424  * @tc.name: assembly_emitter_test_025
1425  * @tc.desc: Verify the AsmEmitter::Emit Handle Same Record.
1426  * @tc.type: FUNC
1427  * @tc.require: I9OWSZ
1428  */
1429 HWTEST_F(AssemblyEmitterTest, assembly_emitter_test_025, TestSize.Level1)
1430 {
1431     Parser p1;
1432     auto source1 = R"(
1433         .record Rec {
1434             u8 rec <value=0>
1435         }
1436     )";
1437     Parser p2;
1438     auto source2 = R"(
1439         .record Rec {
1440             u8 rec <value=1>
1441         }
1442     )";
1443     auto res1 = p1.Parse(source1);
1444     EXPECT_EQ(p1.ShowError().err, Error::ErrorType::ERR_NONE);
1445 
1446     auto res2 = p2.Parse(source2);
1447     EXPECT_EQ(p2.ShowError().err, Error::ErrorType::ERR_NONE);
1448 
1449     std::vector<Program *> progs;
1450     progs.push_back(&res1.Value());
1451     progs.push_back(&res2.Value());
1452     const std::string filename = "source.pa";;
1453     auto pf = AsmEmitter::EmitPrograms(filename, progs, false);
1454     EXPECT_FALSE(pf);
1455     EXPECT_EQ(AsmEmitter::GetLastError(), "Field {Rec.rec} has different value.");
1456 }
1457 
1458 /**
1459  * @tc.name: assembly_emitter_test_026
1460  * @tc.desc: Verify the AsmEmitter::Emit Handle Same Record.
1461  * @tc.type: FUNC
1462  * @tc.require: I9OWSZ
1463  */
1464 HWTEST_F(AssemblyEmitterTest, assembly_emitter_test_026, TestSize.Level1)
1465 {
1466     Parser p1;
1467     auto source1 = R"(
1468         .record Rec {
1469             u8 rec1 <value=0>
1470         }
1471     )";
1472     Parser p2;
1473     auto source2 = R"(
1474         .record Rec {
1475             u8 rec2 <value=0>
1476         }
1477     )";
1478     auto res1 = p1.Parse(source1);
1479     EXPECT_EQ(p1.ShowError().err, Error::ErrorType::ERR_NONE);
1480 
1481     auto res2 = p2.Parse(source2);
1482     EXPECT_EQ(p2.ShowError().err, Error::ErrorType::ERR_NONE);
1483 
1484     std::vector<Program *> progs;
1485     progs.push_back(&res1.Value());
1486     progs.push_back(&res2.Value());
1487     const std::string filename = "source.pa";;
1488     auto pf = AsmEmitter::EmitPrograms(filename, progs, false);
1489     EXPECT_TRUE(pf);
1490 }
1491 }