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