1 //===- WasmYAML.cpp - Wasm YAMLIO implementation --------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines classes for handling the YAML representation of wasm.
12 //===----------------------------------------------------------------------===//
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"
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;
28 } // end namespace WasmYAML
32 void MappingTraits
<WasmYAML::FileHeader
>::mapping(
33 IO
&IO
, WasmYAML::FileHeader
&FileHdr
) {
34 IO
.mapRequired("Version", FileHdr
.Version
);
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);
46 static void commonSectionMapping(IO
&IO
, WasmYAML::Section
&Section
) {
47 IO
.mapRequired("Type", Section
.Type
);
48 IO
.mapOptional("Relocations", Section
.Relocations
);
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
);
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
);
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
);
73 static void sectionMapping(IO
&IO
, WasmYAML::TypeSection
&Section
) {
74 commonSectionMapping(IO
, Section
);
75 IO
.mapOptional("Signatures", Section
.Signatures
);
78 static void sectionMapping(IO
&IO
, WasmYAML::ImportSection
&Section
) {
79 commonSectionMapping(IO
, Section
);
80 IO
.mapOptional("Imports", Section
.Imports
);
83 static void sectionMapping(IO
&IO
, WasmYAML::FunctionSection
&Section
) {
84 commonSectionMapping(IO
, Section
);
85 IO
.mapOptional("FunctionTypes", Section
.FunctionTypes
);
88 static void sectionMapping(IO
&IO
, WasmYAML::TableSection
&Section
) {
89 commonSectionMapping(IO
, Section
);
90 IO
.mapOptional("Tables", Section
.Tables
);
93 static void sectionMapping(IO
&IO
, WasmYAML::MemorySection
&Section
) {
94 commonSectionMapping(IO
, Section
);
95 IO
.mapOptional("Memories", Section
.Memories
);
98 static void sectionMapping(IO
&IO
, WasmYAML::GlobalSection
&Section
) {
99 commonSectionMapping(IO
, Section
);
100 IO
.mapOptional("Globals", Section
.Globals
);
103 static void sectionMapping(IO
&IO
, WasmYAML::ExportSection
&Section
) {
104 commonSectionMapping(IO
, Section
);
105 IO
.mapOptional("Exports", Section
.Exports
);
108 static void sectionMapping(IO
&IO
, WasmYAML::StartSection
&Section
) {
109 commonSectionMapping(IO
, Section
);
110 IO
.mapOptional("StartFunction", Section
.StartFunction
);
113 static void sectionMapping(IO
&IO
, WasmYAML::ElemSection
&Section
) {
114 commonSectionMapping(IO
, Section
);
115 IO
.mapOptional("Segments", Section
.Segments
);
118 static void sectionMapping(IO
&IO
, WasmYAML::CodeSection
&Section
) {
119 commonSectionMapping(IO
, Section
);
120 IO
.mapRequired("Functions", Section
.Functions
);
123 static void sectionMapping(IO
&IO
, WasmYAML::DataSection
&Section
) {
124 commonSectionMapping(IO
, Section
);
125 IO
.mapRequired("Segments", Section
.Segments
);
128 void MappingTraits
<std::unique_ptr
<WasmYAML::Section
>>::mapping(
129 IO
&IO
, std::unique_ptr
<WasmYAML::Section
> &Section
) {
130 WasmYAML::SectionType SectionType
;
132 SectionType
= Section
->Type
;
134 IO
.mapRequired("Type", SectionType
);
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
;
143 IO
.mapRequired("Name", SectionName
);
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()));
154 if (!IO
.outputting())
155 Section
.reset(new WasmYAML::CustomSection(SectionName
));
156 sectionMapping(IO
, *cast
<WasmYAML::CustomSection
>(Section
.get()));
160 case wasm::WASM_SEC_TYPE
:
161 if (!IO
.outputting())
162 Section
.reset(new WasmYAML::TypeSection());
163 sectionMapping(IO
, *cast
<WasmYAML::TypeSection
>(Section
.get()));
165 case wasm::WASM_SEC_IMPORT
:
166 if (!IO
.outputting())
167 Section
.reset(new WasmYAML::ImportSection());
168 sectionMapping(IO
, *cast
<WasmYAML::ImportSection
>(Section
.get()));
170 case wasm::WASM_SEC_FUNCTION
:
171 if (!IO
.outputting())
172 Section
.reset(new WasmYAML::FunctionSection());
173 sectionMapping(IO
, *cast
<WasmYAML::FunctionSection
>(Section
.get()));
175 case wasm::WASM_SEC_TABLE
:
176 if (!IO
.outputting())
177 Section
.reset(new WasmYAML::TableSection());
178 sectionMapping(IO
, *cast
<WasmYAML::TableSection
>(Section
.get()));
180 case wasm::WASM_SEC_MEMORY
:
181 if (!IO
.outputting())
182 Section
.reset(new WasmYAML::MemorySection());
183 sectionMapping(IO
, *cast
<WasmYAML::MemorySection
>(Section
.get()));
185 case wasm::WASM_SEC_GLOBAL
:
186 if (!IO
.outputting())
187 Section
.reset(new WasmYAML::GlobalSection());
188 sectionMapping(IO
, *cast
<WasmYAML::GlobalSection
>(Section
.get()));
190 case wasm::WASM_SEC_EXPORT
:
191 if (!IO
.outputting())
192 Section
.reset(new WasmYAML::ExportSection());
193 sectionMapping(IO
, *cast
<WasmYAML::ExportSection
>(Section
.get()));
195 case wasm::WASM_SEC_START
:
196 if (!IO
.outputting())
197 Section
.reset(new WasmYAML::StartSection());
198 sectionMapping(IO
, *cast
<WasmYAML::StartSection
>(Section
.get()));
200 case wasm::WASM_SEC_ELEM
:
201 if (!IO
.outputting())
202 Section
.reset(new WasmYAML::ElemSection());
203 sectionMapping(IO
, *cast
<WasmYAML::ElemSection
>(Section
.get()));
205 case wasm::WASM_SEC_CODE
:
206 if (!IO
.outputting())
207 Section
.reset(new WasmYAML::CodeSection());
208 sectionMapping(IO
, *cast
<WasmYAML::CodeSection
>(Section
.get()));
210 case wasm::WASM_SEC_DATA
:
211 if (!IO
.outputting())
212 Section
.reset(new WasmYAML::DataSection());
213 sectionMapping(IO
, *cast
<WasmYAML::DataSection
>(Section
.get()));
216 llvm_unreachable("Unknown section type");
220 void ScalarEnumerationTraits
<WasmYAML::SectionType
>::enumeration(
221 IO
&IO
, WasmYAML::SectionType
&Type
) {
222 #define ECase(X) IO.enumCase(Type, #X, wasm::WASM_SEC_##X);
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
);
245 void MappingTraits
<WasmYAML::Table
>::mapping(IO
&IO
, WasmYAML::Table
&Table
) {
246 IO
.mapRequired("ElemType", Table
.ElemType
);
247 IO
.mapRequired("Limits", Table
.TableLimits
);
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
);
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);
265 void MappingTraits
<WasmYAML::NameEntry
>::mapping(
266 IO
&IO
, WasmYAML::NameEntry
&NameEntry
) {
267 IO
.mapRequired("Index", NameEntry
.Index
);
268 IO
.mapRequired("Name", NameEntry
.Name
);
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
);
279 void MappingTraits
<WasmYAML::LocalDecl
>::mapping(
280 IO
&IO
, WasmYAML::LocalDecl
&LocalDecl
) {
281 IO
.mapRequired("Type", LocalDecl
.Type
);
282 IO
.mapRequired("Count", LocalDecl
.Count
);
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
);
294 void MappingTraits
<WasmYAML::ElemSegment
>::mapping(
295 IO
&IO
, WasmYAML::ElemSegment
&Segment
) {
296 IO
.mapRequired("Offset", Segment
.Offset
);
297 IO
.mapRequired("Functions", Segment
.Functions
);
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
);
315 llvm_unreachable("unhandled import type");
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
);
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
);
334 void MappingTraits
<wasm::WasmInitExpr
>::mapping(IO
&IO
,
335 wasm::WasmInitExpr
&Expr
) {
336 WasmYAML::Opcode Op
= Expr
.Opcode
;
337 IO
.mapRequired("Opcode", Op
);
339 switch (Expr
.Opcode
) {
340 case wasm::WASM_OPCODE_I32_CONST
:
341 IO
.mapRequired("Value", Expr
.Value
.Int32
);
343 case wasm::WASM_OPCODE_I64_CONST
:
344 IO
.mapRequired("Value", Expr
.Value
.Int64
);
346 case wasm::WASM_OPCODE_F32_CONST
:
347 IO
.mapRequired("Value", Expr
.Value
.Float32
);
349 case wasm::WASM_OPCODE_F64_CONST
:
350 IO
.mapRequired("Value", Expr
.Value
.Float64
);
352 case wasm::WASM_OPCODE_GET_GLOBAL
:
353 IO
.mapRequired("Index", Expr
.Value
.Global
);
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
);
366 void MappingTraits
<WasmYAML::InitFunction
>::mapping(
367 IO
&IO
, WasmYAML::InitFunction
&Init
) {
368 IO
.mapRequired("Priority", Init
.Priority
);
369 IO
.mapRequired("Symbol", Init
.Symbol
);
372 void ScalarEnumerationTraits
<WasmYAML::ComdatKind
>::enumeration(
373 IO
&IO
, WasmYAML::ComdatKind
&Kind
) {
374 #define ECase(X) IO.enumCase(Kind, #X, wasm::WASM_COMDAT_##X);
380 void MappingTraits
<WasmYAML::ComdatEntry
>::mapping(
381 IO
&IO
, WasmYAML::ComdatEntry
&ComdatEntry
) {
382 IO
.mapRequired("Kind", ComdatEntry
.Kind
);
383 IO
.mapRequired("Index", ComdatEntry
.Index
);
386 void MappingTraits
<WasmYAML::Comdat
>::mapping(
387 IO
&IO
, WasmYAML::Comdat
&Comdat
) {
388 IO
.mapRequired("Name", Comdat
.Name
);
389 IO
.mapRequired("Entries", Comdat
.Entries
);
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
);
408 } else if (Info
.Kind
== wasm::WASM_SYMBOL_TYPE_SECTION
) {
409 IO
.mapRequired("Section", Info
.ElementIndex
);
411 llvm_unreachable("unsupported symbol kind");
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)
422 void ScalarBitSetTraits
<WasmYAML::SegmentFlags
>::bitset(
423 IO
&IO
, WasmYAML::SegmentFlags
&Value
) {
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
);
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);
448 void ScalarEnumerationTraits
<WasmYAML::ValueType
>::enumeration(
449 IO
&IO
, WasmYAML::ValueType
&Type
) {
450 #define ECase(X) IO.enumCase(Type, #X, wasm::WASM_TYPE_##X);
461 void ScalarEnumerationTraits
<WasmYAML::ExportKind
>::enumeration(
462 IO
&IO
, WasmYAML::ExportKind
&Kind
) {
463 #define ECase(X) IO.enumCase(Kind, #X, wasm::WASM_EXTERNAL_##X);
471 void ScalarEnumerationTraits
<WasmYAML::Opcode
>::enumeration(
472 IO
&IO
, WasmYAML::Opcode
&Code
) {
473 #define ECase(X) IO.enumCase(Code, #X, wasm::WASM_OPCODE_##X);
483 void ScalarEnumerationTraits
<WasmYAML::TableType
>::enumeration(
484 IO
&IO
, WasmYAML::TableType
&Type
) {
485 #define ECase(X) IO.enumCase(Type, #X, wasm::WASM_TYPE_##X);
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"
497 } // end namespace yaml
499 } // end namespace llvm