LLVM  8.0.1
WasmYAML.cpp
Go to the documentation of this file.
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 
15 #include "llvm/ADT/StringRef.h"
16 #include "llvm/Support/Casting.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 
33  IO &IO, WasmYAML::FileHeader &FileHdr) {
34  IO.mapRequired("Version", FileHdr.Version);
35 }
36 
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 
47  IO.mapRequired("Type", Section.Type);
48  IO.mapOptional("Relocations", Section.Relocations);
49 }
50 
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 
62  commonSectionMapping(IO, Section);
63  IO.mapRequired("Name", Section.Name);
64  IO.mapOptional("FunctionNames", Section.FunctionNames);
65 }
66 
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 
78  commonSectionMapping(IO, Section);
79  IO.mapRequired("Name", Section.Name);
80  IO.mapRequired("Payload", Section.Payload);
81 }
82 
84  commonSectionMapping(IO, Section);
85  IO.mapOptional("Signatures", Section.Signatures);
86 }
87 
89  commonSectionMapping(IO, Section);
90  IO.mapOptional("Imports", Section.Imports);
91 }
92 
94  commonSectionMapping(IO, Section);
95  IO.mapOptional("FunctionTypes", Section.FunctionTypes);
96 }
97 
99  commonSectionMapping(IO, Section);
100  IO.mapOptional("Tables", Section.Tables);
101 }
102 
104  commonSectionMapping(IO, Section);
105  IO.mapOptional("Memories", Section.Memories);
106 }
107 
109  commonSectionMapping(IO, Section);
110  IO.mapOptional("Globals", Section.Globals);
111 }
112 
114  commonSectionMapping(IO, Section);
115  IO.mapOptional("Events", Section.Events);
116 }
117 
119  commonSectionMapping(IO, Section);
120  IO.mapOptional("Exports", Section.Exports);
121 }
122 
124  commonSectionMapping(IO, Section);
125  IO.mapOptional("StartFunction", Section.StartFunction);
126 }
127 
129  commonSectionMapping(IO, Section);
130  IO.mapOptional("Segments", Section.Segments);
131 }
132 
134  commonSectionMapping(IO, Section);
135  IO.mapRequired("Functions", Section.Functions);
136 }
137 
139  commonSectionMapping(IO, Section);
140  IO.mapRequired("Segments", Section.Segments);
141 }
142 
144  IO &IO, std::unique_ptr<WasmYAML::Section> &Section) {
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: {
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;
185  if (!IO.outputting())
186  Section.reset(new WasmYAML::ImportSection());
187  sectionMapping(IO, *cast<WasmYAML::ImportSection>(Section.get()));
188  break;
190  if (!IO.outputting())
191  Section.reset(new WasmYAML::FunctionSection());
192  sectionMapping(IO, *cast<WasmYAML::FunctionSection>(Section.get()));
193  break;
195  if (!IO.outputting())
196  Section.reset(new WasmYAML::TableSection());
197  sectionMapping(IO, *cast<WasmYAML::TableSection>(Section.get()));
198  break;
200  if (!IO.outputting())
201  Section.reset(new WasmYAML::MemorySection());
202  sectionMapping(IO, *cast<WasmYAML::MemorySection>(Section.get()));
203  break;
205  if (!IO.outputting())
206  Section.reset(new WasmYAML::GlobalSection());
207  sectionMapping(IO, *cast<WasmYAML::GlobalSection>(Section.get()));
208  break;
210  if (!IO.outputting())
211  Section.reset(new WasmYAML::EventSection());
212  sectionMapping(IO, *cast<WasmYAML::EventSection>(Section.get()));
213  break;
215  if (!IO.outputting())
216  Section.reset(new WasmYAML::ExportSection());
217  sectionMapping(IO, *cast<WasmYAML::ExportSection>(Section.get()));
218  break;
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 
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 
271  IO.mapRequired("ElemType", Table.ElemType);
272  IO.mapRequired("Limits", Table.TableLimits);
273 }
274 
277  IO.mapRequired("Index", Function.Index);
278  IO.mapRequired("Locals", Function.Locals);
279  IO.mapRequired("Body", Function.Body);
280 }
281 
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 
291  IO &IO, WasmYAML::NameEntry &NameEntry) {
292  IO.mapRequired("Index", NameEntry.Index);
293  IO.mapRequired("Name", NameEntry.Name);
294 }
295 
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 
305  IO &IO, WasmYAML::LocalDecl &LocalDecl) {
306  IO.mapRequired("Type", LocalDecl.Type);
307  IO.mapRequired("Count", LocalDecl.Count);
308 }
309 
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 
320  IO &IO, WasmYAML::ElemSegment &Segment) {
321  IO.mapRequired("Offset", Segment.Offset);
322  IO.mapRequired("Functions", Segment.Functions);
323 }
324 
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 
348  WasmYAML::Export &Export) {
349  IO.mapRequired("Name", Export.Name);
350  IO.mapRequired("Kind", Export.Kind);
351  IO.mapRequired("Index", Export.Index);
352 }
353 
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 
363  wasm::WasmInitExpr &Expr) {
364  WasmYAML::Opcode Op = Expr.Opcode;
365  IO.mapRequired("Opcode", Op);
366  Expr.Opcode = Op;
367  switch (Expr.Opcode) {
369  IO.mapRequired("Value", Expr.Value.Int32);
370  break;
372  IO.mapRequired("Value", Expr.Value.Int64);
373  break;
375  IO.mapRequired("Value", Expr.Value.Float32);
376  break;
378  IO.mapRequired("Value", Expr.Value.Float64);
379  break;
381  IO.mapRequired("Index", Expr.Value.Global);
382  break;
383  }
384 }
385 
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 
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 
409  IO &IO, WasmYAML::ComdatEntry &ComdatEntry) {
410  IO.mapRequired("Kind", ComdatEntry.Kind);
411  IO.mapRequired("Index", ComdatEntry.Index);
412 }
413 
416  IO.mapRequired("Name", Comdat.Name);
417  IO.mapRequired("Entries", Comdat.Entries);
418 }
419 
422  IO.mapRequired("Index", Info.Index);
423  IO.mapRequired("Kind", Info.Kind);
424  IO.mapRequired("Name", Info.Name);
425  IO.mapRequired("Flags", Info.Flags);
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 
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
std::vector< InitFunction > InitFunctions
Definition: WasmYAML.h:223
std::vector< Comdat > Comdats
Definition: WasmYAML.h:224
std::vector< Relocation > Relocations
Definition: WasmYAML.h:171
std::vector< Limits > Memories
Definition: WasmYAML.h:274
std::vector< Signature > Signatures
Definition: WasmYAML.h:234
This class represents lattice values for constants.
Definition: AllocatorList.h:24
yaml::BinaryRef Body
Definition: WasmYAML.h:104
std::vector< std::unique_ptr< Section > > Sections
Definition: WasmYAML.h:349
wasm::WasmInitExpr InitExpr
Definition: WasmYAML.h:74
yaml::BinaryRef Content
Definition: WasmYAML.h:118
#define BCase(X)
std::vector< Import > Imports
Definition: WasmYAML.h:244
wasm::WasmInitExpr Offset
Definition: WasmYAML.h:66
const unsigned WASM_SYMBOL_UNDEFINED
Definition: Wasm.h:287
std::vector< SegmentInfo > SegmentInfos
Definition: WasmYAML.h:222
std::vector< SymbolInfo > SymbolTable
Definition: WasmYAML.h:221
union llvm::wasm::WasmInitExpr::@143 Value
std::vector< Function > Functions
Definition: WasmYAML.h:334
yaml::Hex32 Initial
Definition: WasmYAML.h:49
Analysis containing CSE Info
Definition: CSEInfo.cpp:21
std::vector< ComdatEntry > Entries
Definition: WasmYAML.h:163
This file declares classes for handling the YAML representation of wasm binaries. ...
uint32_t Attribute
Definition: WasmYAML.h:79
yaml::Hex32 Maximum
Definition: WasmYAML.h:50
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:46
std::vector< Export > Exports
Definition: WasmYAML.h:304
#define BCaseMask(M, X)
static void sectionMapping(IO &IO, WasmYAML::DataSection &Section)
Definition: WasmYAML.cpp:138
std::vector< uint32_t > FunctionTypes
Definition: WasmYAML.h:254
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
#define ECase(X)
ValueType
Value types.
TableType ElemType
Definition: WasmYAML.h:54
std::vector< Table > Tables
Definition: WasmYAML.h:264
LimitFlags Flags
Definition: WasmYAML.h:48
std::vector< ElemSegment > Segments
Definition: WasmYAML.h:324
std::vector< Event > Events
Definition: WasmYAML.h:294
std::vector< uint32_t > Functions
Definition: WasmYAML.h:67
std::vector< DataSegment > Segments
Definition: WasmYAML.h:344
wasm::WasmDataReference DataRef
Definition: WasmYAML.h:147
std::vector< ValueType > ParamTypes
Definition: WasmYAML.h:136
SymbolKind
Duplicate copy of the above enum, but using the official CV names.
Definition: CodeView.h:48
std::vector< LocalDecl > Locals
Definition: WasmYAML.h:103
yaml::BinaryRef Payload
Definition: WasmYAML.h:183
std::vector< NameEntry > FunctionNames
Definition: WasmYAML.h:209
const unsigned Kind
std::vector< Global > Globals
Definition: WasmYAML.h:284
LLVM Value Representation.
Definition: Value.h:73
wasm::WasmInitExpr Offset
Definition: WasmYAML.h:117
static void commonSectionMapping(IO &IO, WasmYAML::Section &Section)
Definition: WasmYAML.cpp:46
const char SectionName[]
Definition: AMDGPUPTNote.h:24
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
SectionType
These are the section type and attributes fields.
Definition: MachO.h:115