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::DylinkSection &Section) { 52 commonSectionMapping(IO, Section); 53 IO.mapRequired("Name", Section.Name); 54 IO.mapRequired("MemorySize", Section.MemorySize); 55 IO.mapRequired("MemoryAlignment", Section.MemoryAlignment); 56 IO.mapRequired("TableSize", Section.TableSize); 57 IO.mapRequired("TableAlignment", Section.TableAlignment); 58 IO.mapRequired("Needed", Section.Needed); 59 } 60 61 static void sectionMapping(IO &IO, WasmYAML::NameSection &Section) { 62 commonSectionMapping(IO, Section); 63 IO.mapRequired("Name", Section.Name); 64 IO.mapOptional("FunctionNames", Section.FunctionNames); 65 } 66 67 static void sectionMapping(IO &IO, WasmYAML::LinkingSection &Section) { 68 commonSectionMapping(IO, Section); 69 IO.mapRequired("Name", Section.Name); 70 IO.mapRequired("Version", Section.Version); 71 IO.mapOptional("SymbolTable", Section.SymbolTable); 72 IO.mapOptional("SegmentInfo", Section.SegmentInfos); 73 IO.mapOptional("InitFunctions", Section.InitFunctions); 74 IO.mapOptional("Comdats", Section.Comdats); 75 } 76 77 static void sectionMapping(IO &IO, WasmYAML::CustomSection &Section) { 78 commonSectionMapping(IO, Section); 79 IO.mapRequired("Name", Section.Name); 80 IO.mapRequired("Payload", Section.Payload); 81 } 82 83 static void sectionMapping(IO &IO, WasmYAML::TypeSection &Section) { 84 commonSectionMapping(IO, Section); 85 IO.mapOptional("Signatures", Section.Signatures); 86 } 87 88 static void sectionMapping(IO &IO, WasmYAML::ImportSection &Section) { 89 commonSectionMapping(IO, Section); 90 IO.mapOptional("Imports", Section.Imports); 91 } 92 93 static void sectionMapping(IO &IO, WasmYAML::FunctionSection &Section) { 94 commonSectionMapping(IO, Section); 95 IO.mapOptional("FunctionTypes", Section.FunctionTypes); 96 } 97 98 static void sectionMapping(IO &IO, WasmYAML::TableSection &Section) { 99 commonSectionMapping(IO, Section); 100 IO.mapOptional("Tables", Section.Tables); 101 } 102 103 static void sectionMapping(IO &IO, WasmYAML::MemorySection &Section) { 104 commonSectionMapping(IO, Section); 105 IO.mapOptional("Memories", Section.Memories); 106 } 107 108 static void sectionMapping(IO &IO, WasmYAML::GlobalSection &Section) { 109 commonSectionMapping(IO, Section); 110 IO.mapOptional("Globals", Section.Globals); 111 } 112 113 static void sectionMapping(IO &IO, WasmYAML::EventSection &Section) { 114 commonSectionMapping(IO, Section); 115 IO.mapOptional("Events", Section.Events); 116 } 117 118 static void sectionMapping(IO &IO, WasmYAML::ExportSection &Section) { 119 commonSectionMapping(IO, Section); 120 IO.mapOptional("Exports", Section.Exports); 121 } 122 123 static void sectionMapping(IO &IO, WasmYAML::StartSection &Section) { 124 commonSectionMapping(IO, Section); 125 IO.mapOptional("StartFunction", Section.StartFunction); 126 } 127 128 static void sectionMapping(IO &IO, WasmYAML::ElemSection &Section) { 129 commonSectionMapping(IO, Section); 130 IO.mapOptional("Segments", Section.Segments); 131 } 132 133 static void sectionMapping(IO &IO, WasmYAML::CodeSection &Section) { 134 commonSectionMapping(IO, Section); 135 IO.mapRequired("Functions", Section.Functions); 136 } 137 138 static void sectionMapping(IO &IO, WasmYAML::DataSection &Section) { 139 commonSectionMapping(IO, Section); 140 IO.mapRequired("Segments", Section.Segments); 141 } 142 143 void MappingTraits<std::unique_ptr<WasmYAML::Section>>::mapping( 144 IO &IO, std::unique_ptr<WasmYAML::Section> &Section) { 145 WasmYAML::SectionType SectionType; 146 if (IO.outputting()) 147 SectionType = Section->Type; 148 else 149 IO.mapRequired("Type", SectionType); 150 151 switch (SectionType) { 152 case wasm::WASM_SEC_CUSTOM: { 153 StringRef SectionName; 154 if (IO.outputting()) { 155 auto CustomSection = cast<WasmYAML::CustomSection>(Section.get()); 156 SectionName = CustomSection->Name; 157 } else { 158 IO.mapRequired("Name", SectionName); 159 } 160 if (SectionName == "dylink") { 161 if (!IO.outputting()) 162 Section.reset(new WasmYAML::DylinkSection()); 163 sectionMapping(IO, *cast<WasmYAML::DylinkSection>(Section.get())); 164 } else if (SectionName == "linking") { 165 if (!IO.outputting()) 166 Section.reset(new WasmYAML::LinkingSection()); 167 sectionMapping(IO, *cast<WasmYAML::LinkingSection>(Section.get())); 168 } else if (SectionName == "name") { 169 if (!IO.outputting()) 170 Section.reset(new WasmYAML::NameSection()); 171 sectionMapping(IO, *cast<WasmYAML::NameSection>(Section.get())); 172 } else { 173 if (!IO.outputting()) 174 Section.reset(new WasmYAML::CustomSection(SectionName)); 175 sectionMapping(IO, *cast<WasmYAML::CustomSection>(Section.get())); 176 } 177 break; 178 } 179 case wasm::WASM_SEC_TYPE: 180 if (!IO.outputting()) 181 Section.reset(new WasmYAML::TypeSection()); 182 sectionMapping(IO, *cast<WasmYAML::TypeSection>(Section.get())); 183 break; 184 case wasm::WASM_SEC_IMPORT: 185 if (!IO.outputting()) 186 Section.reset(new WasmYAML::ImportSection()); 187 sectionMapping(IO, *cast<WasmYAML::ImportSection>(Section.get())); 188 break; 189 case wasm::WASM_SEC_FUNCTION: 190 if (!IO.outputting()) 191 Section.reset(new WasmYAML::FunctionSection()); 192 sectionMapping(IO, *cast<WasmYAML::FunctionSection>(Section.get())); 193 break; 194 case wasm::WASM_SEC_TABLE: 195 if (!IO.outputting()) 196 Section.reset(new WasmYAML::TableSection()); 197 sectionMapping(IO, *cast<WasmYAML::TableSection>(Section.get())); 198 break; 199 case wasm::WASM_SEC_MEMORY: 200 if (!IO.outputting()) 201 Section.reset(new WasmYAML::MemorySection()); 202 sectionMapping(IO, *cast<WasmYAML::MemorySection>(Section.get())); 203 break; 204 case wasm::WASM_SEC_GLOBAL: 205 if (!IO.outputting()) 206 Section.reset(new WasmYAML::GlobalSection()); 207 sectionMapping(IO, *cast<WasmYAML::GlobalSection>(Section.get())); 208 break; 209 case wasm::WASM_SEC_EVENT: 210 if (!IO.outputting()) 211 Section.reset(new WasmYAML::EventSection()); 212 sectionMapping(IO, *cast<WasmYAML::EventSection>(Section.get())); 213 break; 214 case wasm::WASM_SEC_EXPORT: 215 if (!IO.outputting()) 216 Section.reset(new WasmYAML::ExportSection()); 217 sectionMapping(IO, *cast<WasmYAML::ExportSection>(Section.get())); 218 break; 219 case wasm::WASM_SEC_START: 220 if (!IO.outputting()) 221 Section.reset(new WasmYAML::StartSection()); 222 sectionMapping(IO, *cast<WasmYAML::StartSection>(Section.get())); 223 break; 224 case wasm::WASM_SEC_ELEM: 225 if (!IO.outputting()) 226 Section.reset(new WasmYAML::ElemSection()); 227 sectionMapping(IO, *cast<WasmYAML::ElemSection>(Section.get())); 228 break; 229 case wasm::WASM_SEC_CODE: 230 if (!IO.outputting()) 231 Section.reset(new WasmYAML::CodeSection()); 232 sectionMapping(IO, *cast<WasmYAML::CodeSection>(Section.get())); 233 break; 234 case wasm::WASM_SEC_DATA: 235 if (!IO.outputting()) 236 Section.reset(new WasmYAML::DataSection()); 237 sectionMapping(IO, *cast<WasmYAML::DataSection>(Section.get())); 238 break; 239 default: 240 llvm_unreachable("Unknown section type"); 241 } 242 } 243 244 void ScalarEnumerationTraits<WasmYAML::SectionType>::enumeration( 245 IO &IO, WasmYAML::SectionType &Type) { 246 #define ECase(X) IO.enumCase(Type, #X, wasm::WASM_SEC_##X); 247 ECase(CUSTOM); 248 ECase(TYPE); 249 ECase(IMPORT); 250 ECase(FUNCTION); 251 ECase(TABLE); 252 ECase(MEMORY); 253 ECase(GLOBAL); 254 ECase(EVENT); 255 ECase(EXPORT); 256 ECase(START); 257 ECase(ELEM); 258 ECase(CODE); 259 ECase(DATA); 260 #undef ECase 261 } 262 263 void MappingTraits<WasmYAML::Signature>::mapping( 264 IO &IO, WasmYAML::Signature &Signature) { 265 IO.mapRequired("Index", Signature.Index); 266 IO.mapRequired("ReturnType", Signature.ReturnType); 267 IO.mapRequired("ParamTypes", Signature.ParamTypes); 268 } 269 270 void MappingTraits<WasmYAML::Table>::mapping(IO &IO, WasmYAML::Table &Table) { 271 IO.mapRequired("ElemType", Table.ElemType); 272 IO.mapRequired("Limits", Table.TableLimits); 273 } 274 275 void MappingTraits<WasmYAML::Function>::mapping(IO &IO, 276 WasmYAML::Function &Function) { 277 IO.mapRequired("Index", Function.Index); 278 IO.mapRequired("Locals", Function.Locals); 279 IO.mapRequired("Body", Function.Body); 280 } 281 282 void MappingTraits<WasmYAML::Relocation>::mapping( 283 IO &IO, WasmYAML::Relocation &Relocation) { 284 IO.mapRequired("Type", Relocation.Type); 285 IO.mapRequired("Index", Relocation.Index); 286 IO.mapRequired("Offset", Relocation.Offset); 287 IO.mapOptional("Addend", Relocation.Addend, 0); 288 } 289 290 void MappingTraits<WasmYAML::NameEntry>::mapping( 291 IO &IO, WasmYAML::NameEntry &NameEntry) { 292 IO.mapRequired("Index", NameEntry.Index); 293 IO.mapRequired("Name", NameEntry.Name); 294 } 295 296 void MappingTraits<WasmYAML::SegmentInfo>::mapping( 297 IO &IO, WasmYAML::SegmentInfo &SegmentInfo) { 298 IO.mapRequired("Index", SegmentInfo.Index); 299 IO.mapRequired("Name", SegmentInfo.Name); 300 IO.mapRequired("Alignment", SegmentInfo.Alignment); 301 IO.mapRequired("Flags", SegmentInfo.Flags); 302 } 303 304 void MappingTraits<WasmYAML::LocalDecl>::mapping( 305 IO &IO, WasmYAML::LocalDecl &LocalDecl) { 306 IO.mapRequired("Type", LocalDecl.Type); 307 IO.mapRequired("Count", LocalDecl.Count); 308 } 309 310 void MappingTraits<WasmYAML::Limits>::mapping(IO &IO, 311 WasmYAML::Limits &Limits) { 312 if (!IO.outputting() || Limits.Flags) 313 IO.mapOptional("Flags", Limits.Flags); 314 IO.mapRequired("Initial", Limits.Initial); 315 if (!IO.outputting() || Limits.Flags & wasm::WASM_LIMITS_FLAG_HAS_MAX) 316 IO.mapOptional("Maximum", Limits.Maximum); 317 } 318 319 void MappingTraits<WasmYAML::ElemSegment>::mapping( 320 IO &IO, WasmYAML::ElemSegment &Segment) { 321 IO.mapRequired("Offset", Segment.Offset); 322 IO.mapRequired("Functions", Segment.Functions); 323 } 324 325 void MappingTraits<WasmYAML::Import>::mapping(IO &IO, 326 WasmYAML::Import &Import) { 327 IO.mapRequired("Module", Import.Module); 328 IO.mapRequired("Field", Import.Field); 329 IO.mapRequired("Kind", Import.Kind); 330 if (Import.Kind == wasm::WASM_EXTERNAL_FUNCTION) { 331 IO.mapRequired("SigIndex", Import.SigIndex); 332 } else if (Import.Kind == wasm::WASM_EXTERNAL_GLOBAL) { 333 IO.mapRequired("GlobalType", Import.GlobalImport.Type); 334 IO.mapRequired("GlobalMutable", Import.GlobalImport.Mutable); 335 } else if (Import.Kind == wasm::WASM_EXTERNAL_EVENT) { 336 IO.mapRequired("EventAttribute", Import.EventImport.Attribute); 337 IO.mapRequired("EventSigIndex", Import.EventImport.SigIndex); 338 } else if (Import.Kind == wasm::WASM_EXTERNAL_TABLE) { 339 IO.mapRequired("Table", Import.TableImport); 340 } else if (Import.Kind == wasm::WASM_EXTERNAL_MEMORY) { 341 IO.mapRequired("Memory", Import.Memory); 342 } else { 343 llvm_unreachable("unhandled import type"); 344 } 345 } 346 347 void MappingTraits<WasmYAML::Export>::mapping(IO &IO, 348 WasmYAML::Export &Export) { 349 IO.mapRequired("Name", Export.Name); 350 IO.mapRequired("Kind", Export.Kind); 351 IO.mapRequired("Index", Export.Index); 352 } 353 354 void MappingTraits<WasmYAML::Global>::mapping(IO &IO, 355 WasmYAML::Global &Global) { 356 IO.mapRequired("Index", Global.Index); 357 IO.mapRequired("Type", Global.Type); 358 IO.mapRequired("Mutable", Global.Mutable); 359 IO.mapRequired("InitExpr", Global.InitExpr); 360 } 361 362 void MappingTraits<wasm::WasmInitExpr>::mapping(IO &IO, 363 wasm::WasmInitExpr &Expr) { 364 WasmYAML::Opcode Op = Expr.Opcode; 365 IO.mapRequired("Opcode", Op); 366 Expr.Opcode = Op; 367 switch (Expr.Opcode) { 368 case wasm::WASM_OPCODE_I32_CONST: 369 IO.mapRequired("Value", Expr.Value.Int32); 370 break; 371 case wasm::WASM_OPCODE_I64_CONST: 372 IO.mapRequired("Value", Expr.Value.Int64); 373 break; 374 case wasm::WASM_OPCODE_F32_CONST: 375 IO.mapRequired("Value", Expr.Value.Float32); 376 break; 377 case wasm::WASM_OPCODE_F64_CONST: 378 IO.mapRequired("Value", Expr.Value.Float64); 379 break; 380 case wasm::WASM_OPCODE_GLOBAL_GET: 381 IO.mapRequired("Index", Expr.Value.Global); 382 break; 383 } 384 } 385 386 void MappingTraits<WasmYAML::DataSegment>::mapping( 387 IO &IO, WasmYAML::DataSegment &Segment) { 388 IO.mapOptional("SectionOffset", Segment.SectionOffset); 389 IO.mapRequired("MemoryIndex", Segment.MemoryIndex); 390 IO.mapRequired("Offset", Segment.Offset); 391 IO.mapRequired("Content", Segment.Content); 392 } 393 394 void MappingTraits<WasmYAML::InitFunction>::mapping( 395 IO &IO, WasmYAML::InitFunction &Init) { 396 IO.mapRequired("Priority", Init.Priority); 397 IO.mapRequired("Symbol", Init.Symbol); 398 } 399 400 void ScalarEnumerationTraits<WasmYAML::ComdatKind>::enumeration( 401 IO &IO, WasmYAML::ComdatKind &Kind) { 402 #define ECase(X) IO.enumCase(Kind, #X, wasm::WASM_COMDAT_##X); 403 ECase(FUNCTION); 404 ECase(DATA); 405 #undef ECase 406 } 407 408 void MappingTraits<WasmYAML::ComdatEntry>::mapping( 409 IO &IO, WasmYAML::ComdatEntry &ComdatEntry) { 410 IO.mapRequired("Kind", ComdatEntry.Kind); 411 IO.mapRequired("Index", ComdatEntry.Index); 412 } 413 414 void MappingTraits<WasmYAML::Comdat>::mapping(IO &IO, 415 WasmYAML::Comdat &Comdat) { 416 IO.mapRequired("Name", Comdat.Name); 417 IO.mapRequired("Entries", Comdat.Entries); 418 } 419 420 void MappingTraits<WasmYAML::SymbolInfo>::mapping(IO &IO, 421 WasmYAML::SymbolInfo &Info) { 422 IO.mapRequired("Index", Info.Index); 423 IO.mapRequired("Kind", Info.Kind); 424 IO.mapRequired("Name", Info.Name); 425 IO.mapRequired("Flags", Info.Flags); 426 if (Info.Kind == wasm::WASM_SYMBOL_TYPE_FUNCTION) { 427 IO.mapRequired("Function", Info.ElementIndex); 428 } else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_GLOBAL) { 429 IO.mapRequired("Global", Info.ElementIndex); 430 } else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_EVENT) { 431 IO.mapRequired("Event", Info.ElementIndex); 432 } else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_DATA) { 433 if ((Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0) { 434 IO.mapRequired("Segment", Info.DataRef.Segment); 435 IO.mapOptional("Offset", Info.DataRef.Offset, 0u); 436 IO.mapRequired("Size", Info.DataRef.Size); 437 } 438 } else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_SECTION) { 439 IO.mapRequired("Section", Info.ElementIndex); 440 } else { 441 llvm_unreachable("unsupported symbol kind"); 442 } 443 } 444 445 void MappingTraits<WasmYAML::Event>::mapping(IO &IO, WasmYAML::Event &Event) { 446 IO.mapRequired("Index", Event.Index); 447 IO.mapRequired("Attribute", Event.Attribute); 448 IO.mapRequired("SigIndex", Event.SigIndex); 449 } 450 451 void ScalarBitSetTraits<WasmYAML::LimitFlags>::bitset( 452 IO &IO, WasmYAML::LimitFlags &Value) { 453 #define BCase(X) IO.bitSetCase(Value, #X, wasm::WASM_LIMITS_FLAG_##X) 454 BCase(HAS_MAX); 455 BCase(IS_SHARED); 456 #undef BCase 457 } 458 459 void ScalarBitSetTraits<WasmYAML::SegmentFlags>::bitset( 460 IO &IO, WasmYAML::SegmentFlags &Value) {} 461 462 void ScalarBitSetTraits<WasmYAML::SymbolFlags>::bitset( 463 IO &IO, WasmYAML::SymbolFlags &Value) { 464 #define BCaseMask(M, X) \ 465 IO.maskedBitSetCase(Value, #X, wasm::WASM_SYMBOL_##X, wasm::WASM_SYMBOL_##M) 466 // BCaseMask(BINDING_MASK, BINDING_GLOBAL); 467 BCaseMask(BINDING_MASK, BINDING_WEAK); 468 BCaseMask(BINDING_MASK, BINDING_LOCAL); 469 // BCaseMask(VISIBILITY_MASK, VISIBILITY_DEFAULT); 470 BCaseMask(VISIBILITY_MASK, VISIBILITY_HIDDEN); 471 BCaseMask(UNDEFINED, UNDEFINED); 472 #undef BCaseMask 473 } 474 475 void ScalarEnumerationTraits<WasmYAML::SymbolKind>::enumeration( 476 IO &IO, WasmYAML::SymbolKind &Kind) { 477 #define ECase(X) IO.enumCase(Kind, #X, wasm::WASM_SYMBOL_TYPE_##X); 478 ECase(FUNCTION); 479 ECase(DATA); 480 ECase(GLOBAL); 481 ECase(SECTION); 482 ECase(EVENT); 483 #undef ECase 484 } 485 486 void ScalarEnumerationTraits<WasmYAML::ValueType>::enumeration( 487 IO &IO, WasmYAML::ValueType &Type) { 488 #define ECase(X) IO.enumCase(Type, #X, wasm::WASM_TYPE_##X); 489 ECase(I32); 490 ECase(I64); 491 ECase(F32); 492 ECase(F64); 493 ECase(V128); 494 ECase(FUNCREF); 495 ECase(FUNC); 496 ECase(NORESULT); 497 #undef ECase 498 } 499 500 void ScalarEnumerationTraits<WasmYAML::ExportKind>::enumeration( 501 IO &IO, WasmYAML::ExportKind &Kind) { 502 #define ECase(X) IO.enumCase(Kind, #X, wasm::WASM_EXTERNAL_##X); 503 ECase(FUNCTION); 504 ECase(TABLE); 505 ECase(MEMORY); 506 ECase(GLOBAL); 507 ECase(EVENT); 508 #undef ECase 509 } 510 511 void ScalarEnumerationTraits<WasmYAML::Opcode>::enumeration( 512 IO &IO, WasmYAML::Opcode &Code) { 513 #define ECase(X) IO.enumCase(Code, #X, wasm::WASM_OPCODE_##X); 514 ECase(END); 515 ECase(I32_CONST); 516 ECase(I64_CONST); 517 ECase(F64_CONST); 518 ECase(F32_CONST); 519 ECase(GLOBAL_GET); 520 #undef ECase 521 } 522 523 void ScalarEnumerationTraits<WasmYAML::TableType>::enumeration( 524 IO &IO, WasmYAML::TableType &Type) { 525 #define ECase(X) IO.enumCase(Type, #X, wasm::WASM_TYPE_##X); 526 ECase(FUNCREF); 527 #undef ECase 528 } 529 530 void ScalarEnumerationTraits<WasmYAML::RelocType>::enumeration( 531 IO &IO, WasmYAML::RelocType &Type) { 532 #define WASM_RELOC(name, value) IO.enumCase(Type, #name, wasm::name); 533 #include "llvm/BinaryFormat/WasmRelocs.def" 534 #undef WASM_RELOC 535 } 536 537 } // end namespace yaml 538 539 } // end namespace llvm 540