Home | History | Annotate | Download | only in ObjectYAML
      1 //===- WasmYAML.cpp - Wasm YAMLIO implementation --------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file defines classes for handling the YAML representation of wasm.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "llvm/ObjectYAML/WasmYAML.h"
     15 #include "llvm/ADT/StringRef.h"
     16 #include "llvm/Support/Casting.h"
     17 #include "llvm/Support/ErrorHandling.h"
     18 #include "llvm/Support/YAMLTraits.h"
     19 
     20 namespace llvm {
     21 
     22 namespace WasmYAML {
     23 
     24 // Declared here rather than in the header to comply with:
     25 // http://llvm.org/docs/CodingStandards.html#provide-a-virtual-method-anchor-for-classes-in-headers
     26 Section::~Section() = default;
     27 
     28 } // end namespace WasmYAML
     29 
     30 namespace yaml {
     31 
     32 void MappingTraits<WasmYAML::FileHeader>::mapping(
     33     IO &IO, WasmYAML::FileHeader &FileHdr) {
     34   IO.mapRequired("Version", FileHdr.Version);
     35 }
     36 
     37 void MappingTraits<WasmYAML::Object>::mapping(IO &IO,
     38                                               WasmYAML::Object &Object) {
     39   IO.setContext(&Object);
     40   IO.mapTag("!WASM", true);
     41   IO.mapRequired("FileHeader", Object.Header);
     42   IO.mapOptional("Sections", Object.Sections);
     43   IO.setContext(nullptr);
     44 }
     45 
     46 static void commonSectionMapping(IO &IO, WasmYAML::Section &Section) {
     47   IO.mapRequired("Type", Section.Type);
     48   IO.mapOptional("Relocations", Section.Relocations);
     49 }
     50 
     51 static void sectionMapping(IO &IO, WasmYAML::NameSection &Section) {
     52   commonSectionMapping(IO, Section);
     53   IO.mapRequired("Name", Section.Name);
     54   IO.mapOptional("FunctionNames", Section.FunctionNames);
     55 }
     56 
     57 static void sectionMapping(IO &IO, WasmYAML::LinkingSection &Section) {
     58   commonSectionMapping(IO, Section);
     59   IO.mapRequired("Name", Section.Name);
     60   IO.mapRequired("Version", Section.Version);
     61   IO.mapOptional("SymbolTable", Section.SymbolTable);
     62   IO.mapOptional("SegmentInfo", Section.SegmentInfos);
     63   IO.mapOptional("InitFunctions", Section.InitFunctions);
     64   IO.mapOptional("Comdats", Section.Comdats);
     65 }
     66 
     67 static void sectionMapping(IO &IO, WasmYAML::CustomSection &Section) {
     68   commonSectionMapping(IO, Section);
     69   IO.mapRequired("Name", Section.Name);
     70   IO.mapRequired("Payload", Section.Payload);
     71 }
     72 
     73 static void sectionMapping(IO &IO, WasmYAML::TypeSection &Section) {
     74   commonSectionMapping(IO, Section);
     75   IO.mapOptional("Signatures", Section.Signatures);
     76 }
     77 
     78 static void sectionMapping(IO &IO, WasmYAML::ImportSection &Section) {
     79   commonSectionMapping(IO, Section);
     80   IO.mapOptional("Imports", Section.Imports);
     81 }
     82 
     83 static void sectionMapping(IO &IO, WasmYAML::FunctionSection &Section) {
     84   commonSectionMapping(IO, Section);
     85   IO.mapOptional("FunctionTypes", Section.FunctionTypes);
     86 }
     87 
     88 static void sectionMapping(IO &IO, WasmYAML::TableSection &Section) {
     89   commonSectionMapping(IO, Section);
     90   IO.mapOptional("Tables", Section.Tables);
     91 }
     92 
     93 static void sectionMapping(IO &IO, WasmYAML::MemorySection &Section) {
     94   commonSectionMapping(IO, Section);
     95   IO.mapOptional("Memories", Section.Memories);
     96 }
     97 
     98 static void sectionMapping(IO &IO, WasmYAML::GlobalSection &Section) {
     99   commonSectionMapping(IO, Section);
    100   IO.mapOptional("Globals", Section.Globals);
    101 }
    102 
    103 static void sectionMapping(IO &IO, WasmYAML::ExportSection &Section) {
    104   commonSectionMapping(IO, Section);
    105   IO.mapOptional("Exports", Section.Exports);
    106 }
    107 
    108 static void sectionMapping(IO &IO, WasmYAML::StartSection &Section) {
    109   commonSectionMapping(IO, Section);
    110   IO.mapOptional("StartFunction", Section.StartFunction);
    111 }
    112 
    113 static void sectionMapping(IO &IO, WasmYAML::ElemSection &Section) {
    114   commonSectionMapping(IO, Section);
    115   IO.mapOptional("Segments", Section.Segments);
    116 }
    117 
    118 static void sectionMapping(IO &IO, WasmYAML::CodeSection &Section) {
    119   commonSectionMapping(IO, Section);
    120   IO.mapRequired("Functions", Section.Functions);
    121 }
    122 
    123 static void sectionMapping(IO &IO, WasmYAML::DataSection &Section) {
    124   commonSectionMapping(IO, Section);
    125   IO.mapRequired("Segments", Section.Segments);
    126 }
    127 
    128 void MappingTraits<std::unique_ptr<WasmYAML::Section>>::mapping(
    129     IO &IO, std::unique_ptr<WasmYAML::Section> &Section) {
    130   WasmYAML::SectionType SectionType;
    131   if (IO.outputting())
    132     SectionType = Section->Type;
    133   else
    134     IO.mapRequired("Type", SectionType);
    135 
    136   switch (SectionType) {
    137   case wasm::WASM_SEC_CUSTOM: {
    138     StringRef SectionName;
    139     if (IO.outputting()) {
    140       auto CustomSection = cast<WasmYAML::CustomSection>(Section.get());
    141       SectionName = CustomSection->Name;
    142     } else {
    143       IO.mapRequired("Name", SectionName);
    144     }
    145     if (SectionName == "linking") {
    146       if (!IO.outputting())
    147         Section.reset(new WasmYAML::LinkingSection());
    148       sectionMapping(IO, *cast<WasmYAML::LinkingSection>(Section.get()));
    149     } else if (SectionName == "name") {
    150       if (!IO.outputting())
    151         Section.reset(new WasmYAML::NameSection());
    152       sectionMapping(IO, *cast<WasmYAML::NameSection>(Section.get()));
    153     } else {
    154       if (!IO.outputting())
    155         Section.reset(new WasmYAML::CustomSection(SectionName));
    156       sectionMapping(IO, *cast<WasmYAML::CustomSection>(Section.get()));
    157     }
    158     break;
    159   }
    160   case wasm::WASM_SEC_TYPE:
    161     if (!IO.outputting())
    162       Section.reset(new WasmYAML::TypeSection());
    163     sectionMapping(IO, *cast<WasmYAML::TypeSection>(Section.get()));
    164     break;
    165   case wasm::WASM_SEC_IMPORT:
    166     if (!IO.outputting())
    167       Section.reset(new WasmYAML::ImportSection());
    168     sectionMapping(IO, *cast<WasmYAML::ImportSection>(Section.get()));
    169     break;
    170   case wasm::WASM_SEC_FUNCTION:
    171     if (!IO.outputting())
    172       Section.reset(new WasmYAML::FunctionSection());
    173     sectionMapping(IO, *cast<WasmYAML::FunctionSection>(Section.get()));
    174     break;
    175   case wasm::WASM_SEC_TABLE:
    176     if (!IO.outputting())
    177       Section.reset(new WasmYAML::TableSection());
    178     sectionMapping(IO, *cast<WasmYAML::TableSection>(Section.get()));
    179     break;
    180   case wasm::WASM_SEC_MEMORY:
    181     if (!IO.outputting())
    182       Section.reset(new WasmYAML::MemorySection());
    183     sectionMapping(IO, *cast<WasmYAML::MemorySection>(Section.get()));
    184     break;
    185   case wasm::WASM_SEC_GLOBAL:
    186     if (!IO.outputting())
    187       Section.reset(new WasmYAML::GlobalSection());
    188     sectionMapping(IO, *cast<WasmYAML::GlobalSection>(Section.get()));
    189     break;
    190   case wasm::WASM_SEC_EXPORT:
    191     if (!IO.outputting())
    192       Section.reset(new WasmYAML::ExportSection());
    193     sectionMapping(IO, *cast<WasmYAML::ExportSection>(Section.get()));
    194     break;
    195   case wasm::WASM_SEC_START:
    196     if (!IO.outputting())
    197       Section.reset(new WasmYAML::StartSection());
    198     sectionMapping(IO, *cast<WasmYAML::StartSection>(Section.get()));
    199     break;
    200   case wasm::WASM_SEC_ELEM:
    201     if (!IO.outputting())
    202       Section.reset(new WasmYAML::ElemSection());
    203     sectionMapping(IO, *cast<WasmYAML::ElemSection>(Section.get()));
    204     break;
    205   case wasm::WASM_SEC_CODE:
    206     if (!IO.outputting())
    207       Section.reset(new WasmYAML::CodeSection());
    208     sectionMapping(IO, *cast<WasmYAML::CodeSection>(Section.get()));
    209     break;
    210   case wasm::WASM_SEC_DATA:
    211     if (!IO.outputting())
    212       Section.reset(new WasmYAML::DataSection());
    213     sectionMapping(IO, *cast<WasmYAML::DataSection>(Section.get()));
    214     break;
    215   default:
    216     llvm_unreachable("Unknown section type");
    217   }
    218 }
    219 
    220 void ScalarEnumerationTraits<WasmYAML::SectionType>::enumeration(
    221     IO &IO, WasmYAML::SectionType &Type) {
    222 #define ECase(X) IO.enumCase(Type, #X, wasm::WASM_SEC_##X);
    223   ECase(CUSTOM);
    224   ECase(TYPE);
    225   ECase(IMPORT);
    226   ECase(FUNCTION);
    227   ECase(TABLE);
    228   ECase(MEMORY);
    229   ECase(GLOBAL);
    230   ECase(EXPORT);
    231   ECase(START);
    232   ECase(ELEM);
    233   ECase(CODE);
    234   ECase(DATA);
    235 #undef ECase
    236 }
    237 
    238 void MappingTraits<WasmYAML::Signature>::mapping(
    239     IO &IO, WasmYAML::Signature &Signature) {
    240   IO.mapRequired("Index", Signature.Index);
    241   IO.mapRequired("ReturnType", Signature.ReturnType);
    242   IO.mapRequired("ParamTypes", Signature.ParamTypes);
    243 }
    244 
    245 void MappingTraits<WasmYAML::Table>::mapping(IO &IO, WasmYAML::Table &Table) {
    246   IO.mapRequired("ElemType", Table.ElemType);
    247   IO.mapRequired("Limits", Table.TableLimits);
    248 }
    249 
    250 void MappingTraits<WasmYAML::Function>::mapping(IO &IO,
    251                                                 WasmYAML::Function &Function) {
    252   IO.mapRequired("Index", Function.Index);
    253   IO.mapRequired("Locals", Function.Locals);
    254   IO.mapRequired("Body", Function.Body);
    255 }
    256 
    257 void MappingTraits<WasmYAML::Relocation>::mapping(
    258     IO &IO, WasmYAML::Relocation &Relocation) {
    259   IO.mapRequired("Type", Relocation.Type);
    260   IO.mapRequired("Index", Relocation.Index);
    261   IO.mapRequired("Offset", Relocation.Offset);
    262   IO.mapOptional("Addend", Relocation.Addend, 0);
    263 }
    264 
    265 void MappingTraits<WasmYAML::NameEntry>::mapping(
    266     IO &IO, WasmYAML::NameEntry &NameEntry) {
    267   IO.mapRequired("Index", NameEntry.Index);
    268   IO.mapRequired("Name", NameEntry.Name);
    269 }
    270 
    271 void MappingTraits<WasmYAML::SegmentInfo>::mapping(
    272     IO &IO, WasmYAML::SegmentInfo &SegmentInfo) {
    273   IO.mapRequired("Index", SegmentInfo.Index);
    274   IO.mapRequired("Name", SegmentInfo.Name);
    275   IO.mapRequired("Alignment", SegmentInfo.Alignment);
    276   IO.mapRequired("Flags", SegmentInfo.Flags);
    277 }
    278 
    279 void MappingTraits<WasmYAML::LocalDecl>::mapping(
    280     IO &IO, WasmYAML::LocalDecl &LocalDecl) {
    281   IO.mapRequired("Type", LocalDecl.Type);
    282   IO.mapRequired("Count", LocalDecl.Count);
    283 }
    284 
    285 void MappingTraits<WasmYAML::Limits>::mapping(IO &IO,
    286                                               WasmYAML::Limits &Limits) {
    287   if (!IO.outputting() || Limits.Flags)
    288     IO.mapOptional("Flags", Limits.Flags);
    289   IO.mapRequired("Initial", Limits.Initial);
    290   if (!IO.outputting() || Limits.Flags & wasm::WASM_LIMITS_FLAG_HAS_MAX)
    291     IO.mapOptional("Maximum", Limits.Maximum);
    292 }
    293 
    294 void MappingTraits<WasmYAML::ElemSegment>::mapping(
    295     IO &IO, WasmYAML::ElemSegment &Segment) {
    296   IO.mapRequired("Offset", Segment.Offset);
    297   IO.mapRequired("Functions", Segment.Functions);
    298 }
    299 
    300 void MappingTraits<WasmYAML::Import>::mapping(IO &IO,
    301                                               WasmYAML::Import &Import) {
    302   IO.mapRequired("Module", Import.Module);
    303   IO.mapRequired("Field", Import.Field);
    304   IO.mapRequired("Kind", Import.Kind);
    305   if (Import.Kind == wasm::WASM_EXTERNAL_FUNCTION) {
    306     IO.mapRequired("SigIndex", Import.SigIndex);
    307   } else if (Import.Kind == wasm::WASM_EXTERNAL_GLOBAL) {
    308     IO.mapRequired("GlobalType", Import.GlobalImport.Type);
    309     IO.mapRequired("GlobalMutable", Import.GlobalImport.Mutable);
    310   } else if (Import.Kind == wasm::WASM_EXTERNAL_TABLE) {
    311     IO.mapRequired("Table", Import.TableImport);
    312   } else if (Import.Kind == wasm::WASM_EXTERNAL_MEMORY ) {
    313     IO.mapRequired("Memory", Import.Memory);
    314   } else {
    315     llvm_unreachable("unhandled import type");
    316   }
    317 }
    318 
    319 void MappingTraits<WasmYAML::Export>::mapping(IO &IO,
    320                                               WasmYAML::Export &Export) {
    321   IO.mapRequired("Name", Export.Name);
    322   IO.mapRequired("Kind", Export.Kind);
    323   IO.mapRequired("Index", Export.Index);
    324 }
    325 
    326 void MappingTraits<WasmYAML::Global>::mapping(IO &IO,
    327                                               WasmYAML::Global &Global) {
    328   IO.mapRequired("Index", Global.Index);
    329   IO.mapRequired("Type", Global.Type);
    330   IO.mapRequired("Mutable", Global.Mutable);
    331   IO.mapRequired("InitExpr", Global.InitExpr);
    332 }
    333 
    334 void MappingTraits<wasm::WasmInitExpr>::mapping(IO &IO,
    335                                                 wasm::WasmInitExpr &Expr) {
    336   WasmYAML::Opcode Op = Expr.Opcode;
    337   IO.mapRequired("Opcode", Op);
    338   Expr.Opcode = Op;
    339   switch (Expr.Opcode) {
    340   case wasm::WASM_OPCODE_I32_CONST:
    341     IO.mapRequired("Value", Expr.Value.Int32);
    342     break;
    343   case wasm::WASM_OPCODE_I64_CONST:
    344     IO.mapRequired("Value", Expr.Value.Int64);
    345     break;
    346   case wasm::WASM_OPCODE_F32_CONST:
    347     IO.mapRequired("Value", Expr.Value.Float32);
    348     break;
    349   case wasm::WASM_OPCODE_F64_CONST:
    350     IO.mapRequired("Value", Expr.Value.Float64);
    351     break;
    352   case wasm::WASM_OPCODE_GET_GLOBAL:
    353     IO.mapRequired("Index", Expr.Value.Global);
    354     break;
    355   }
    356 }
    357 
    358 void MappingTraits<WasmYAML::DataSegment>::mapping(
    359     IO &IO, WasmYAML::DataSegment &Segment) {
    360   IO.mapOptional("SectionOffset", Segment.SectionOffset);
    361   IO.mapRequired("MemoryIndex", Segment.MemoryIndex);
    362   IO.mapRequired("Offset", Segment.Offset);
    363   IO.mapRequired("Content", Segment.Content);
    364 }
    365 
    366 void MappingTraits<WasmYAML::InitFunction>::mapping(
    367     IO &IO, WasmYAML::InitFunction &Init) {
    368   IO.mapRequired("Priority", Init.Priority);
    369   IO.mapRequired("Symbol", Init.Symbol);
    370 }
    371 
    372 void ScalarEnumerationTraits<WasmYAML::ComdatKind>::enumeration(
    373     IO &IO, WasmYAML::ComdatKind &Kind) {
    374 #define ECase(X) IO.enumCase(Kind, #X, wasm::WASM_COMDAT_##X);
    375   ECase(FUNCTION);
    376   ECase(DATA);
    377 #undef ECase
    378 }
    379 
    380 void MappingTraits<WasmYAML::ComdatEntry>::mapping(
    381     IO &IO, WasmYAML::ComdatEntry &ComdatEntry) {
    382   IO.mapRequired("Kind", ComdatEntry.Kind);
    383   IO.mapRequired("Index", ComdatEntry.Index);
    384 }
    385 
    386 void MappingTraits<WasmYAML::Comdat>::mapping(
    387     IO &IO, WasmYAML::Comdat &Comdat) {
    388   IO.mapRequired("Name", Comdat.Name);
    389   IO.mapRequired("Entries", Comdat.Entries);
    390 }
    391 
    392 void MappingTraits<WasmYAML::SymbolInfo>::mapping(IO &IO,
    393                                                   WasmYAML::SymbolInfo &Info) {
    394   IO.mapRequired("Index", Info.Index);
    395   IO.mapRequired("Kind", Info.Kind);
    396   IO.mapRequired("Name", Info.Name);
    397   IO.mapRequired("Flags", Info.Flags);
    398   if (Info.Kind == wasm::WASM_SYMBOL_TYPE_FUNCTION) {
    399     IO.mapRequired("Function", Info.ElementIndex);
    400   } else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_GLOBAL) {
    401     IO.mapRequired("Global", Info.ElementIndex);
    402   } else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_DATA) {
    403     if ((Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0) {
    404       IO.mapRequired("Segment", Info.DataRef.Segment);
    405       IO.mapOptional("Offset", Info.DataRef.Offset, 0u);
    406       IO.mapRequired("Size", Info.DataRef.Size);
    407     }
    408   } else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_SECTION) {
    409     IO.mapRequired("Section", Info.ElementIndex);
    410   } else {
    411     llvm_unreachable("unsupported symbol kind");
    412   }
    413 }
    414 
    415 void ScalarBitSetTraits<WasmYAML::LimitFlags>::bitset(
    416     IO &IO, WasmYAML::LimitFlags &Value) {
    417 #define BCase(X) IO.bitSetCase(Value, #X, wasm::WASM_LIMITS_FLAG_##X)
    418   BCase(HAS_MAX);
    419 #undef BCase
    420 }
    421 
    422 void ScalarBitSetTraits<WasmYAML::SegmentFlags>::bitset(
    423     IO &IO, WasmYAML::SegmentFlags &Value) {
    424 }
    425 
    426 void ScalarBitSetTraits<WasmYAML::SymbolFlags>::bitset(
    427     IO &IO, WasmYAML::SymbolFlags &Value) {
    428 #define BCaseMask(M, X) IO.maskedBitSetCase(Value, #X, wasm::WASM_SYMBOL_##X, wasm::WASM_SYMBOL_##M)
    429   //BCaseMask(BINDING_MASK, BINDING_GLOBAL);
    430   BCaseMask(BINDING_MASK, BINDING_WEAK);
    431   BCaseMask(BINDING_MASK, BINDING_LOCAL);
    432   //BCaseMask(VISIBILITY_MASK, VISIBILITY_DEFAULT);
    433   BCaseMask(VISIBILITY_MASK, VISIBILITY_HIDDEN);
    434   BCaseMask(UNDEFINED, UNDEFINED);
    435 #undef BCaseMask
    436 }
    437 
    438 void ScalarEnumerationTraits<WasmYAML::SymbolKind>::enumeration(
    439     IO &IO, WasmYAML::SymbolKind &Kind) {
    440 #define ECase(X) IO.enumCase(Kind, #X, wasm::WASM_SYMBOL_TYPE_##X);
    441   ECase(FUNCTION);
    442   ECase(DATA);
    443   ECase(GLOBAL);
    444   ECase(SECTION);
    445 #undef ECase
    446 }
    447 
    448 void ScalarEnumerationTraits<WasmYAML::ValueType>::enumeration(
    449     IO &IO, WasmYAML::ValueType &Type) {
    450 #define ECase(X) IO.enumCase(Type, #X, wasm::WASM_TYPE_##X);
    451   ECase(I32);
    452   ECase(I64);
    453   ECase(F32);
    454   ECase(F64);
    455   ECase(ANYFUNC);
    456   ECase(FUNC);
    457   ECase(NORESULT);
    458 #undef ECase
    459 }
    460 
    461 void ScalarEnumerationTraits<WasmYAML::ExportKind>::enumeration(
    462     IO &IO, WasmYAML::ExportKind &Kind) {
    463 #define ECase(X) IO.enumCase(Kind, #X, wasm::WASM_EXTERNAL_##X);
    464   ECase(FUNCTION);
    465   ECase(TABLE);
    466   ECase(MEMORY);
    467   ECase(GLOBAL);
    468 #undef ECase
    469 }
    470 
    471 void ScalarEnumerationTraits<WasmYAML::Opcode>::enumeration(
    472     IO &IO, WasmYAML::Opcode &Code) {
    473 #define ECase(X) IO.enumCase(Code, #X, wasm::WASM_OPCODE_##X);
    474   ECase(END);
    475   ECase(I32_CONST);
    476   ECase(I64_CONST);
    477   ECase(F64_CONST);
    478   ECase(F32_CONST);
    479   ECase(GET_GLOBAL);
    480 #undef ECase
    481 }
    482 
    483 void ScalarEnumerationTraits<WasmYAML::TableType>::enumeration(
    484     IO &IO, WasmYAML::TableType &Type) {
    485 #define ECase(X) IO.enumCase(Type, #X, wasm::WASM_TYPE_##X);
    486   ECase(ANYFUNC);
    487 #undef ECase
    488 }
    489 
    490 void ScalarEnumerationTraits<WasmYAML::RelocType>::enumeration(
    491     IO &IO, WasmYAML::RelocType &Type) {
    492 #define WASM_RELOC(name, value) IO.enumCase(Type, #name, wasm::name);
    493 #include "llvm/BinaryFormat/WasmRelocs.def"
    494 #undef WASM_RELOC
    495 }
    496 
    497 } // end namespace yaml
    498 
    499 } // end namespace llvm
    500