1//===- WasmYAML.h - Wasm YAMLIO implementation ------------------*- C++ -*-===//
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/// \file
11/// \brief This file declares classes for handling the YAML representation
12/// of wasm binaries.
13///
14//===----------------------------------------------------------------------===//
15
16#ifndef LLVM_OBJECTYAML_WASMYAML_H
17#define LLVM_OBJECTYAML_WASMYAML_H
18
19#include "llvm/BinaryFormat/Wasm.h"
20#include "llvm/ObjectYAML/YAML.h"
21
22namespace llvm {
23namespace WasmYAML {
24
25LLVM_YAML_STRONG_TYPEDEF(uint32_t, SectionType)
26LLVM_YAML_STRONG_TYPEDEF(int32_t, ValueType)
27LLVM_YAML_STRONG_TYPEDEF(int32_t, TableType)
28LLVM_YAML_STRONG_TYPEDEF(int32_t, SignatureForm)
29LLVM_YAML_STRONG_TYPEDEF(uint32_t, ExportKind)
30LLVM_YAML_STRONG_TYPEDEF(uint32_t, Opcode)
31LLVM_YAML_STRONG_TYPEDEF(uint32_t, RelocType)
32
33struct FileHeader {
34  yaml::Hex32 Version;
35};
36
37struct Limits {
38  yaml::Hex32 Flags;
39  yaml::Hex32 Initial;
40  yaml::Hex32 Maximum;
41};
42
43struct Table {
44  TableType ElemType;
45  Limits TableLimits;
46};
47
48struct Export {
49  StringRef Name;
50  ExportKind Kind;
51  uint32_t Index;
52};
53
54struct ElemSegment {
55  uint32_t TableIndex;
56  wasm::WasmInitExpr Offset;
57  std::vector<uint32_t> Functions;
58};
59
60struct Global {
61  ValueType Type;
62  bool Mutable;
63  wasm::WasmInitExpr InitExpr;
64};
65
66struct Import {
67  StringRef Module;
68  StringRef Field;
69  ExportKind Kind;
70  union {
71    uint32_t SigIndex;
72    Global GlobalImport;
73    Table TableImport;
74    Limits Memory;
75  };
76};
77
78struct LocalDecl {
79  ValueType Type;
80  uint32_t Count;
81};
82
83struct Function {
84  std::vector<LocalDecl> Locals;
85  yaml::BinaryRef Body;
86};
87
88struct Relocation {
89  RelocType Type;
90  uint32_t Index;
91  yaml::Hex32 Offset;
92  int32_t Addend;
93};
94
95struct DataSegment {
96  uint32_t Index;
97  wasm::WasmInitExpr Offset;
98  yaml::BinaryRef Content;
99};
100
101struct NameEntry {
102  uint32_t Index;
103  StringRef Name;
104};
105
106struct Signature {
107  Signature() : Form(wasm::WASM_TYPE_FUNC) {}
108
109  uint32_t Index;
110  SignatureForm Form;
111  std::vector<ValueType> ParamTypes;
112  ValueType ReturnType;
113};
114
115struct Section {
116  Section(SectionType SecType) : Type(SecType) {}
117  virtual ~Section();
118
119  SectionType Type;
120  std::vector<Relocation> Relocations;
121};
122
123struct CustomSection : Section {
124  CustomSection() : Section(wasm::WASM_SEC_CUSTOM) {}
125  static bool classof(const Section *S) {
126    return S->Type == wasm::WASM_SEC_CUSTOM;
127  }
128
129  StringRef Name;
130  yaml::BinaryRef Payload;
131
132  // The follow is used by the "name" custom section.
133  // TODO(sbc): Add support for more then just functions names.  The wasm
134  // name section can support multiple sub-sections.
135  std::vector<NameEntry> FunctionNames;
136};
137
138struct TypeSection : Section {
139  TypeSection() : Section(wasm::WASM_SEC_TYPE) {}
140  static bool classof(const Section *S) {
141    return S->Type == wasm::WASM_SEC_TYPE;
142  }
143
144  std::vector<Signature> Signatures;
145};
146
147struct ImportSection : Section {
148  ImportSection() : Section(wasm::WASM_SEC_IMPORT) {}
149  static bool classof(const Section *S) {
150    return S->Type == wasm::WASM_SEC_IMPORT;
151  }
152
153  std::vector<Import> Imports;
154};
155
156struct FunctionSection : Section {
157  FunctionSection() : Section(wasm::WASM_SEC_FUNCTION) {}
158  static bool classof(const Section *S) {
159    return S->Type == wasm::WASM_SEC_FUNCTION;
160  }
161
162  std::vector<uint32_t> FunctionTypes;
163};
164
165struct TableSection : Section {
166  TableSection() : Section(wasm::WASM_SEC_TABLE) {}
167  static bool classof(const Section *S) {
168    return S->Type == wasm::WASM_SEC_TABLE;
169  }
170
171  std::vector<Table> Tables;
172};
173
174struct MemorySection : Section {
175  MemorySection() : Section(wasm::WASM_SEC_MEMORY) {}
176  static bool classof(const Section *S) {
177    return S->Type == wasm::WASM_SEC_MEMORY;
178  }
179
180  std::vector<Limits> Memories;
181};
182
183struct GlobalSection : Section {
184  GlobalSection() : Section(wasm::WASM_SEC_GLOBAL) {}
185  static bool classof(const Section *S) {
186    return S->Type == wasm::WASM_SEC_GLOBAL;
187  }
188
189  std::vector<Global> Globals;
190};
191
192struct ExportSection : Section {
193  ExportSection() : Section(wasm::WASM_SEC_EXPORT) {}
194  static bool classof(const Section *S) {
195    return S->Type == wasm::WASM_SEC_EXPORT;
196  }
197
198  std::vector<Export> Exports;
199};
200
201struct StartSection : Section {
202  StartSection() : Section(wasm::WASM_SEC_START) {}
203  static bool classof(const Section *S) {
204    return S->Type == wasm::WASM_SEC_START;
205  }
206
207  uint32_t StartFunction;
208};
209
210struct ElemSection : Section {
211  ElemSection() : Section(wasm::WASM_SEC_ELEM) {}
212  static bool classof(const Section *S) {
213    return S->Type == wasm::WASM_SEC_ELEM;
214  }
215
216  std::vector<ElemSegment> Segments;
217};
218
219struct CodeSection : Section {
220  CodeSection() : Section(wasm::WASM_SEC_CODE) {}
221  static bool classof(const Section *S) {
222    return S->Type == wasm::WASM_SEC_CODE;
223  }
224
225  std::vector<Function> Functions;
226};
227
228struct DataSection : Section {
229  DataSection() : Section(wasm::WASM_SEC_DATA) {}
230  static bool classof(const Section *S) {
231    return S->Type == wasm::WASM_SEC_DATA;
232  }
233
234  std::vector<DataSegment> Segments;
235};
236
237struct Object {
238  FileHeader Header;
239  std::vector<std::unique_ptr<Section>> Sections;
240};
241
242} // end namespace WasmYAML
243} // end namespace llvm
244
245LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::WasmYAML::Section>)
246LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Signature)
247LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::ValueType)
248LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Table)
249LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Import)
250LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Export)
251LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::ElemSegment)
252LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Limits)
253LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::DataSegment)
254LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Global)
255LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Function)
256LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::LocalDecl)
257LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Relocation)
258LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::NameEntry)
259LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(uint32_t)
260
261namespace llvm {
262namespace yaml {
263
264template <> struct MappingTraits<WasmYAML::FileHeader> {
265  static void mapping(IO &IO, WasmYAML::FileHeader &FileHdr);
266};
267
268template <> struct MappingTraits<std::unique_ptr<WasmYAML::Section>> {
269  static void mapping(IO &IO, std::unique_ptr<WasmYAML::Section> &Section);
270};
271
272template <> struct MappingTraits<WasmYAML::Object> {
273  static void mapping(IO &IO, WasmYAML::Object &Object);
274};
275
276template <> struct MappingTraits<WasmYAML::Import> {
277  static void mapping(IO &IO, WasmYAML::Import &Import);
278};
279
280template <> struct MappingTraits<WasmYAML::Export> {
281  static void mapping(IO &IO, WasmYAML::Export &Export);
282};
283
284template <> struct MappingTraits<WasmYAML::Global> {
285  static void mapping(IO &IO, WasmYAML::Global &Global);
286};
287
288template <> struct ScalarEnumerationTraits<WasmYAML::SectionType> {
289  static void enumeration(IO &IO, WasmYAML::SectionType &Type);
290};
291
292template <> struct MappingTraits<WasmYAML::Signature> {
293  static void mapping(IO &IO, WasmYAML::Signature &Signature);
294};
295
296template <> struct MappingTraits<WasmYAML::Table> {
297  static void mapping(IO &IO, WasmYAML::Table &Table);
298};
299
300template <> struct MappingTraits<WasmYAML::Limits> {
301  static void mapping(IO &IO, WasmYAML::Limits &Limits);
302};
303
304template <> struct MappingTraits<WasmYAML::Function> {
305  static void mapping(IO &IO, WasmYAML::Function &Function);
306};
307
308template <> struct MappingTraits<WasmYAML::Relocation> {
309  static void mapping(IO &IO, WasmYAML::Relocation &Relocation);
310};
311
312template <> struct MappingTraits<WasmYAML::NameEntry> {
313  static void mapping(IO &IO, WasmYAML::NameEntry &NameEntry);
314};
315
316template <> struct MappingTraits<WasmYAML::LocalDecl> {
317  static void mapping(IO &IO, WasmYAML::LocalDecl &LocalDecl);
318};
319
320template <> struct MappingTraits<wasm::WasmInitExpr> {
321  static void mapping(IO &IO, wasm::WasmInitExpr &Expr);
322};
323
324template <> struct MappingTraits<WasmYAML::DataSegment> {
325  static void mapping(IO &IO, WasmYAML::DataSegment &Segment);
326};
327
328template <> struct MappingTraits<WasmYAML::ElemSegment> {
329  static void mapping(IO &IO, WasmYAML::ElemSegment &Segment);
330};
331
332template <> struct ScalarEnumerationTraits<WasmYAML::ValueType> {
333  static void enumeration(IO &IO, WasmYAML::ValueType &Type);
334};
335
336template <> struct ScalarEnumerationTraits<WasmYAML::ExportKind> {
337  static void enumeration(IO &IO, WasmYAML::ExportKind &Kind);
338};
339
340template <> struct ScalarEnumerationTraits<WasmYAML::TableType> {
341  static void enumeration(IO &IO, WasmYAML::TableType &Type);
342};
343
344template <> struct ScalarEnumerationTraits<WasmYAML::Opcode> {
345  static void enumeration(IO &IO, WasmYAML::Opcode &Opcode);
346};
347
348template <> struct ScalarEnumerationTraits<WasmYAML::RelocType> {
349  static void enumeration(IO &IO, WasmYAML::RelocType &Kind);
350};
351
352} // end namespace yaml
353} // end namespace llvm
354
355#endif
356